[
  {
    "path": ".cirrus.yml",
    "content": "#\n#  Copyright Christopher Di Bella\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\ntask:\n  env:\n    matrix:\n      COMPILER_VERSION: 8\n    matrix:\n      BUILD_TYPE: Debug\n      BUILD_TYPE: Release\n  container:\n    dockerfile: config/ci/Dockerfile\n    cpu: 8\n    memory: 16G\n  configure_script:\n    - mkdir -p build\n    - cd build\n    - export CC=`which gcc-${COMPILER_VERSION}`\n    - export CXX=`which g++-${COMPILER_VERSION}`\n    - cmake .. -GNinja -DCMAKE_BUILD_TYPE=\"${BUILD_TYPE}\"\n  build_script:\n    - cd build\n    - ninja -v\n  test_script:\n    - cd build\n    - ctest -j8 --output-on-failure\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Disable CRLF-mapping for all files.\n* -text\n"
  },
  {
    "path": ".gitignore",
    "content": "*.user\n*~\n*.o\n*.obj\na.out\n\\#*#\n.#*\nbuild*/\n.vscode/\n.vs/\n*.*.swp\n"
  },
  {
    "path": ".travis.yml",
    "content": "# Copyright Casey Carter 2015-2017\n\n# Distributed under the Boost Software License, Version 1.0.\n# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt)\n\ndist: xenial\nlanguage: cpp\n\ncache:\n  directories:\n    - ${TRAVIS_BUILD_DIR}/deps/cmake-3.12.4\n\nmatrix:\n  include:\n    - env: GCC_VERSION=8 BUILD_TYPE=Debug\n      os: linux\n      addons: &gcc8\n        apt:\n          packages:\n            - g++-8\n            - ninja-build\n          sources:\n            - ubuntu-toolchain-r-test\n\n    - env: GCC_VERSION=8 BUILD_TYPE=Release\n      os: linux\n      addons: *gcc8\n\nbefore_install:\n  - if [ -n \"$GCC_VERSION\" ]; then export CXX=\"g++-${GCC_VERSION}\" CC=\"gcc-${GCC_VERSION}\"; fi\n  - which $CC\n  - which $CXX\n  - $CXX --version\n  - ninja --version\n  - JOBS=2\n\ninstall:\n  - DEPS_DIR=\"${TRAVIS_BUILD_DIR}/deps\"\n  - mkdir -p \"${DEPS_DIR}\" && cd \"${DEPS_DIR}\"\n  ############################################################################\n  # Install a recent CMake (unless already installed on OS X)\n  ############################################################################\n  - |\n    if [[ \"${TRAVIS_OS_NAME}\" == \"linux\" ]]; then\n      CMAKE_VERSION=3.12.4\n      if [[ -z \"$(ls -A ${DEPS_DIR}/cmake-${CMAKE_VERSION}/bin)\" ]]; then\n        CMAKE_URL=\"https://cmake.org/files/v3.12/cmake-3.12.4-Linux-x86_64.tar.gz\"\n        mkdir -p \"cmake-${CMAKE_VERSION}\" && travis_retry wget --no-check-certificate --quiet -O - \"${CMAKE_URL}\" | tar --strip-components=1 -xz -C \"cmake-${CMAKE_VERSION}\"\n      fi\n      export PATH=\"${DEPS_DIR}/cmake-${CMAKE_VERSION}/bin:${PATH}\"\n    fi\n\nbefore_script:\n  - cd \"${TRAVIS_BUILD_DIR}\"\n  - mkdir -p build\n  - cd build\n  - cmake .. -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS=\"${CXX_FLAGS}\"\n  - ninja -v\n\nscript:\n  - ctest -j${JOBS} --output-on-failure\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Eric Niebler 2015\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\ncmake_minimum_required(VERSION 3.12)\n\nproject(cmcstl2 CXX)\n\nset(CMAKE_CXX_EXTENSIONS OFF)\n\n# check if cmcstl2 is not a subproject\nif(CMAKE_CURRENT_LIST_DIR STREQUAL CMAKE_SOURCE_DIR)\n    option(STL2_BUILD_EXAMPLES \"Build stl2 examples\" ON)\n    option(STL2_BUILD_TESTING \"Build stl2 tests\" ON)\nelse()\n    option(STL2_BUILD_EXAMPLES \"Build stl2 examples\" OFF)\n    option(STL2_BUILD_TESTING \"Build stl2 tests\" OFF)\nendif()\n\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/config/cmake\")\nfind_package(Sanitizer COMPONENTS address undefined)\n\nadd_library(stl2 INTERFACE)\ntarget_include_directories(stl2 INTERFACE\n    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>\n    $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)\ntarget_compile_features(stl2 INTERFACE cxx_std_20)\ntarget_compile_options(stl2 INTERFACE\n    $<$<CXX_COMPILER_ID:GNU>:-fconcepts>\n    $<$<CXX_COMPILER_ID:Clang>:-Xclang -fconcepts-ts>\n    $<$<CXX_COMPILER_ID:MSVC>:/permissive->)\n\ninstall(DIRECTORY include/ DESTINATION include)\ninstall(TARGETS stl2 EXPORT cmcstl2-targets)\ninstall(EXPORT cmcstl2-targets DESTINATION lib/cmake/cmcstl2)\nfile(\n    WRITE ${PROJECT_BINARY_DIR}/cmcstl2-config.cmake\n    \"include(\\${CMAKE_CURRENT_LIST_DIR}/cmcstl2-targets.cmake)\")\ninstall(\n    FILES ${PROJECT_BINARY_DIR}/cmcstl2-config.cmake\n    DESTINATION lib/cmake/cmcstl2)\n\nif(STL2_BUILD_EXAMPLES)\n    add_subdirectory(examples)\nendif()\n\nif(STL2_BUILD_TESTING)\n    include(CTest)\n    add_custom_target(stl2-check ${CMAKE_CTEST_COMMAND} -V)\n    add_subdirectory(test)\nendif()\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "========================================================\nBoost Software License - Version 1.0 - August 17th, 2003\n========================================================\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\n==============================================================================\nlibc++ License\n==============================================================================\n\nThe libc++ library is dual licensed under both the University of Illinois\n\"BSD-Like\" license and the MIT license.  As a user of this code you may choose\nto use it under either license.  As a contributor, you agree to allow your code\nto be used under both.\n\nFull text of the relevant licenses is included below.\n\n==============================================================================\n\nUniversity of Illinois/NCSA\nOpen Source License\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\nhttp://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT\n\nAll rights reserved.\n\nDeveloped by:\n\n    LLVM Team\n\n    University of Illinois at Urbana-Champaign\n\n    http://llvm.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal with\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimers.\n\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimers in the\n      documentation and/or other materials provided with the distribution.\n\n    * Neither the names of the LLVM Team, University of Illinois at\n      Urbana-Champaign, nor the names of its contributors may be used to\n      endorse or promote products derived from this Software without specific\n      prior written permission.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nCONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE\nSOFTWARE.\n\n==============================================================================\n\nCopyright (c) 2009-2014 by the contributors listed in CREDITS.TXT\n  http://llvm.org/svn/llvm-project/libcxx/trunk/CREDITS.TXT\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n==============================================================================\nSGI C++ Standard Template Library license\n==============================================================================\n\n// Copyright (c) 1994\n// Hewlett-Packard Company\n//\n// Permission to use, copy, modify, distribute and sell this software\n// and its documentation for any purpose is hereby granted without fee,\n// provided that the above copyright notice appear in all copies and\n// that both that copyright notice and this permission notice appear\n// in supporting documentation.  Hewlett-Packard Company makes no\n// representations about the suitability of this software for any\n// purpose.  It is provided \"as is\" without express or implied warranty.\n//\n// Copyright (c) 1996\n// Silicon Graphics Computer Systems, Inc.\n//\n// Permission to use, copy, modify, distribute and sell this software\n// and its documentation for any purpose is hereby granted without fee,\n// provided that the above copyright notice appear in all copies and\n// that both that copyright notice and this permission notice appear\n// in supporting documentation.  Silicon Graphics makes no\n// representations about the suitability of this software for any\n// purpose.  It is provided \"as is\" without express or implied warranty.\n//\n"
  },
  {
    "path": "README.md",
    "content": "# cmcstl2\nAn implementation of [P0896R4 \"The One Ranges Proposal\"](https://wg21.link/p0896r4).\nCompilation requires a compiler with support for C++17 and the Concepts TS, which as of this writing means [GCC 7+](https://gcc.gnu.org/) with the `-std=c++1z` and `-fconcepts` command line options.\n"
  },
  {
    "path": "config/ci/Dockerfile",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nFROM ubuntu:disco\n\n# Install packages\nRUN apt update\nRUN apt upgrade -y\nRUN apt update\nRUN apt install -y git cmake ninja-build g++-8 g++-9\n"
  },
  {
    "path": "config/cmake/FindSanitizer.cmake",
    "content": "#\n#  Copyright Christopher Di Bella\n#  Copyright Morris Hafner\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\ninclude(FindPackageHandleStandardArgs)\ninclude(CheckCXXCompilerFlag)\ninclude(CMakePushCheckState)\n\nadd_library(Sanitizer::all INTERFACE IMPORTED)\nset(Sanitizer_FOUND ON)\n\nforeach(san ${Sanitizer_FIND_COMPONENTS})\n   if(TARGET Sanitizer::${san})\n      continue()\n   endif()\n\n   cmake_push_check_state(RESET)\n   list(APPEND CMAKE_REQUIRED_LIBRARIES -fsanitize=${san})\n   check_cxx_compiler_flag(-fsanitize=${san} ${san}_sanitizer_supported)\n   cmake_pop_check_state()\n   \n   if(${${san}_sanitizer_supported})\n      add_library(Sanitizer::${san} INTERFACE IMPORTED)\n      set_target_properties(Sanitizer::${san} PROPERTIES\n                       INTERFACE_COMPILE_OPTIONS -fsanitize=${san}\n                       INTERFACE_LINK_LIBRARIES -fsanitize=${san})\n      set(Sanitizer_${san}_FOUND TRUE)\n      set_property(TARGET Sanitizer::all APPEND PROPERTY\n         INTERFACE_LINK_LIBRARIES Sanitizer::${san})\n   endif()\nendforeach()\n\nfind_package_handle_standard_args(Sanitizer \n   REQUIRED_VARS Sanitizer_FOUND\nHANDLE_COMPONENTS)\n"
  },
  {
    "path": "examples/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_executable(simple simple.cpp)\ntarget_link_libraries(simple stl2)\n"
  },
  {
    "path": "examples/simple.cpp",
    "content": "#include <cassert>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <experimental/ranges/algorithm>\n#include <experimental/ranges/iterator>\n\n// Qualify everything with \"std::experimental::ranges\" if you like,\n// I prefer to use a namespace alias:\nnamespace ranges = std::experimental::ranges;\n\ntemplate<class...> class show_type;\n\ntemplate<ranges::readable T>\nvoid foo(T&) {}\n\nint main() {\n\tauto v = std::vector<std::string>{\"this\", \"is\", \"a\", \"test\"};\n\tranges::sort(v);\n\tauto out = ranges::ostream_iterator<std::string>{std::cout, \" \"};\n\tranges::copy(v, out);\n\tstd::cout << '\\n';\n\tauto result = ranges::reverse_copy(v, out);\n\tstd::cout << '\\n';\n\treturn !(result.in == ranges::end(v));\n}\n"
  },
  {
    "path": "include/experimental/ranges/algorithm",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/algorithm.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/concepts",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/concepts.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/functional",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/functional.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/iterator",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/iterator.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/memory",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/memory.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/random",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/random.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/range",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/ranges.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/ranges",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/ranges.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/type_traits",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/type_traits.hpp>\n"
  },
  {
    "path": "include/experimental/ranges/utility",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/utility.hpp>\n"
  },
  {
    "path": "include/meta/meta.hpp",
    "content": "/// \\file meta.hpp Tiny meta-programming library.\n//\n// Meta library\n//\n//  Copyright Eric Niebler 2014-present\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/meta\n//\n\n#ifndef META_HPP\n#define META_HPP\n\n#include <cstddef>\n#include <initializer_list>\n#include <meta/meta_fwd.hpp>\n#include <type_traits>\n#include <utility>\n\n#ifdef __clang__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n#pragma GCC diagnostic ignored \"-Wpragmas\"\n#pragma GCC diagnostic ignored \"-Wdocumentation-deprecated-sync\"\n#pragma GCC diagnostic ignored \"-Wmissing-variable-declarations\"\n#endif\n\n/// \\defgroup meta Meta\n///\n/// A tiny metaprogramming library\n\n/// \\defgroup trait Trait\n/// Trait invocation/composition.\n/// \\ingroup meta\n\n/// \\defgroup invocation Invocation\n/// Trait invocation\n/// \\ingroup trait\n\n/// \\defgroup composition Composition\n/// Trait composition\n/// \\ingroup trait\n\n/// \\defgroup logical Logical\n/// Logical operations\n/// \\ingroup meta\n\n/// \\defgroup algorithm Algorithms\n/// Algorithms.\n/// \\ingroup meta\n\n/// \\defgroup query Query/Search\n/// Query and search algorithms\n/// \\ingroup algorithm\n\n/// \\defgroup transformation Transformation\n/// Transformation algorithms\n/// \\ingroup algorithm\n\n/// \\defgroup runtime Runtime\n/// Runtime algorithms\n/// \\ingroup algorithm\n\n/// \\defgroup datatype Datatype\n/// Datatypes.\n/// \\ingroup meta\n\n/// \\defgroup list List\n/// \\ingroup datatype\n\n/// \\defgroup integral Integer sequence\n/// Equivalent to C++14's `std::integer_sequence`\n/// \\ingroup datatype\n\n/// \\defgroup extension Extension\n/// Extend meta with your own datatypes.\n/// \\ingroup datatype\n\n/// \\defgroup math Math\n/// Integral constant arithmetic.\n/// \\ingroup meta\n\n/// \\defgroup lazy_trait lazy\n/// \\ingroup trait\n\n/// \\defgroup lazy_invocation lazy\n/// \\ingroup invocation\n\n/// \\defgroup lazy_composition lazy\n/// \\ingroup composition\n\n/// \\defgroup lazy_logical lazy\n/// \\ingroup logical\n\n/// \\defgroup lazy_query lazy\n/// \\ingroup query\n\n/// \\defgroup lazy_transformation lazy\n/// \\ingroup transformation\n\n/// \\defgroup lazy_list lazy\n/// \\ingroup list\n\n/// \\defgroup lazy_datatype lazy\n/// \\ingroup datatype\n\n/// \\defgroup lazy_math lazy\n/// \\ingroup math\n\n/// Tiny metaprogramming library\nnamespace meta\n{\n    namespace detail\n    {\n        /// Returns a \\p T nullptr\n        template <typename T>\n        constexpr T *_nullptr_v()\n        {\n            return nullptr;\n        }\n\n#if META_CXX_VARIABLE_TEMPLATES\n        template <typename T>\n        META_INLINE_VAR constexpr T *nullptr_v = nullptr;\n#endif\n    } // namespace detail\n\n    /// An empty type.\n    /// \\ingroup datatype\n    struct nil_\n    {\n    };\n\n    /// Type alias for \\p T::type.\n    /// \\ingroup invocation\n    template <META_TYPE_CONSTRAINT(Trait) T>\n    using _t = typename T::type;\n\n#if META_CXX_VARIABLE_TEMPLATES || defined(META_DOXYGEN_INVOKED)\n    /// Variable alias for \\c T::type::value\n    /// \\note Requires C++14 or greater.\n    /// \\ingroup invocation\n    template <META_TYPE_CONSTRAINT(Integral) T>\n    constexpr typename T::type::value_type _v = T::type::value;\n#endif\n\n    /// Lazy versions of meta actions\n    namespace lazy\n    {\n        /// \\sa `meta::_t`\n        /// \\ingroup lazy_invocation\n        template <typename T>\n        using _t = defer<_t, T>;\n    } // namespace lazy\n\n    /// An integral constant wrapper for \\c std::size_t.\n    /// \\ingroup integral\n    template <std::size_t N>\n    using size_t = std::integral_constant<std::size_t, N>;\n\n    /// An integral constant wrapper for \\c bool.\n    /// \\ingroup integral\n    template <bool B>\n    using bool_ = std::integral_constant<bool, B>;\n\n    /// An integral constant wrapper for \\c int.\n    /// \\ingroup integral\n    template <int I>\n    using int_ = std::integral_constant<int, I>;\n\n    /// An integral constant wrapper for \\c char.\n    /// \\ingroup integral\n    template <char Ch>\n    using char_ = std::integral_constant<char, Ch>;\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // Math operations\n    /// An integral constant wrapper around the result of incrementing the wrapped integer \\c\n    /// T::type::value.\n    template <META_TYPE_CONSTRAINT(Integral) T>\n    using inc = std::integral_constant<decltype(T::type::value + 1), T::type::value + 1>;\n\n    /// An integral constant wrapper around the result of decrementing the wrapped integer \\c\n    /// T::type::value.\n    template <META_TYPE_CONSTRAINT(Integral) T>\n    using dec = std::integral_constant<decltype(T::type::value - 1), T::type::value - 1>;\n\n    /// An integral constant wrapper around the result of adding the two wrapped integers\n    /// \\c T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using plus = std::integral_constant<decltype(T::type::value + U::type::value),\n                                        T::type::value + U::type::value>;\n\n    /// An integral constant wrapper around the result of subtracting the two wrapped integers\n    /// \\c T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using minus = std::integral_constant<decltype(T::type::value - U::type::value),\n                                            T::type::value - U::type::value>;\n\n    /// An integral constant wrapper around the result of multiplying the two wrapped integers\n    /// \\c T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using multiplies = std::integral_constant<decltype(T::type::value * U::type::value),\n                                                T::type::value * U::type::value>;\n\n    /// An integral constant wrapper around the result of dividing the two wrapped integers \\c\n    /// T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using divides = std::integral_constant<decltype(T::type::value / U::type::value),\n                                            T::type::value / U::type::value>;\n\n    /// An integral constant wrapper around the result of negating the wrapped integer\n    /// \\c T::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T>\n    using negate = std::integral_constant<decltype(-T::type::value), -T::type::value>;\n\n    /// An integral constant wrapper around the remainder of dividing the two wrapped integers\n    /// \\c T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using modulus = std::integral_constant<decltype(T::type::value % U::type::value),\n                                            T::type::value % U::type::value>;\n\n    /// A Boolean integral constant wrapper around the result of comparing \\c T::type::value and\n    /// \\c U::type::value for equality.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using equal_to = bool_<T::type::value == U::type::value>;\n\n    /// A Boolean integral constant wrapper around the result of comparing \\c T::type::value and\n    /// \\c U::type::value for inequality.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using not_equal_to = bool_<T::type::value != U::type::value>;\n\n    /// A Boolean integral constant wrapper around \\c true if \\c T::type::value is greater than\n    /// \\c U::type::value; \\c false, otherwise.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using greater = bool_<(T::type::value > U::type::value)>;\n\n    /// A Boolean integral constant wrapper around \\c true if \\c T::type::value is less than \\c\n    /// U::type::value; \\c false, otherwise.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using less = bool_<(T::type::value < U::type::value)>;\n\n    /// A Boolean integral constant wrapper around \\c true if \\c T::type::value is greater than\n    /// or equal to \\c U::type::value; \\c false, otherwise.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using greater_equal = bool_<(T::type::value >= U::type::value)>;\n\n    /// A Boolean integral constant wrapper around \\c true if \\c T::type::value is less than or\n    /// equal to \\c U::type::value; \\c false, otherwise.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using less_equal = bool_<(T::type::value <= U::type::value)>;\n\n    /// An integral constant wrapper around the result of bitwise-and'ing the two wrapped\n    /// integers \\c T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using bit_and = std::integral_constant<decltype(T::type::value & U::type::value),\n                                            T::type::value & U::type::value>;\n\n    /// An integral constant wrapper around the result of bitwise-or'ing the two wrapped\n    /// integers \\c T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using bit_or = std::integral_constant<decltype(T::type::value | U::type::value),\n                                            T::type::value | U::type::value>;\n\n    /// An integral constant wrapper around the result of bitwise-exclusive-or'ing the two\n    /// wrapped integers \\c T::type::value and \\c U::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T, META_TYPE_CONSTRAINT(Integral) U>\n    using bit_xor = std::integral_constant<decltype(T::type::value ^ U::type::value),\n                                            T::type::value ^ U::type::value>;\n\n    /// An integral constant wrapper around the result of bitwise-complementing the wrapped\n    /// integer \\c T::type::value.\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral) T>\n    using bit_not = std::integral_constant<decltype(~T::type::value), ~T::type::value>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::int'\n        /// \\ingroup lazy_math\n        template <typename T>\n        using inc = defer<inc, T>;\n\n        /// \\sa 'meta::dec'\n        /// \\ingroup lazy_math\n        template <typename T>\n        using dec = defer<dec, T>;\n\n        /// \\sa 'meta::plus'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using plus = defer<plus, T, U>;\n\n        /// \\sa 'meta::minus'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using minus = defer<minus, T, U>;\n\n        /// \\sa 'meta::multiplies'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using multiplies = defer<multiplies, T, U>;\n\n        /// \\sa 'meta::divides'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using divides = defer<divides, T, U>;\n\n        /// \\sa 'meta::negate'\n        /// \\ingroup lazy_math\n        template <typename T>\n        using negate = defer<negate, T>;\n\n        /// \\sa 'meta::modulus'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using modulus = defer<modulus, T, U>;\n\n        /// \\sa 'meta::equal_to'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using equal_to = defer<equal_to, T, U>;\n\n        /// \\sa 'meta::not_equal_t'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using not_equal_to = defer<not_equal_to, T, U>;\n\n        /// \\sa 'meta::greater'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using greater = defer<greater, T, U>;\n\n        /// \\sa 'meta::less'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using less = defer<less, T, U>;\n\n        /// \\sa 'meta::greater_equal'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using greater_equal = defer<greater_equal, T, U>;\n\n        /// \\sa 'meta::less_equal'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using less_equal = defer<less_equal, T, U>;\n\n        /// \\sa 'meta::bit_and'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using bit_and = defer<bit_and, T, U>;\n\n        /// \\sa 'meta::bit_or'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using bit_or = defer<bit_or, T, U>;\n\n        /// \\sa 'meta::bit_xor'\n        /// \\ingroup lazy_math\n        template <typename T, typename U>\n        using bit_xor = defer<bit_xor, T, U>;\n\n        /// \\sa 'meta::bit_not'\n        /// \\ingroup lazy_math\n        template <typename T>\n        using bit_not = defer<bit_not, T>;\n    } // namespace lazy\n\n    /// \\cond\n    namespace detail\n    {\n        enum class indices_strategy_\n        {\n            done,\n            repeat,\n            recurse\n        };\n\n        constexpr indices_strategy_ strategy_(std::size_t cur, std::size_t end)\n        {\n            return cur >= end ? indices_strategy_::done\n                              : cur * 2 <= end ? indices_strategy_::repeat\n                                               : indices_strategy_::recurse;\n        }\n\n        template <typename T>\n        constexpr std::size_t range_distance_(T begin, T end)\n        {\n            return begin <= end ? static_cast<std::size_t>(end - begin)\n                                : throw \"The start of the integer_sequence must not be \"\n                                        \"greater than the end\";\n        }\n\n        template <std::size_t End, typename State, indices_strategy_ Status_>\n        struct make_indices_\n        {\n            using type = State;\n        };\n\n        template <typename T, T, typename>\n        struct coerce_indices_\n        {\n        };\n    } // namespace detail\n    /// \\endcond\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // integer_sequence\n#if !META_CXX_INTEGER_SEQUENCE\n    /// A container for a sequence of compile-time integer constants.\n    /// \\ingroup integral\n    template <typename T, T... Is>\n    struct integer_sequence\n    {\n        using value_type = T;\n        /// \\return `sizeof...(Is)`\n        static constexpr std::size_t size() noexcept { return sizeof...(Is); }\n    };\n#endif\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // index_sequence\n    /// A container for a sequence of compile-time integer constants of type\n    /// \\c std::size_t\n    /// \\ingroup integral\n    template <std::size_t... Is>\n    using index_sequence = integer_sequence<std::size_t, Is...>;\n\n#if META_HAS_MAKE_INTEGER_SEQ && !defined(META_DOXYGEN_INVOKED)\n    // Implement make_integer_sequence and make_index_sequence with the\n    // __make_integer_seq builtin on compilers that provide it. (Redirect\n    // through decltype to workaround suspected clang bug.)\n    /// \\cond\n    namespace detail\n    {\n        template <typename T, T N>\n        __make_integer_seq<integer_sequence, T, N> make_integer_sequence_();\n    }\n    /// \\endcond\n\n    template <typename T, T N>\n    using make_integer_sequence = decltype(detail::make_integer_sequence_<T, N>());\n\n    template <std::size_t N>\n    using make_index_sequence = make_integer_sequence<std::size_t, N>;\n#elif META_HAS_INTEGER_PACK && !defined(META_DOXYGEN_INVOKED)\n    // Implement make_integer_sequence and make_index_sequence with the\n    // __integer_pack builtin on compilers that provide it.\n    template <typename T, T N>\n    using make_integer_sequence = integer_sequence<T, __integer_pack(N)...>;\n\n    template <std::size_t N>\n    using make_index_sequence = make_integer_sequence<std::size_t, N>;\n#else\n    /// Generate \\c index_sequence containing integer constants [0,1,2,...,N-1].\n    /// \\par Complexity\n    /// \\f$ O(log(N)) \\f$.\n    /// \\ingroup integral\n    template <std::size_t N>\n    using make_index_sequence =\n        _t<detail::make_indices_<N, index_sequence<0>, detail::strategy_(1, N)>>;\n\n    /// Generate \\c integer_sequence containing integer constants [0,1,2,...,N-1].\n    /// \\par Complexity\n    /// \\f$ O(log(N)) \\f$.\n    /// \\ingroup integral\n    template <typename T, T N>\n    using make_integer_sequence =\n        _t<detail::coerce_indices_<T, 0, make_index_sequence<static_cast<std::size_t>(N)>>>;\n#endif\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // integer_range\n    /// Makes the integer sequence <tt>[From, To)</tt>.\n    /// \\par Complexity\n    /// \\f$ O(log(To - From)) \\f$.\n    /// \\ingroup integral\n    template <typename T, T From, T To>\n    using integer_range =\n        _t<detail::coerce_indices_<T, From,\n                                    make_index_sequence<detail::range_distance_(From, To)>>>;\n\n    /// \\cond\n    namespace detail\n    {\n        template <typename, typename>\n        struct concat_indices_\n        {\n        };\n\n        template <std::size_t... Is, std::size_t... Js>\n        struct concat_indices_<index_sequence<Is...>, index_sequence<Js...>>\n        {\n            using type = index_sequence<Is..., (Js + sizeof...(Is))...>;\n        };\n\n        template <>\n        struct make_indices_<0u, index_sequence<0>, indices_strategy_::done>\n        {\n            using type = index_sequence<>;\n        };\n\n        template <std::size_t End, std::size_t... Values>\n        struct make_indices_<End, index_sequence<Values...>, indices_strategy_::repeat>\n          : make_indices_<End, index_sequence<Values..., (Values + sizeof...(Values))...>,\n                          detail::strategy_(sizeof...(Values) * 2, End)>\n        {\n        };\n\n        template <std::size_t End, std::size_t... Values>\n        struct make_indices_<End, index_sequence<Values...>, indices_strategy_::recurse>\n          : concat_indices_<index_sequence<Values...>,\n                            make_index_sequence<End - sizeof...(Values)>>\n        {\n        };\n\n        template <typename T, T Offset, std::size_t... Values>\n        struct coerce_indices_<T, Offset, index_sequence<Values...>>\n        {\n            using type =\n                integer_sequence<T, static_cast<T>(static_cast<T>(Values) + Offset)...>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Evaluate the Invocable \\p Fn with the arguments \\p Args.\n    /// \\ingroup invocation\n    template <META_TYPE_CONSTRAINT(Invocable) Fn, typename... Args>\n    using invoke = typename Fn::template invoke<Args...>;\n\n    /// Lazy versions of meta actions\n    namespace lazy\n    {\n        /// \\sa `meta::invoke`\n        /// \\ingroup lazy_invocation\n        template <typename Fn, typename... Args>\n        using invoke = defer<invoke, Fn, Args...>;\n    } // namespace lazy\n\n    /// A Trait that always returns its argument \\p T. It is also an Invocable\n    /// that always returns \\p T.\n    /// \\ingroup trait\n    /// \\ingroup invocation\n    template <typename T>\n    struct id\n    {\n#if defined(META_WORKAROUND_CWG_1558) && !defined(META_DOXYGEN_INVOKED)\n        // Redirect through decltype for compilers that have not\n        // yet implemented CWG 1558:\n        static id impl(void *);\n\n        template <typename... Ts>\n        using invoke = _t<decltype(id::impl(static_cast<list<Ts...> *>(nullptr)))>;\n#else\n        template <typename...>\n        using invoke = T;\n#endif\n\n        using type = T;\n    };\n\n    /// An alias for type \\p T. Useful in non-deduced contexts.\n    /// \\ingroup trait\n    template <typename T>\n    using id_t = _t<id<T>>;\n\n    namespace lazy\n    {\n        /// \\sa `meta::id`\n        /// \\ingroup lazy_trait\n        /// \\ingroup lazy_invocation\n        template <typename T>\n        using id = defer<id, T>;\n    } // namespace lazy\n\n    /// An alias for `void`.\n    /// \\ingroup trait\n#if defined(META_WORKAROUND_CWG_1558) && !defined(META_DOXYGEN_INVOKED)\n    // Redirect through decltype for compilers that have not\n    // yet implemented CWG 1558:\n    template <typename... Ts>\n    using void_ = invoke<id<void>, Ts...>;\n#else\n    template <typename...>\n    using void_ = void;\n#endif\n\n#if META_CXX_VARIABLE_TEMPLATES\n#ifdef META_CONCEPT\n    /// `true` if `T::type` exists and names a type; `false` otherwise.\n    /// \\ingroup trait\n    template <typename T>\n    META_INLINE_VAR constexpr bool is_trait_v = Trait<T>;\n\n    /// `true` if `T::invoke` exists and names a class template; `false` otherwise.\n    /// \\ingroup trait\n    template <typename T>\n    META_INLINE_VAR constexpr bool is_callable_v = Invocable<T>;\n#else   // ^^^ Concepts / No concepts vvv\n    /// \\cond\n    namespace detail\n    {\n        template <typename, typename = void>\n        META_INLINE_VAR constexpr bool is_trait_ = false;\n\n        template <typename T>\n        META_INLINE_VAR constexpr bool is_trait_<T, void_<typename T::type>> = true;\n\n        template <typename, typename = void>\n        META_INLINE_VAR constexpr bool is_callable_ = false;\n\n        template <typename T>\n        META_INLINE_VAR constexpr bool is_callable_<T, void_<quote<T::template invoke>>> = true;\n    } // namespace detail\n    /// \\endcond\n\n    /// `true` if `T::type` exists and names a type; `false` otherwise.\n    /// \\ingroup trait\n    template <typename T>\n    META_INLINE_VAR constexpr bool is_trait_v = detail::is_trait_<T>;\n\n    /// `true` if `T::invoke` exists and names a class template; `false` otherwise.\n    /// \\ingroup trait\n    template <typename T>\n    META_INLINE_VAR constexpr bool is_callable_v = detail::is_callable_<T>;\n#endif  // Concepts vs. variable templates\n\n    /// An alias for `std::true_type` if `T::type` exists and names a type; otherwise, it's an\n    /// alias for `std::false_type`.\n    /// \\ingroup trait\n    template <typename T>\n    using is_trait = bool_<is_trait_v<T>>;\n\n    /// An alias for `std::true_type` if `T::invoke` exists and names a class template;\n    /// otherwise, it's an alias for `std::false_type`.\n    /// \\ingroup trait\n    template <typename T>\n    using is_callable = bool_<is_callable_v<T>>;\n#else   // ^^^ META_CXX_VARIABLE_TEMPLATES / !META_CXX_VARIABLE_TEMPLATES vvv\n    /// \\cond\n    namespace detail\n    {\n        template <typename, typename = void>\n        struct is_trait_\n        {\n            using type = std::false_type;\n        };\n\n        template <typename T>\n        struct is_trait_<T, void_<typename T::type>>\n        {\n            using type = std::true_type;\n        };\n\n        template <typename, typename = void>\n        struct is_callable_\n        {\n            using type = std::false_type;\n        };\n\n        template <typename T>\n        struct is_callable_<T, void_<quote<T::template invoke>>>\n        {\n            using type = std::true_type;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    template <typename T>\n    using is_trait = _t<detail::is_trait_<T>>;\n\n    /// An alias for `std::true_type` if `T::invoke` exists and names a class\n    /// template or alias template; otherwise, it's an alias for\n    /// `std::false_type`.\n    /// \\ingroup trait\n    template <typename T>\n    using is_callable = _t<detail::is_callable_<T>>;\n#endif\n\n    /// \\cond\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <template <typename...> class, typename...>\n        struct defer_\n        {\n        };\n\n        template <template <typename...> class C, typename... Ts>\n        requires Valid<C, Ts...> struct defer_<C, Ts...>\n        {\n            using type = C<Ts...>;\n        };\n\n        template <typename T, template <T...> class, T...>\n        struct defer_i_\n        {\n        };\n\n        template <typename T, template <T...> class C, T... Is>\n        requires Valid_I<T, C, Is...> struct defer_i_<T, C, Is...>\n        {\n            using type = C<Is...>;\n        };\n#elif defined(META_WORKAROUND_MSVC_703656) // ^^^ Concepts / MSVC workaround vvv\n        template <typename, template <typename...> class, typename...>\n        struct _defer_\n        {\n        };\n\n        template <template <typename...> class C, typename... Ts>\n        struct _defer_<void_<C<Ts...>>, C, Ts...>\n        {\n            using type = C<Ts...>;\n        };\n\n        template <template <typename...> class C, typename... Ts>\n        using defer_ = _defer_<void, C, Ts...>;\n\n        template <typename, typename T, template <T...> class, T...>\n        struct _defer_i_\n        {\n        };\n\n        template <typename T, template <T...> class C, T... Is>\n        struct _defer_i_<void_<C<Is...>>, T, C, Is...>\n        {\n            using type = C<Is...>;\n        };\n\n        template <typename T, template <T...> class C, T... Is>\n        using defer_i_ = _defer_i_<void, T, C, Is...>;\n#else                             // ^^^ workaround ^^^ / vvv no workaround vvv\n        template <template <typename...> class C, typename... Ts,\n                    template <typename...> class D = C>\n        id<D<Ts...>> try_defer_(int);\n        template <template <typename...> class C, typename... Ts>\n        nil_ try_defer_(long);\n\n        template <template <typename...> class C, typename... Ts>\n        using defer_ = decltype(detail::try_defer_<C, Ts...>(0));\n\n        template <typename T, template <T...> class C, T... Is, template <T...> class D = C>\n        id<D<Is...>> try_defer_i_(int);\n        template <typename T, template <T...> class C, T... Is>\n        nil_ try_defer_i_(long);\n\n        template <typename T, template <T...> class C, T... Is>\n        using defer_i_ = decltype(detail::try_defer_i_<T, C, Is...>(0));\n#endif                            // Concepts vs. MSVC vs. Other\n\n        template <typename T>\n        using _t_t = _t<_t<T>>;\n    } // namespace detail\n    /// \\endcond\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // defer\n    /// A wrapper that defers the instantiation of a template \\p C with type parameters \\p Ts in\n    /// a \\c lambda or \\c let expression.\n    ///\n    /// In the code below, the lambda would ideally be written as\n    /// `lambda<_a,_b,push_back<_a,_b>>`, however this fails since `push_back` expects its first\n    /// argument to be a list, not a placeholder. Instead, we express it using \\c defer as\n    /// follows:\n    ///\n    /// \\code\n    /// template <typename L>\n    /// using reverse = reverse_fold<L, list<>, lambda<_a, _b, defer<push_back, _a, _b>>>;\n    /// \\endcode\n    ///\n    /// \\ingroup invocation\n    template <template <typename...> class C, typename... Ts>\n    struct defer : detail::defer_<C, Ts...>\n    {\n    };\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // defer_i\n    /// A wrapper that defers the instantiation of a template \\p C with integral constant\n    /// parameters \\p Is in a \\c lambda or \\c let expression.\n    /// \\sa `defer`\n    /// \\ingroup invocation\n    template <typename T, template <T...> class C, T... Is>\n    struct defer_i : detail::defer_i_<T, C, Is...>\n    {\n    };\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // defer_trait\n    /// A wrapper that defers the instantiation of a trait \\p C with type parameters \\p Ts in a\n    /// \\c lambda or \\c let expression.\n    /// \\sa `defer`\n    /// \\ingroup invocation\n    template <template <typename...> class C, typename... Ts>\n    using defer_trait = defer<detail::_t_t, detail::defer_<C, Ts...>>;\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // defer_trait_i\n    /// A wrapper that defers the instantiation of a trait \\p C with integral constant\n    /// parameters \\p Is in a \\c lambda or \\c let expression.\n    /// \\sa `defer_i`\n    /// \\ingroup invocation\n    template <typename T, template <T...> class C, T... Is>\n    using defer_trait_i = defer<detail::_t_t, detail::defer_i_<T, C, Is...>>;\n\n    /// An alias that computes the size of the type \\p T.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup trait\n    template <typename T>\n    using sizeof_ = meta::size_t<sizeof(T)>;\n\n    /// An alias that computes the alignment required for any instance of the type \\p T.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup trait\n    template <typename T>\n    using alignof_ = meta::size_t<alignof(T)>;\n\n    namespace lazy\n    {\n        /// \\sa `meta::sizeof_`\n        /// \\ingroup lazy_trait\n        template <typename T>\n        using sizeof_ = defer<sizeof_, T>;\n\n        /// \\sa `meta::alignof_`\n        /// \\ingroup lazy_trait\n        template <typename T>\n        using alignof_ = defer<alignof_, T>;\n    } // namespace lazy\n\n#if META_CXX_VARIABLE_TEMPLATES\n    /// is\n    /// Test whether a type \\p T is an instantiation of class\n    /// template \\p C.\n    /// \\ingroup trait\n    template <typename T, template <typename...> class C>\n    using is = bool_<is_v<T, C>>;\n#else\n    /// is\n    /// \\cond\n    namespace detail\n    {\n        template <typename, template <typename...> class>\n        struct is_ : std::false_type\n        {\n        };\n\n        template <typename... Ts, template <typename...> class C>\n        struct is_<C<Ts...>, C> : std::true_type\n        {\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Test whether a type \\c T is an instantiation of class\n    /// template \\c C.\n    /// \\ingroup trait\n    template <typename T, template <typename...> class C>\n    using is = _t<detail::is_<T, C>>;\n#endif\n\n    /// Compose the Invocables \\p Fns in the parameter pack \\p Ts.\n    /// \\ingroup composition\n    template <META_TYPE_CONSTRAINT(Invocable)... Fns>\n    struct compose_\n    {\n    };\n\n    template <META_TYPE_CONSTRAINT(Invocable) Fn0>\n    struct compose_<Fn0>\n    {\n        template <typename... Ts>\n        using invoke = invoke<Fn0, Ts...>;\n    };\n\n    template <META_TYPE_CONSTRAINT(Invocable) Fn0, META_TYPE_CONSTRAINT(Invocable)... Fns>\n    struct compose_<Fn0, Fns...>\n    {\n        template <typename... Ts>\n        using invoke = invoke<Fn0, invoke<compose_<Fns...>, Ts...>>;\n    };\n\n    template <typename... Fns>\n    using compose = compose_<Fns...>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::compose'\n        /// \\ingroup lazy_composition\n        template <typename... Fns>\n        using compose = defer<compose, Fns...>;\n    } // namespace lazy\n\n    /// Turn a template \\p C into an Invocable.\n    /// \\ingroup composition\n    template <template <typename...> class C>\n    struct quote\n    {\n        // Indirection through defer here needed to avoid Core issue 1430\n        // https://wg21.link/cwg1430\n        template <typename... Ts>\n        using invoke = _t<defer<C, Ts...>>;\n    };\n\n    /// Turn a template \\p C taking literals of type \\p T into a\n    /// Invocable.\n    /// \\ingroup composition\n    template <typename T, template <T...> class C>\n    struct quote_i\n    {\n        // Indirection through defer_i here needed to avoid Core issue 1430\n        // https://wg21.link/cwg1430\n        template <META_TYPE_CONSTRAINT(Integral)... Ts>\n        using invoke = _t<defer_i<T, C, Ts::type::value...>>;\n    };\n\n#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 8 && \\\n!defined(META_DOXYGEN_INVOKED)\n    template <template <typename...> class C>\n    struct quote_trait\n    {\n        template <typename... Ts>\n        using invoke = _t<invoke<quote<C>, Ts...>>;\n    };\n\n    template <typename T, template <T...> class C>\n    struct quote_trait_i\n    {\n        template <typename... Ts>\n        using invoke = _t<invoke<quote_i<T, C>, Ts...>>;\n    };\n#else\n    // clang-format off\n    /// Turn a trait template \\p C into an Invocable.\n    /// \\code\n    /// static_assert(std::is_same<invoke<quote_trait<std::add_const>, int>, int const>::value, \"\");\n    /// \\endcode\n    /// \\ingroup composition\n    template <template <typename...> class C>\n    using quote_trait = compose<quote<_t>, quote<C>>;\n\n    /// Turn a trait template \\p C taking literals of type \\p T into an Invocable.\n    /// \\ingroup composition\n    template <typename T, template <T...> class C>\n    using quote_trait_i = compose<quote<_t>, quote_i<T, C>>;\n    // clang-format on\n#endif\n\n    /// An Invocable that partially applies the Invocable\n    /// \\p Fn by binding the arguments \\p Ts to the \\e front of \\p Fn.\n    /// \\ingroup composition\n    template <META_TYPE_CONSTRAINT(Invocable) Fn, typename... Ts>\n    struct bind_front\n    {\n        template <typename... Us>\n        using invoke = invoke<Fn, Ts..., Us...>;\n    };\n\n    /// An Invocable that partially applies the Invocable \\p Fn by binding the\n    /// arguments \\p Us to the \\e back of \\p Fn.\n    /// \\ingroup composition\n    template <META_TYPE_CONSTRAINT(Invocable) Fn, typename... Us>\n    struct bind_back\n    {\n        template <typename... Ts>\n        using invoke = invoke<Fn, Ts..., Us...>;\n    };\n\n    namespace lazy\n    {\n        /// \\sa 'meta::bind_front'\n        /// \\ingroup lazy_composition\n        template <typename Fn, typename... Ts>\n        using bind_front = defer<bind_front, Fn, Ts...>;\n\n        /// \\sa 'meta::bind_back'\n        /// \\ingroup lazy_composition\n        template <typename Fn, typename... Ts>\n        using bind_back = defer<bind_back, Fn, Ts...>;\n    } // namespace lazy\n\n    /// Extend meta with your own datatypes.\n    namespace extension\n    {\n        /// A trait that unpacks the types in the type list \\p L into the Invocable\n        /// \\p Fn.\n        /// \\ingroup extension\n        template <META_TYPE_CONSTRAINT(Invocable) Fn, typename L>\n        struct apply\n        {\n        };\n\n        template <META_TYPE_CONSTRAINT(Invocable) Fn, typename Ret, typename... Args>\n        struct apply<Fn, Ret(Args...)> : lazy::invoke<Fn, Ret, Args...>\n        {\n        };\n\n        template <META_TYPE_CONSTRAINT(Invocable) Fn, template <typename...> class T,\n                    typename... Ts>\n        struct apply<Fn, T<Ts...>> : lazy::invoke<Fn, Ts...>\n        {\n        };\n\n        template <META_TYPE_CONSTRAINT(Invocable) Fn, typename T, T... Is>\n        struct apply<Fn, integer_sequence<T, Is...>>\n          : lazy::invoke<Fn, std::integral_constant<T, Is>...>\n        {\n        };\n    } // namespace extension\n\n    /// Applies the Invocable \\p Fn using the types in the type list \\p L as\n    /// arguments.\n    /// \\ingroup invocation\n    template <META_TYPE_CONSTRAINT(Invocable) Fn, typename L>\n    using apply = _t<extension::apply<Fn, L>>;\n\n    namespace lazy\n    {\n        template <typename Fn, typename L>\n        using apply = defer<apply, Fn, L>;\n    }\n\n    /// An Invocable that takes a bunch of arguments, bundles them into a type\n    /// list, and then calls the Invocable \\p Fn with the type list \\p Q.\n    /// \\ingroup composition\n    template <META_TYPE_CONSTRAINT(Invocable) Fn,\n                META_TYPE_CONSTRAINT(Invocable) Q = quote<list>>\n    using curry = compose<Fn, Q>;\n\n    /// An Invocable that takes a type list, unpacks the types, and then\n    /// calls the Invocable \\p Fn with the types.\n    /// \\ingroup composition\n    template <META_TYPE_CONSTRAINT(Invocable) Fn>\n    using uncurry = bind_front<quote<apply>, Fn>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::curry'\n        /// \\ingroup lazy_composition\n        template <typename Fn, typename Q = quote<list>>\n        using curry = defer<curry, Fn, Q>;\n\n        /// \\sa 'meta::uncurry'\n        /// \\ingroup lazy_composition\n        template <typename Fn>\n        using uncurry = defer<uncurry, Fn>;\n    } // namespace lazy\n\n    /// An Invocable that reverses the order of the first two arguments.\n    /// \\ingroup composition\n    template <META_TYPE_CONSTRAINT(Invocable) Fn>\n    struct flip\n    {\n    private:\n        template <typename... Ts>\n        struct impl\n        {\n        };\n        template <typename A, typename B, typename... Ts>\n        struct impl<A, B, Ts...> : lazy::invoke<Fn, B, A, Ts...>\n        {\n        };\n\n    public:\n        template <typename... Ts>\n        using invoke = _t<impl<Ts...>>;\n    };\n\n    namespace lazy\n    {\n        /// \\sa 'meta::flip'\n        /// \\ingroup lazy_composition\n        template <typename Fn>\n        using flip = defer<flip, Fn>;\n    } // namespace lazy\n\n    /// \\cond\n    namespace detail\n    {\n        template <typename...>\n        struct on_\n        {\n        };\n        template <typename Fn, typename... Gs>\n        struct on_<Fn, Gs...>\n        {\n            template <typename... Ts>\n            using invoke = invoke<Fn, invoke<compose<Gs...>, Ts>...>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Use as `on<Fn, Gs...>`. Creates an Invocable that applies Invocable \\c Fn to the\n    /// result of applying Invocable `compose<Gs...>` to all the arguments.\n    /// \\ingroup composition\n    template <META_TYPE_CONSTRAINT(Invocable)... Fns>\n    using on_ = detail::on_<Fns...>;\n\n    template <typename... Fns>\n    using on = on_<Fns...>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::on'\n        /// \\ingroup lazy_composition\n        template <typename Fn, typename G>\n        using on = defer<on, Fn, G>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // if_\n    /// \\cond\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <typename...>\n        struct _if_\n        {\n        };\n\n        template <Integral If>\n        struct _if_<If> : std::enable_if<_v<If>>\n        {\n        };\n\n        template <Integral If, typename Then>\n        struct _if_<If, Then> : std::enable_if<_v<If>, Then>\n        {\n        };\n\n        template <Integral If, typename Then, typename Else>\n        struct _if_<If, Then, Else> : std::conditional<_v<If>, Then, Else>\n        {\n        };\n#elif defined(__clang__)\n        // Clang is faster with this implementation\n        template <typename, typename = bool>\n        struct _if_\n        {\n        };\n\n        template <typename If>\n        struct _if_<list<If>, decltype(bool(If::type::value))> : std::enable_if<If::type::value>\n        {\n        };\n\n        template <typename If, typename Then>\n        struct _if_<list<If, Then>, decltype(bool(If::type::value))>\n          : std::enable_if<If::type::value, Then>\n        {\n        };\n\n        template <typename If, typename Then, typename Else>\n        struct _if_<list<If, Then, Else>, decltype(bool(If::type::value))>\n          : std::conditional<If::type::value, Then, Else>\n        {\n        };\n#else\n        // GCC seems to prefer this implementation\n        template <typename, typename = std::true_type>\n        struct _if_\n        {\n        };\n\n        template <typename If>\n        struct _if_<list<If>, bool_<If::type::value>>\n        {\n            using type = void;\n        };\n\n        template <typename If, typename Then>\n        struct _if_<list<If, Then>, bool_<If::type::value>>\n        {\n            using type = Then;\n        };\n\n        template <typename If, typename Then, typename Else>\n        struct _if_<list<If, Then, Else>, bool_<If::type::value>>\n        {\n            using type = Then;\n        };\n\n        template <typename If, typename Then, typename Else>\n        struct _if_<list<If, Then, Else>, bool_<!If::type::value>>\n        {\n            using type = Else;\n        };\n#endif\n    } // namespace detail\n        /// \\endcond\n\n    /// Select one type or another depending on a compile-time Boolean.\n    /// \\ingroup logical\n#ifdef META_CONCEPT\n    template <typename... Args>\n    using if_ = _t<detail::_if_<Args...>>;\n\n    /// Select one type or another depending on a compile-time Boolean.\n    /// \\ingroup logical\n    template <bool If, typename... Args>\n    using if_c = _t<detail::_if_<bool_<If>, Args...>>;\n#else\n    template <typename... Args>\n    using if_ = _t<detail::_if_<list<Args...>>>;\n\n    template <bool If, typename... Args>\n    using if_c = _t<detail::_if_<list<bool_<If>, Args...>>>;\n#endif\n\n    namespace lazy\n    {\n        /// \\sa 'meta::if_'\n        /// \\ingroup lazy_logical\n        template <typename... Args>\n        using if_ = defer<if_, Args...>;\n\n        /// \\sa 'meta::if_c'\n        /// \\ingroup lazy_logical\n        template <bool If, typename... Args>\n        using if_c = if_<bool_<If>, Args...>;\n    } // namespace lazy\n\n    /// \\cond\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <typename...>\n        struct _and_\n        {\n        };\n\n        template <>\n        struct _and_<> : std::true_type\n        {\n        };\n\n        template <Integral B, typename... Bs>\n        requires (bool(B::type::value)) struct _and_<B, Bs...> : _and_<Bs...>\n        {\n        };\n\n        template <Integral B, typename... Bs>\n        requires (!bool(B::type::value)) struct _and_<B, Bs...> : std::false_type\n        {\n        };\n\n        template <typename...>\n        struct _or_\n        {\n        };\n\n        template <>\n        struct _or_<> : std::false_type\n        {\n        };\n\n        template <Integral B, typename... Bs>\n        requires (bool(B::type::value)) struct _or_<B, Bs...> : std::true_type\n        {\n        };\n\n        template <Integral B, typename... Bs>\n        requires (!bool(B::type::value)) struct _or_<B, Bs...> : _or_<Bs...>\n        {\n        };\n#else\n        template <bool>\n        struct _and_\n        {\n            template <typename...>\n            using invoke = std::true_type;\n        };\n\n        template <>\n        struct _and_<false>\n        {\n            template <typename B, typename... Bs>\n            using invoke = invoke<\n                if_c<!B::type::value, id<std::false_type>, _and_<0 == sizeof...(Bs)>>,\n                Bs...>;\n        };\n\n        template <bool>\n        struct _or_\n        {\n            template <typename = void>\n            using invoke = std::false_type;\n        };\n\n        template <>\n        struct _or_<false>\n        {\n            template <typename B, typename... Bs>\n            using invoke = invoke<\n                if_c<B::type::value, id<std::true_type>, _or_<0 == sizeof...(Bs)>>,\n                Bs...>;\n        };\n#endif\n    } // namespace detail\n    /// \\endcond\n\n    /// Logically negate the Boolean parameter\n    /// \\ingroup logical\n    template <bool B>\n    using not_c = bool_<!B>;\n\n    /// Logically negate the integral constant-wrapped Boolean parameter.\n    /// \\ingroup logical\n    template <META_TYPE_CONSTRAINT(Integral) B>\n    using not_ = not_c<B::type::value>;\n\n#if META_CXX_FOLD_EXPRESSIONS && !defined(META_WORKAROUND_GCC_UNKNOWN1)\n    template <bool... Bs>\n    META_INLINE_VAR constexpr bool and_v = (true && ... && Bs);\n\n    /// Logically AND together all the Boolean parameters\n    /// \\ingroup logical\n    template <bool... Bs>\n#if defined(META_WORKAROUND_MSVC_756112) || defined(META_WORKAROUND_GCC_86356)\n    using and_c = bool_<and_v<Bs...>>;\n#else\n    using and_c = bool_<(true && ... && Bs)>;\n#endif\n#else\n#if defined(META_WORKAROUND_GCC_66405)\n    template <bool... Bs>\n    using and_c = std::is_same<integer_sequence<bool, true, Bs...>,\n                                integer_sequence<bool, Bs..., true>>;\n#else\n    template <bool... Bs>\n    using and_c = std::is_same<integer_sequence<bool, Bs...>,\n                                integer_sequence<bool, (Bs || true)...>>;\n#endif\n#if META_CXX_VARIABLE_TEMPLATES\n    template <bool... Bs>\n    META_INLINE_VAR constexpr bool and_v = and_c<Bs...>::value;\n#endif\n#endif\n\n    /// Logically AND together all the integral constant-wrapped Boolean\n    /// parameters, \\e without short-circuiting.\n    /// \\ingroup logical\n    template <META_TYPE_CONSTRAINT(Integral)... Bs>\n    using strict_and_ = and_c<Bs::type::value...>;\n\n    template <typename... Bs>\n    using strict_and = strict_and_<Bs...>;\n\n    /// Logically AND together all the integral constant-wrapped Boolean\n    /// parameters, \\e with short-circuiting.\n    /// \\ingroup logical\n    template <typename... Bs>\n#ifdef META_CONCEPT\n    using and_ = _t<detail::_and_<Bs...>>;\n#else\n    // Make a trip through defer<> to avoid CWG1430\n    // https://wg21.link/cwg1430\n    using and_ = _t<defer<detail::_and_<0 == sizeof...(Bs)>::template invoke, Bs...>>;\n#endif\n\n    /// Logically OR together all the Boolean parameters\n    /// \\ingroup logical\n#if META_CXX_FOLD_EXPRESSIONS && !defined(META_WORKAROUND_GCC_UNKNOWN1)\n    template <bool... Bs>\n    META_INLINE_VAR constexpr bool or_v = (false || ... || Bs);\n\n    template <bool... Bs>\n#if defined(META_WORKAROUND_MSVC_756112) || defined(META_WORKAROUND_GCC_86356)\n    using or_c = bool_<or_v<Bs...>>;\n#else\n    using or_c = bool_<(false || ... || Bs)>;\n#endif\n#else\n    template <bool... Bs>\n    using or_c = not_<std::is_same<integer_sequence<bool, Bs...>,\n                                    integer_sequence<bool, (Bs && false)...>>>;\n#if META_CXX_VARIABLE_TEMPLATES\n    template <bool... Bs>\n    META_INLINE_VAR constexpr bool or_v = or_c<Bs...>::value;\n#endif\n#endif\n\n    /// Logically OR together all the integral constant-wrapped Boolean\n    /// parameters, \\e without short-circuiting.\n    /// \\ingroup logical\n    template <META_TYPE_CONSTRAINT(Integral)... Bs>\n    using strict_or_ = or_c<Bs::type::value...>;\n\n    template <typename... Bs>\n    using strict_or = strict_or_<Bs...>;\n\n    /// Logically OR together all the integral constant-wrapped Boolean\n    /// parameters, \\e with short-circuiting.\n    /// \\ingroup logical\n    template <typename... Bs>\n#ifdef META_CONCEPT\n    using or_ = _t<detail::_or_<Bs...>>;\n#else\n    // Make a trip through defer<> to avoid CWG1430\n    // https://wg21.link/cwg1430\n    using or_ = _t<defer<detail::_or_<0 == sizeof...(Bs)>::template invoke, Bs...>>;\n#endif\n\n    namespace lazy\n    {\n        /// \\sa 'meta::and_'\n        /// \\ingroup lazy_logical\n        template <typename... Bs>\n        using and_ = defer<and_, Bs...>;\n\n        /// \\sa 'meta::or_'\n        /// \\ingroup lazy_logical\n        template <typename... Bs>\n        using or_ = defer<or_, Bs...>;\n\n        /// \\sa 'meta::not_'\n        /// \\ingroup lazy_logical\n        template <typename B>\n        using not_ = defer<not_, B>;\n\n        /// \\sa 'meta::strict_and'\n        /// \\ingroup lazy_logical\n        template <typename... Bs>\n        using strict_and = defer<strict_and, Bs...>;\n\n        /// \\sa 'meta::strict_or'\n        /// \\ingroup lazy_logical\n        template <typename... Bs>\n        using strict_or = defer<strict_or, Bs...>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // fold\n    /// \\cond\n    namespace detail\n    {\n        template <typename, typename, typename>\n        struct fold_\n        {\n        };\n\n        template <typename Fn, typename T0, typename T1, typename T2, typename T3, typename T4,\n                    typename T5, typename T6, typename T7, typename T8, typename T9>\n        struct compose10_\n        {\n            template <typename X, typename Y>\n            using F = invoke<Fn, X, Y>;\n\n            template <typename S>\n            using invoke =\n                F<F<F<F<F<F<F<F<F<F<_t<S>, T0>, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;\n        };\n\n#ifdef META_CONCEPT\n        template <typename Fn>\n        struct compose_\n        {\n            template <typename X, typename Y>\n            using F = invoke<Fn, X, Y>;\n\n            template <typename T0, typename T1, typename T2, typename T3, typename T4,\n                        typename T5, typename T6, typename T7, typename T8, typename T9,\n                        typename State>\n            using invoke =\n                F<F<F<F<F<F<F<F<F<F<State, T0>, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;\n        };\n\n        template <typename State, typename Fn>\n        struct fold_<list<>, State, Fn>\n        {\n            using type = State;\n        };\n\n        template <typename Head, typename... Tail, typename State, typename Fn>\n        requires Valid<invoke, Fn, State, Head>\n        struct fold_<list<Head, Tail...>, State, Fn>\n          : fold_<list<Tail...>, invoke<Fn, State, Head>, Fn>\n        {\n        };\n\n        template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,\n                    typename T6, typename T7, typename T8, typename T9, typename... Tail,\n                    typename State, typename Fn>\n        requires Valid<invoke, compose_<Fn>, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, State>\n        struct fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Tail...>, State, Fn>\n          : fold_<list<Tail...>,\n                  invoke<compose_<Fn>, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, State>, Fn>\n        {\n        };\n#else   // ^^^ Concepts / no Concepts vvv\n        template <typename Fn, typename T0>\n        struct compose1_\n        {\n            template <typename X>\n            using invoke = invoke<Fn, _t<X>, T0>;\n        };\n\n        template <typename State, typename Fn>\n        struct fold_<list<>, State, Fn> : State\n        {\n        };\n\n        template <typename Head, typename... Tail, typename State, typename Fn>\n        struct fold_<list<Head, Tail...>, State, Fn>\n          : fold_<list<Tail...>, lazy::invoke<compose1_<Fn, Head>, State>, Fn>\n        {\n        };\n\n        template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,\n                    typename T6, typename T7, typename T8, typename T9, typename... Tail,\n                    typename State, typename Fn>\n        struct fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Tail...>, State, Fn>\n          : fold_<list<Tail...>,\n                  lazy::invoke<compose10_<Fn, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, State>, Fn>\n        {\n        };\n#endif  // META_CONCEPT\n    } // namespace detail\n    /// \\endcond\n\n    /// Return a new \\c meta::list constructed by doing a left fold of the list \\p L using\n    /// binary Invocable \\p Fn and initial state \\p State. That is, the \\c State_N for\n    /// the list element \\c A_N is computed by `Fn(State_N-1, A_N) -> State_N`.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, typename State, META_TYPE_CONSTRAINT(Invocable) Fn>\n#ifdef META_CONCEPT\n    using fold = _t<detail::fold_<L, State, Fn>>;\n#else\n    using fold = _t<detail::fold_<L, id<State>, Fn>>;\n#endif\n\n    /// An alias for `meta::fold`.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, typename State, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using accumulate = fold<L, State, Fn>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::foldl'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename State, typename Fn>\n        using fold = defer<fold, L, State, Fn>;\n\n        /// \\sa 'meta::accumulate'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename State, typename Fn>\n        using accumulate = defer<accumulate, L, State, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // reverse_fold\n    /// \\cond\n    namespace detail\n    {\n        template <typename, typename, typename>\n        struct reverse_fold_\n        {\n        };\n\n        template <typename State, typename Fn>\n        struct reverse_fold_<list<>, State, Fn>\n        {\n            using type = State;\n        };\n\n#ifdef META_CONCEPT\n        template <typename Head, typename... L, typename State, typename Fn>\n        requires Trait<reverse_fold_<list<L...>, State, Fn>> struct reverse_fold_<\n            list<Head, L...>, State, Fn>\n          : lazy::invoke<Fn, _t<reverse_fold_<list<L...>, State, Fn>>, Head>\n        {\n        };\n#else\n        template <typename Head, typename... Tail, typename State, typename Fn>\n        struct reverse_fold_<list<Head, Tail...>, State, Fn>\n          : lazy::invoke<compose1_<Fn, Head>, reverse_fold_<list<Tail...>, State, Fn>>\n        {\n        };\n#endif\n\n        template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,\n                    typename T6, typename T7, typename T8, typename T9, typename... Tail,\n                    typename State, typename Fn>\n        struct reverse_fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Tail...>, State, Fn>\n          : lazy::invoke<compose10_<Fn, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0>,\n                            reverse_fold_<list<Tail...>, State, Fn>>\n        {\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return a new \\c meta::list constructed by doing a right fold of the list \\p L using\n    /// binary Invocable \\p Fn and initial state \\p State. That is, the \\c State_N for the list\n    /// element \\c A_N is computed by `Fn(A_N, State_N+1) -> State_N`.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, typename State, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using reverse_fold = _t<detail::reverse_fold_<L, State, Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::foldr'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename State, typename Fn>\n        using reverse_fold = defer<reverse_fold, L, State, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // npos\n    /// A special value used to indicate no matches. It equals the maximum\n    /// value representable by std::size_t.\n    /// \\ingroup list\n    using npos = meta::size_t<std::size_t(-1)>;\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // list\n    /// A list of types.\n    /// \\ingroup list\n    template <typename... Ts>\n    struct list\n    {\n        using type = list;\n        /// \\return `sizeof...(Ts)`\n        static constexpr std::size_t size() noexcept { return sizeof...(Ts); }\n    };\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // size\n    /// An integral constant wrapper that is the size of the \\c meta::list\n    /// \\p L.\n    /// \\ingroup list\n    template <META_TYPE_CONSTRAINT(List) L>\n    using size = meta::size_t<L::size()>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::size'\n        /// \\ingroup lazy_list\n        template <typename L>\n        using size = defer<size, L>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // concat\n    /// \\cond\n    namespace detail\n    {\n        template <typename... Lists>\n        struct concat_\n        {\n        };\n\n        template <>\n        struct concat_<>\n        {\n            using type = list<>;\n        };\n\n        template <typename... L1>\n        struct concat_<list<L1...>>\n        {\n            using type = list<L1...>;\n        };\n\n        template <typename... L1, typename... L2>\n        struct concat_<list<L1...>, list<L2...>>\n        {\n            using type = list<L1..., L2...>;\n        };\n\n        template <typename... L1, typename... L2, typename... L3>\n        struct concat_<list<L1...>, list<L2...>, list<L3...>>\n        {\n            using type = list<L1..., L2..., L3...>;\n        };\n\n        template <typename... L1, typename... L2, typename... L3, typename... Rest>\n        struct concat_<list<L1...>, list<L2...>, list<L3...>, Rest...>\n          : concat_<list<L1..., L2..., L3...>, Rest...>\n        {\n        };\n\n        template <typename... L1, typename... L2, typename... L3, typename... L4,\n                    typename... L5, typename... L6, typename... L7, typename... L8,\n                    typename... L9, typename... L10, typename... Rest>\n        struct concat_<list<L1...>, list<L2...>, list<L3...>, list<L4...>, list<L5...>,\n                        list<L6...>, list<L7...>, list<L8...>, list<L9...>, list<L10...>,\n                        Rest...>\n          : concat_<list<L1..., L2..., L3..., L4..., L5..., L6..., L7..., L8..., L9..., L10...>,\n                    Rest...>\n        {\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Concatenates several lists into a single list.\n    /// \\pre The parameters must all be instantiations of \\c meta::list.\n    /// \\par Complexity\n    /// \\f$ O(L) \\f$ where \\f$ L \\f$ is the number of lists in the list of lists.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List)... Ls>\n    using concat_ = _t<detail::concat_<Ls...>>;\n\n    template <typename... Lists>\n    using concat = concat_<Lists...>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::concat'\n        /// \\ingroup lazy_transformation\n        template <typename... Lists>\n        using concat = defer<concat, Lists...>;\n    } // namespace lazy\n\n    /// Joins a list of lists into a single list.\n    /// \\pre The parameter must be an instantiation of \\c meta::list\\<T...\\>\n    /// where each \\c T is itself an instantiation of \\c meta::list.\n    /// \\par Complexity\n    /// \\f$ O(L) \\f$ where \\f$ L \\f$ is the number of lists in the list of\n    /// lists.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) ListOfLists>\n    using join = apply<quote<concat>, ListOfLists>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::join'\n        /// \\ingroup lazy_transformation\n        template <typename ListOfLists>\n        using join = defer<join, ListOfLists>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // transform\n    /// \\cond\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <typename... Args>\n        struct transform_\n        {\n        };\n\n        template <typename... Ts, Invocable Fn>\n        requires (Valid<invoke, Fn, Ts> && ...)\n        struct transform_<list<Ts...>, Fn>\n        {\n            using type = list<invoke<Fn, Ts>...>;\n        };\n\n        template <typename... Ts, typename... Us, Invocable Fn>\n        requires (Valid<invoke, Fn, Ts, Us> && ...)\n        struct transform_<list<Ts...>, list<Us...>, Fn>\n        {\n            using type = list<invoke<Fn, Ts, Us>...>;\n        };\n#else\n        template <typename, typename = void>\n        struct transform_\n        {\n        };\n\n        template <typename... Ts, typename Fn>\n        struct transform_<list<list<Ts...>, Fn>, void_<invoke<Fn, Ts>...>>\n        {\n            using type = list<invoke<Fn, Ts>...>;\n        };\n\n        template <typename... Ts0, typename... Ts1, typename Fn>\n        struct transform_<list<list<Ts0...>, list<Ts1...>, Fn>,\n                            void_<invoke<Fn, Ts0, Ts1>...>>\n        {\n            using type = list<invoke<Fn, Ts0, Ts1>...>;\n        };\n#endif\n    } // namespace detail\n        /// \\endcond\n\n    /// Return a new \\c meta::list constructed by transforming all the\n    /// elements in \\p L with the unary Invocable \\p Fn. \\c transform can\n    /// also be called with two lists of the same length and a binary\n    /// Invocable, in which case it returns a new list constructed with the\n    /// results of calling \\c Fn with each element in the lists, pairwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n#ifdef META_CONCEPT\n    template <typename... Args>\n    using transform = _t<detail::transform_<Args...>>;\n#else\n    template <typename... Args>\n    using transform = _t<detail::transform_<list<Args...>>>;\n#endif\n\n    namespace lazy\n    {\n        /// \\sa 'meta::transform'\n        /// \\ingroup lazy_transformation\n        template <typename... Args>\n        using transform = defer<transform, Args...>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // repeat_n\n    /// \\cond\n    namespace detail\n    {\n        template <typename T, std::size_t>\n        using first_ = T;\n\n        template <typename T, typename Ints>\n        struct repeat_n_c_\n        {\n        };\n\n        template <typename T, std::size_t... Is>\n        struct repeat_n_c_<T, index_sequence<Is...>>\n        {\n            using type = list<first_<T, Is>...>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Generate `list<T,T,T...T>` of size \\p N arguments.\n    /// \\par Complexity\n    /// \\f$ O(log N) \\f$.\n    /// \\ingroup list\n    template <std::size_t N, typename T = void>\n    using repeat_n_c = _t<detail::repeat_n_c_<T, make_index_sequence<N>>>;\n\n    /// Generate `list<T,T,T...T>` of size \\p N arguments.\n    /// \\par Complexity\n    /// \\f$ O(log N) \\f$.\n    /// \\ingroup list\n    template <META_TYPE_CONSTRAINT(Integral) N, typename T = void>\n    using repeat_n = repeat_n_c<N::type::value, T>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::repeat_n'\n        /// \\ingroup lazy_list\n        template <typename N, typename T = void>\n        using repeat_n = defer<repeat_n, N, T>;\n\n        /// \\sa 'meta::repeat_n_c'\n        /// \\ingroup lazy_list\n        template <std::size_t N, typename T = void>\n        using repeat_n_c = defer<repeat_n, meta::size_t<N>, T>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // at\n    /// \\cond\n    namespace detail\n    {\n#if META_HAS_TYPE_PACK_ELEMENT && !defined(META_DOXYGEN_INVOKED)\n        template <typename L, std::size_t N, typename = void>\n        struct at_\n        {\n        };\n\n        template <typename... Ts, std::size_t N>\n        struct at_<list<Ts...>, N, void_<__type_pack_element<N, Ts...>>>\n        {\n            using type = __type_pack_element<N, Ts...>;\n        };\n#else\n        template <typename VoidPtrs>\n        struct at_impl_;\n\n        template <typename... VoidPtrs>\n        struct at_impl_<list<VoidPtrs...>>\n        {\n            static nil_ eval(...);\n\n            template <typename T, typename... Us>\n            static T eval(VoidPtrs..., T *, Us *...);\n        };\n\n        template <typename L, std::size_t N>\n        struct at_\n        {\n        };\n\n        template <typename... Ts, std::size_t N>\n        struct at_<list<Ts...>, N>\n          : decltype(at_impl_<repeat_n_c<N, void *>>::eval(static_cast<id<Ts> *>(nullptr)...))\n        {\n        };\n#endif    // META_HAS_TYPE_PACK_ELEMENT\n    } // namespace detail\n    /// \\endcond\n\n    /// Return the \\p N th element in the \\c meta::list \\p L.\n    /// \\par Complexity\n    /// Amortized \\f$ O(1) \\f$.\n    /// \\ingroup list\n    template <META_TYPE_CONSTRAINT(List) L, std::size_t N>\n    using at_c = _t<detail::at_<L, N>>;\n\n    /// Return the \\p N th element in the \\c meta::list \\p L.\n    /// \\par Complexity\n    /// Amortized \\f$ O(1) \\f$.\n    /// \\ingroup list\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Integral) N>\n    using at = at_c<L, N::type::value>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::at'\n        /// \\ingroup lazy_list\n        template <typename L, typename N>\n        using at = defer<at, L, N>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // drop\n    /// \\cond\n    namespace detail\n    {\n        ///////////////////////////////////////////////////////////////////////////////////////\n        /// drop_impl_\n        template <typename VoidPtrs>\n        struct drop_impl_\n        {\n            static nil_ eval(...);\n        };\n\n        template <typename... VoidPtrs>\n        struct drop_impl_<list<VoidPtrs...>>\n        {\n            static nil_ eval(...);\n\n            template <typename... Ts>\n            static id<list<Ts...>> eval(VoidPtrs..., id<Ts> *...);\n        };\n\n        template <>\n        struct drop_impl_<list<>>\n        {\n            template <typename... Ts>\n            static id<list<Ts...>> eval(id<Ts> *...);\n        };\n\n        template <typename L, std::size_t N>\n        struct drop_\n        {\n        };\n\n        template <typename... Ts, std::size_t N>\n        struct drop_<list<Ts...>, N>\n#if META_CXX_VARIABLE_TEMPLATES\n          : decltype(drop_impl_<repeat_n_c<N, void *>>::eval(detail::nullptr_v<id<Ts>>...))\n#else\n          : decltype(drop_impl_<repeat_n_c<N, void *>>::eval(detail::_nullptr_v<id<Ts>>()...))\n#endif\n        {\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return a new \\c meta::list by removing the first \\p N elements from \\p L.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, std::size_t N>\n    using drop_c = _t<detail::drop_<L, N>>;\n\n    /// Return a new \\c meta::list by removing the first \\p N elements from \\p L.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Integral) N>\n    using drop = drop_c<L, N::type::value>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::drop'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename N>\n        using drop = defer<drop, L, N>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // front\n    /// \\cond\n    namespace detail\n    {\n        template <typename L>\n        struct front_\n        {\n        };\n\n        template <typename Head, typename... Tail>\n        struct front_<list<Head, Tail...>>\n        {\n            using type = Head;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return the first element in \\c meta::list \\p L.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup list\n    template <META_TYPE_CONSTRAINT(List) L>\n    using front = _t<detail::front_<L>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::front'\n        /// \\ingroup lazy_list\n        template <typename L>\n        using front = defer<front, L>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // back\n    /// \\cond\n    namespace detail\n    {\n        template <typename L>\n        struct back_\n        {\n        };\n\n        template <typename Head, typename... Tail>\n        struct back_<list<Head, Tail...>>\n        {\n            using type = at_c<list<Head, Tail...>, sizeof...(Tail)>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return the last element in \\c meta::list \\p L.\n    /// \\par Complexity\n    /// Amortized \\f$ O(1) \\f$.\n    /// \\ingroup list\n    template <META_TYPE_CONSTRAINT(List) L>\n    using back = _t<detail::back_<L>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::back'\n        /// \\ingroup lazy_list\n        template <typename L>\n        using back = defer<back, L>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // push_front\n    /// Return a new \\c meta::list by adding the element \\c T to the front of \\p L.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, typename... Ts>\n    using push_front = apply<bind_front<quote<list>, Ts...>, L>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::push_front'\n        /// \\ingroup lazy_transformation\n        template <typename... Ts>\n        using push_front = defer<push_front, Ts...>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // pop_front\n    /// \\cond\n    namespace detail\n    {\n        template <typename L>\n        struct pop_front_\n        {\n        };\n\n        template <typename Head, typename... L>\n        struct pop_front_<list<Head, L...>>\n        {\n            using type = list<L...>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return a new \\c meta::list by removing the first element from the\n    /// front of \\p L.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L>\n    using pop_front = _t<detail::pop_front_<L>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::pop_front'\n        /// \\ingroup lazy_transformation\n        template <typename L>\n        using pop_front = defer<pop_front, L>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // push_back\n    /// Return a new \\c meta::list by adding the element \\c T to the back of \\p L.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\note \\c pop_back not provided because it cannot be made to meet the\n    /// complexity guarantees one would expect.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, typename... Ts>\n    using push_back = apply<bind_back<quote<list>, Ts...>, L>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::push_back'\n        /// \\ingroup lazy_transformation\n        template <typename... Ts>\n        using push_back = defer<push_back, Ts...>;\n    } // namespace lazy\n\n    /// \\cond\n    namespace detail\n    {\n        template <typename T, typename U>\n        using min_ = if_<less<U, T>, U, T>;\n\n        template <typename T, typename U>\n        using max_ = if_<less<U, T>, T, U>;\n    } // namespace detail\n    /// \\endcond\n\n    /// An integral constant wrapper around the minimum of `Ts::type::value...`\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral)... Ts>\n    using min_ = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::min_>>;\n\n    template <typename... Ts>\n    using min = min_<Ts...>;\n\n    /// An integral constant wrapper around the maximum of `Ts::type::value...`\n    /// \\ingroup math\n    template <META_TYPE_CONSTRAINT(Integral)... Ts>\n    using max_ = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::max_>>;\n\n    template <typename... Ts>\n    using max = max_<Ts...>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::min'\n        /// \\ingroup lazy_math\n        template <typename... Ts>\n        using min = defer<min, Ts...>;\n\n        /// \\sa 'meta::max'\n        /// \\ingroup lazy_math\n        template <typename... Ts>\n        using max = defer<max, Ts...>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // empty\n    /// An Boolean integral constant wrapper around \\c true if \\p L is an\n    /// empty type list; \\c false, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(1) \\f$.\n    /// \\ingroup list\n    template <META_TYPE_CONSTRAINT(List) L>\n    using empty = bool_<0 == size<L>::type::value>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::empty'\n        /// \\ingroup lazy_list\n        template <typename L>\n        using empty = defer<empty, L>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // pair\n    /// A list with exactly two elements\n    /// \\ingroup list\n    template <typename F, typename S>\n    using pair = list<F, S>;\n\n    /// Retrieve the first element of the \\c pair \\p Pair\n    /// \\ingroup list\n    template <typename Pair>\n    using first = front<Pair>;\n\n    /// Retrieve the first element of the \\c pair \\p Pair\n    /// \\ingroup list\n    template <typename Pair>\n    using second = front<pop_front<Pair>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::first'\n        /// \\ingroup lazy_list\n        template <typename Pair>\n        using first = defer<first, Pair>;\n\n        /// \\sa 'meta::second'\n        /// \\ingroup lazy_list\n        template <typename Pair>\n        using second = defer<second, Pair>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // find_index\n    /// \\cond\n    namespace detail\n    {\n        // With thanks to Peter Dimov:\n        constexpr std::size_t find_index_i_(bool const *const first, bool const *const last,\n                                            std::size_t N = 0)\n        {\n            return first == last ? npos::value\n                                 : *first ? N : find_index_i_(first + 1, last, N + 1);\n        }\n\n        template <typename L, typename T>\n        struct find_index_\n        {\n        };\n\n        template <typename V>\n        struct find_index_<list<>, V>\n        {\n            using type = npos;\n        };\n\n        template <typename... T, typename V>\n        struct find_index_<list<T...>, V>\n        {\n#ifdef META_WORKAROUND_LLVM_28385\n            static constexpr bool s_v[sizeof...(T)] = {std::is_same<T, V>::value...};\n#else\n            static constexpr bool s_v[] = {std::is_same<T, V>::value...};\n#endif\n            using type = size_t<find_index_i_(s_v, s_v + sizeof...(T))>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Finds the index of the first occurrence of the type \\p T within the list \\p L.\n    /// Returns `#meta::npos` if the type \\p T was not found.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    /// \\sa `meta::npos`\n    template <META_TYPE_CONSTRAINT(List) L, typename T>\n    using find_index = _t<detail::find_index_<L, T>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::find_index'\n        /// \\ingroup lazy_query\n        template <typename L, typename T>\n        using find_index = defer<find_index, L, T>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // reverse_find_index\n    /// \\cond\n    namespace detail\n    {\n        // With thanks to Peter Dimov:\n        constexpr std::size_t reverse_find_index_i_(bool const *const first,\n                                                    bool const *const last, std::size_t N)\n        {\n            return first == last\n                ? npos::value\n                : *(last - 1) ? N - 1 : reverse_find_index_i_(first, last - 1, N - 1);\n        }\n\n        template <typename L, typename T>\n        struct reverse_find_index_\n        {\n        };\n\n        template <typename V>\n        struct reverse_find_index_<list<>, V>\n        {\n            using type = npos;\n        };\n\n        template <typename... T, typename V>\n        struct reverse_find_index_<list<T...>, V>\n        {\n#ifdef META_WORKAROUND_LLVM_28385\n            static constexpr bool s_v[sizeof...(T)] = {std::is_same<T, V>::value...};\n#else\n            static constexpr bool s_v[] = {std::is_same<T, V>::value...};\n#endif\n            using type = size_t<reverse_find_index_i_(s_v, s_v + sizeof...(T), sizeof...(T))>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Finds the index of the last occurrence of the type \\p T within the\n    /// list \\p L. Returns `#meta::npos` if the type \\p T was not found.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    /// \\sa `#meta::npos`\n    template <META_TYPE_CONSTRAINT(List) L, typename T>\n    using reverse_find_index = _t<detail::reverse_find_index_<L, T>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::reverse_find_index'\n        /// \\ingroup lazy_query\n        template <typename L, typename T>\n        using reverse_find_index = defer<reverse_find_index, L, T>;\n    } // namespace lazy\n\n    ////////////////////////////////////////////////////////////////////////////////////\n    // find\n    /// Return the tail of the list \\p L starting at the first occurrence of\n    /// \\p T, if any such element exists; the empty list, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, typename T>\n    using find = drop<L, min<find_index<L, T>, size<L>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::find'\n        /// \\ingroup lazy_query\n        template <typename L, typename T>\n        using find = defer<find, L, T>;\n    } // namespace lazy\n\n    ////////////////////////////////////////////////////////////////////////////////////\n    // reverse_find\n    /// \\cond\n    namespace detail\n    {\n        template <typename L, typename T, typename State = list<>>\n        struct reverse_find_\n        {\n        };\n\n        template <typename T, typename State>\n        struct reverse_find_<list<>, T, State>\n        {\n            using type = State;\n        };\n\n        template <typename Head, typename... L, typename T, typename State>\n        struct reverse_find_<list<Head, L...>, T, State> : reverse_find_<list<L...>, T, State>\n        {\n        };\n\n        template <typename... L, typename T, typename State>\n        struct reverse_find_<list<T, L...>, T, State>\n          : reverse_find_<list<L...>, T, list<T, L...>>\n        {\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return the tail of the list \\p L starting at the last occurrence of \\p T, if any such\n    /// element exists; the empty list, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, typename T>\n    using reverse_find = drop<L, min<reverse_find_index<L, T>, size<L>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::rfind'\n        /// \\ingroup lazy_query\n        template <typename L, typename T>\n        using reverse_find = defer<reverse_find, L, T>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // find_if\n    /// \\cond\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <typename L, typename Fn>\n        struct find_if_\n        {\n        };\n\n        template <typename Fn>\n        struct find_if_<list<>, Fn>\n        {\n            using type = list<>;\n        };\n\n        template <typename Head, typename... L, typename Fn>\n        requires Integral<invoke<Fn, Head>>\n        struct find_if_<list<Head, L...>, Fn>\n          : if_<invoke<Fn, Head>, id<list<Head, L...>>, find_if_<list<L...>, Fn>>\n        {\n        };\n#else\n        constexpr bool const *find_if_i_(bool const *const begin, bool const *const end)\n        {\n            return begin == end || *begin ? begin : find_if_i_(begin + 1, end);\n        }\n\n        template <typename L, typename Fn, typename = void>\n        struct find_if_\n        {\n        };\n\n        template <typename Fn>\n        struct find_if_<list<>, Fn>\n        {\n            using type = list<>;\n        };\n\n        template <typename... L, typename Fn>\n        struct find_if_<list<L...>, Fn,\n                        void_<integer_sequence<bool, bool(invoke<Fn, L>::type::value)...>>>\n        {\n#ifdef META_WORKAROUND_LLVM_28385\n            static constexpr bool s_v[sizeof...(L)] = {invoke<Fn, L>::type::value...};\n#else\n            static constexpr bool s_v[] = {invoke<Fn, L>::type::value...};\n#endif\n            using type =\n                drop_c<list<L...>, detail::find_if_i_(s_v, s_v + sizeof...(L)) - s_v>;\n        };\n#endif\n    } // namespace detail\n    /// \\endcond\n\n    /// Return the tail of the list \\p L starting at the first element `A`\n    /// such that `invoke<Fn, A>::%value` is \\c true, if any such element\n    /// exists; the empty list, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using find_if = _t<detail::find_if_<L, Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::find_if'\n        /// \\ingroup lazy_query\n        template <typename L, typename Fn>\n        using find_if = defer<find_if, L, Fn>;\n    } // namespace lazy\n\n    ////////////////////////////////////////////////////////////////////////////////////\n    // reverse_find_if\n    /// \\cond\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <typename L, typename Fn, typename State = list<>>\n        struct reverse_find_if_\n        {\n        };\n\n        template <typename Fn, typename State>\n        struct reverse_find_if_<list<>, Fn, State>\n        {\n            using type = State;\n        };\n\n        template <typename Head, typename... L, typename Fn, typename State>\n        requires Integral<invoke<Fn, Head>>\n        struct reverse_find_if_<list<Head, L...>, Fn, State>\n          : reverse_find_if_<list<L...>, Fn, if_<invoke<Fn, Head>, list<Head, L...>, State>>\n        {\n        };\n#else\n        constexpr bool const *reverse_find_if_i_(bool const *const begin, bool const *const pos,\n                                                    bool const *const end)\n        {\n            return begin == pos\n                ? end\n                : *(pos - 1) ? pos - 1 : reverse_find_if_i_(begin, pos - 1, end);\n        }\n\n        template <typename L, typename Fn, typename = void>\n        struct reverse_find_if_\n        {\n        };\n\n        template <typename Fn>\n        struct reverse_find_if_<list<>, Fn>\n        {\n            using type = list<>;\n        };\n\n        template <typename... L, typename Fn>\n        struct reverse_find_if_<\n            list<L...>, Fn,\n            void_<integer_sequence<bool, bool(invoke<Fn, L>::type::value)...>>>\n        {\n#ifdef META_WORKAROUND_LLVM_28385\n            static constexpr bool s_v[sizeof...(L)] = {invoke<Fn, L>::type::value...};\n#else\n            static constexpr bool s_v[] = {invoke<Fn, L>::type::value...};\n#endif\n            using type =\n                drop_c<list<L...>, detail::reverse_find_if_i_(s_v, s_v + sizeof...(L),\n                                                                    s_v + sizeof...(L)) -\n                                            s_v>;\n        };\n#endif\n    } // namespace detail\n    /// \\endcond\n\n    /// Return the tail of the list \\p L starting at the last element `A`\n    /// such that `invoke<Fn, A>::%value` is \\c true, if any such element\n    /// exists; the empty list, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using reverse_find_if = _t<detail::reverse_find_if_<L, Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::rfind_if'\n        /// \\ingroup lazy_query\n        template <typename L, typename Fn>\n        using reverse_find_if = defer<reverse_find_if, L, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // replace\n    /// \\cond\n    namespace detail\n    {\n        template <typename L, typename T, typename U>\n        struct replace_\n        {\n        };\n\n        template <typename... L, typename T, typename U>\n        struct replace_<list<L...>, T, U>\n        {\n            using type = list<if_<std::is_same<T, L>, U, L>...>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return a new \\c meta::list where all instances of type \\p T have\n    /// been replaced with \\p U.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, typename T, typename U>\n    using replace = _t<detail::replace_<L, T, U>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::replace'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename T, typename U>\n        using replace = defer<replace, T, U>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // replace_if\n    /// \\cond\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <typename L, typename C, typename U>\n        struct replace_if_\n        {\n        };\n\n        template <typename... L, typename C, typename U>\n        requires (Integral<invoke<C, L>> &&...)\n        struct replace_if_<list<L...>, C, U>\n        {\n            using type = list<if_<invoke<C, L>, U, L>...>;\n        };\n#else\n        template <typename L, typename C, typename U, typename = void>\n        struct replace_if_\n        {\n        };\n\n        template <typename... L, typename C, typename U>\n        struct replace_if_<list<L...>, C, U,\n                            void_<integer_sequence<bool, bool(invoke<C, L>::type::value)...>>>\n        {\n            using type = list<if_<invoke<C, L>, U, L>...>;\n        };\n#endif\n    } // namespace detail\n    /// \\endcond\n\n    /// Return a new \\c meta::list where all elements \\c A of the list \\p L\n    /// for which `invoke<C,A>::%value` is \\c true have been replaced with\n    /// \\p U.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, typename C, typename U>\n    using replace_if = _t<detail::replace_if_<L, C, U>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::replace_if'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename C, typename U>\n        using replace_if = defer<replace_if, C, U>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////\n    // count\n    namespace detail\n    {\n        template <typename, typename>\n        struct count_\n        {\n        };\n\n#if defined(META_CONCEPT) || META_CXX_VARIABLE_TEMPLATES && META_CXX_FOLD_EXPRESSIONS\n        template <typename... Ts, typename T>\n        struct count_<list<Ts...>, T>\n        {\n            using type = meta::size_t<((std::size_t)_v<std::is_same<T, Ts>> + ...)>;\n        };\n#else\n        constexpr std::size_t count_i_(bool const *const begin, bool const *const end,\n                                        std::size_t n)\n        {\n            return begin == end ? n : detail::count_i_(begin + 1, end, n + *begin);\n        }\n\n        template <typename T>\n        struct count_<list<>, T>\n        {\n            using type = meta::size_t<0>;\n        };\n\n        template <typename... L, typename T>\n        struct count_<list<L...>, T>\n        {\n#ifdef META_WORKAROUND_LLVM_28385\n            static constexpr bool s_v[sizeof...(L)] = {std::is_same<T, L>::value...};\n#else\n            static constexpr bool s_v[] = {std::is_same<T, L>::value...};\n#endif\n            using type = meta::size_t<detail::count_i_(s_v, s_v + sizeof...(L), 0u)>;\n        };\n#endif\n    } // namespace detail\n\n    /// Count the number of times a type \\p T appears in the list \\p L.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, typename T>\n    using count = _t<detail::count_<L, T>>;\n\n    namespace lazy\n    {\n        /// \\sa `meta::count`\n        /// \\ingroup lazy_query\n        template <typename L, typename T>\n        using count = defer<count, L, T>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////\n    // count_if\n    namespace detail\n    {\n#ifdef META_CONCEPT\n        template <typename, typename>\n        struct count_if_\n        {\n        };\n\n        template <typename... Ts, typename Fn>\n        requires (Integral<invoke<Fn, Ts>> &&...)\n        struct count_if_<list<Ts...>, Fn>\n        {\n            using type = meta::size_t<((std::size_t)(bool)_v<invoke<Fn, Ts>> + ...)>;\n        };\n#else\n        template <typename L, typename Fn, typename = void>\n        struct count_if_\n        {\n        };\n\n        template <typename Fn>\n        struct count_if_<list<>, Fn>\n        {\n            using type = meta::size_t<0>;\n        };\n\n        template <typename... L, typename Fn>\n        struct count_if_<list<L...>, Fn,\n                            void_<integer_sequence<bool, bool(invoke<Fn, L>::type::value)...>>>\n        {\n#if META_CXX_FOLD_EXPRESSIONS\n            using type = meta::size_t<((std::size_t)(bool)invoke<Fn, L>::type::value + ...)>;\n#else\n#ifdef META_WORKAROUND_LLVM_28385\n            static constexpr bool s_v[sizeof...(L)] = {invoke<Fn, L>::type::value...};\n#else\n            static constexpr bool s_v[] = {invoke<Fn, L>::type::value...};\n#endif\n            using type = meta::size_t<detail::count_i_(s_v, s_v + sizeof...(L), 0u)>;\n#endif  // META_CXX_FOLD_EXPRESSIONS\n        };\n#endif  // META_CONCEPT\n    } // namespace detail\n\n    /// Count the number of times the predicate \\p Fn evaluates to true for all the elements in\n    /// the list \\p L.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using count_if = _t<detail::count_if_<L, Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa `meta::count_if`\n        /// \\ingroup lazy_query\n        template <typename L, typename Fn>\n        using count_if = defer<count_if, L, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // filter\n    /// \\cond\n    namespace detail\n    {\n        template <typename Pred>\n        struct filter_\n        {\n            template <typename A>\n            using invoke = if_c<invoke<Pred, A>::type::value, list<A>, list<>>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Returns a new meta::list where only those elements of \\p L that satisfy the\n    /// Callable \\p Pred such that `invoke<Pred,A>::%value` is \\c true are present.\n    /// That is, those elements that don't satisfy the \\p Pred are \"removed\".\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <typename L, typename Pred>\n    using filter = join<transform<L, detail::filter_<Pred>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::filter'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename Fn>\n        using filter = defer<filter, L, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // static_const\n    ///\\cond\n    namespace detail\n    {\n        template <typename T>\n        struct static_const\n        {\n            static constexpr T value{};\n        };\n\n        // Avoid potential ODR violations with global objects:\n        template <typename T>\n        constexpr T static_const<T>::value;\n    } // namespace detail\n\n    ///\\endcond\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // for_each\n    /// \\cond\n    namespace detail\n    {\n        struct for_each_fn\n        {\n            template <class Fn, class... Args>\n            constexpr auto operator()(list<Args...>, Fn f) const -> Fn\n            {\n                return (void)std::initializer_list<int>{((void)f(Args{}), 0)...}, f;\n            }\n        };\n    } // namespace detail\n    /// \\endcond\n\n#if META_CXX_INLINE_VARIABLES\n    /// `for_each(L, Fn)` calls the \\p Fn for each\n    /// argument in the \\p L.\n    /// \\ingroup runtime\n    inline constexpr detail::for_each_fn for_each{};\n#else\n    ///\\cond\n    namespace\n    {\n        /// \\endcond\n\n        /// `for_each(List, UnaryFunction)` calls the \\p UnaryFunction for each\n        /// argument in the \\p List.\n        /// \\ingroup runtime\n        constexpr auto &&for_each = detail::static_const<detail::for_each_fn>::value;\n\n        /// \\cond\n    }\n    /// \\endcond\n#endif\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // transpose\n    /// Given a list of lists of the same number of types \\p ListOfLists, transpose the\n    /// elements from the lists.\n    /// \\par Complexity\n    /// \\f$ O(N \\times M) \\f$, where \\f$ N \\f$ is the size of the outer list, and \\f$ M \\f$ is\n    /// the size of all of the inner lists.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) ListOfLists>\n    using transpose = fold<ListOfLists, repeat_n<size<front<ListOfLists>>, list<>>,\n                            bind_back<quote<transform>, quote<push_back>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::transpose'\n        /// \\ingroup lazy_transformation\n        template <typename ListOfLists>\n        using transpose = defer<transpose, ListOfLists>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // zip_with\n    /// Given a list of lists of types \\p ListOfLists and an Invocable \\p Fn, construct a new\n    /// list by calling \\p Fn with the elements from the lists pairwise.\n    /// \\par Complexity\n    /// \\f$ O(N \\times M) \\f$, where \\f$ N \\f$ is the size of the outer list, and\n    /// \\f$ M \\f$ is the size of the inner lists.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(Invocable) Fn, META_TYPE_CONSTRAINT(List) ListOfLists>\n    using zip_with = transform<transpose<ListOfLists>, uncurry<Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::zip_with'\n        /// \\ingroup lazy_transformation\n        template <typename Fn, typename ListOfLists>\n        using zip_with = defer<zip_with, Fn, ListOfLists>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // zip\n    /// Given a list of lists of types \\p ListOfLists, construct a new list by grouping the\n    /// elements from the lists pairwise into `meta::list`s.\n    /// \\par Complexity\n    /// \\f$ O(N \\times M) \\f$, where \\f$ N \\f$ is the size of the outer list, and \\f$ M \\f$\n    /// is the size of the inner lists.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) ListOfLists>\n    using zip = transpose<ListOfLists>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::zip'\n        /// \\ingroup lazy_transformation\n        template <typename ListOfLists>\n        using zip = defer<zip, ListOfLists>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // as_list\n    /// \\cond\n    namespace detail\n    {\n        template <typename T>\n        using uncvref_t = _t<std::remove_cv<_t<std::remove_reference<T>>>>;\n\n        // Indirection here needed to avoid Core issue 1430\n        // https://wg21.link/cwg1430\n        template <typename Sequence>\n        struct as_list_ : lazy::invoke<uncurry<quote<list>>, Sequence>\n        {\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Turn a type into an instance of \\c meta::list in a way determined by\n    /// \\c meta::apply.\n    /// \\ingroup list\n    template <typename Sequence>\n    using as_list = _t<detail::as_list_<detail::uncvref_t<Sequence>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::as_list'\n        /// \\ingroup lazy_list\n        template <typename Sequence>\n        using as_list = defer<as_list, Sequence>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // reverse\n    /// \\cond\n    namespace detail\n    {\n        template <typename L, typename State = list<>>\n        struct reverse_ : lazy::fold<L, State, quote<push_front>>\n        {\n        };\n\n        template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,\n                    typename T6, typename T7, typename T8, typename T9, typename... Ts,\n                    typename... Us>\n        struct reverse_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ts...>, list<Us...>>\n          : reverse_<list<Ts...>, list<T9, T8, T7, T6, T5, T4, T3, T2, T1, T0, Us...>>\n        {\n        };\n    }\n    /// \\endcond\n\n    /// Return a new \\c meta::list by reversing the elements in the list \\p L.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L>\n    using reverse = _t<detail::reverse_<L>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::reverse'\n        /// \\ingroup lazy_transformation\n        template <typename L>\n        using reverse = defer<reverse, L>;\n    } // namespace lazy\n\n    /// Logically negate the result of Invocable \\p Fn.\n    /// \\ingroup trait\n    template <META_TYPE_CONSTRAINT(Invocable) Fn>\n    using not_fn = compose<quote<not_>, Fn>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::not_fn'\n        /// \\ingroup lazy_trait\n        template <typename Fn>\n        using not_fn = defer<not_fn, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // all_of\n    /// A Boolean integral constant wrapper around \\c true if `invoke<Fn, A>::%value` is \\c true\n    /// for all elements \\c A in \\c meta::list \\p L; \\c false, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using all_of = empty<find_if<L, not_fn<Fn>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::all_of'\n        /// \\ingroup lazy_query\n        template <typename L, typename Fn>\n        using all_of = defer<all_of, L, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // any_of\n    /// A Boolean integral constant wrapper around \\c true if `invoke<Fn, A>::%value` is\n    /// \\c true for any element \\c A in \\c meta::list \\p L; \\c false, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using any_of = not_<empty<find_if<L, Fn>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::any_of'\n        /// \\ingroup lazy_query\n        template <typename L, typename Fn>\n        using any_of = defer<any_of, L, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // none_of\n    /// A Boolean integral constant wrapper around \\c true if `invoke<Fn, A>::%value` is\n    /// \\c false for all elements \\c A in \\c meta::list \\p L; \\c false, otherwise.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using none_of = empty<find_if<L, Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::none_of'\n        /// \\ingroup lazy_query\n        template <typename L, META_TYPE_CONSTRAINT(Invocable) Fn>\n        using none_of = defer<none_of, L, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // in\n    /// A Boolean integral constant wrapper around \\c true if there is at least one occurrence\n    /// of \\p T in \\p L.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup query\n    template <META_TYPE_CONSTRAINT(List) L, typename T>\n    using in = not_<empty<find<L, T>>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::in'\n        /// \\ingroup lazy_query\n        template <typename L, typename T>\n        using in = defer<in, L, T>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // inherit\n    /// \\cond\n    namespace detail\n    {\n        template <typename L>\n        struct inherit_\n        {\n        };\n\n        template <typename... L>\n        struct inherit_<list<L...>> : L...\n        {\n            using type = inherit_;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// A type that inherits from all the types in the list\n    /// \\pre The types in the list must be unique\n    /// \\pre All the types in the list must be non-final class types\n    /// \\ingroup datatype\n    template <META_TYPE_CONSTRAINT(List) L>\n    using inherit = meta::_t<detail::inherit_<L>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::inherit'\n        /// \\ingroup lazy_datatype\n        template <typename L>\n        using inherit = defer<inherit, L>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // unique\n    /// \\cond\n    namespace detail\n    {\n        template <typename Set, typename T>\n        struct in_\n        {\n        };\n\n        template <typename... Set, typename T>\n        struct in_<list<Set...>, T> : std::is_base_of<id<T>, inherit<list<id<Set>...>>>\n        {\n        };\n\n        template <typename Set, typename T>\n        struct insert_back_\n        {\n        };\n\n        template <typename... Set, typename T>\n        struct insert_back_<list<Set...>, T>\n        {\n            using type = if_<in_<list<Set...>, T>, list<Set...>, list<Set..., T>>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Return a new \\c meta::list where all duplicate elements have been removed.\n    /// \\par Complexity\n    /// \\f$ O(N^2) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L>\n    using unique = fold<L, list<>, quote_trait<detail::insert_back_>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::unique'\n        /// \\ingroup lazy_transformation\n        template <typename L>\n        using unique = defer<unique, L>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // partition\n    /// \\cond\n    namespace detail\n    {\n        template <typename Fn>\n        struct partition_\n        {\n#ifdef META_CONCEPT\n            template <typename, typename>\n#else\n            template <typename, typename, typename = void>\n#endif\n            struct impl\n            {\n            };\n            template <typename... Yes, typename... No, typename A>\n#ifdef META_CONCEPT\n            requires Integral<invoke<Fn, A>>\n            struct impl<pair<list<Yes...>, list<No...>>, A>\n#else\n            struct impl<pair<list<Yes...>, list<No...>>, A,\n                        void_<bool_<invoke<Fn, A>::type::value>>>\n#endif\n            {\n                using type = if_<invoke<Fn, A>, pair<list<Yes..., A>, list<No...>>,\n                                    pair<list<Yes...>, list<No..., A>>>;\n            };\n\n            template <typename State, typename A>\n            using invoke = _t<impl<State, A>>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Returns a pair of lists, where the elements of \\p L that satisfy the\n    /// Invocable \\p Fn such that `invoke<Fn,A>::%value` is \\c true are present in the\n    /// first list and the rest are in the second.\n    /// \\par Complexity\n    /// \\f$ O(N) \\f$.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using partition = fold<L, pair<list<>, list<>>, detail::partition_<Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::partition'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename Fn>\n        using partition = defer<partition, L, Fn>;\n    } // namespace lazy\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // sort\n    /// \\cond\n    namespace detail\n    {\n        template <META_TYPE_CONSTRAINT(Invocable) Fn, typename A, typename B, typename... Ts>\n        using part_ = partition<list<B, Ts...>, bind_back<Fn, A>>;\n#ifdef META_CONCEPT\n        template <List L, Invocable Fn>\n#else\n        template <typename, typename, typename = void>\n#endif\n        struct sort_\n        {\n        };\n        template <typename Fn>\n        struct sort_<list<>, Fn>\n        {\n            using type = list<>;\n        };\n\n        template <typename A, typename Fn>\n        struct sort_<list<A>, Fn>\n        {\n            using type = list<A>;\n        };\n\n        template <typename A, typename B, typename... Ts, typename Fn>\n#ifdef META_CONCEPT\n        requires Trait<sort_<first<part_<Fn, A, B, Ts...>>, Fn>> &&\n            Trait<sort_<second<part_<Fn, A, B, Ts...>>, Fn>>\n        struct sort_<list<A, B, Ts...>, Fn>\n#else\n        struct sort_<\n            list<A, B, Ts...>, Fn,\n            void_<_t<sort_<first<part_<Fn, A, B, Ts...>>, Fn>>>>\n#endif\n        {\n            using P = part_<Fn, A, B, Ts...>;\n            using type = concat<_t<sort_<first<P>, Fn>>, list<A>, _t<sort_<second<P>, Fn>>>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    // clang-format off\n    /// Return a new \\c meta::list that is sorted according to Invocable predicate \\p Fn.\n    /// \\par Complexity\n    /// Expected: \\f$ O(N log N) \\f$\n    /// Worst case: \\f$ O(N^2) \\f$.\n    /// \\code\n    /// using L0 = list<char[5], char[3], char[2], char[6], char[1], char[5], char[10]>;\n    /// using L1 = meta::sort<L0, lambda<_a, _b, lazy::less<lazy::sizeof_<_a>, lazy::sizeof_<_b>>>>;\n    /// static_assert(std::is_same<L1, list<char[1], char[2], char[3], char[5], char[5], char[6], char[10]>>::value, \"\");\n    /// \\endcode\n    /// \\ingroup transformation\n    // clang-format on\n    template <META_TYPE_CONSTRAINT(List) L, META_TYPE_CONSTRAINT(Invocable) Fn>\n    using sort = _t<detail::sort_<L, Fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::sort'\n        /// \\ingroup lazy_transformation\n        template <typename L, typename Fn>\n        using sort = defer<sort, L, Fn>;\n    } // namespace lazy\n\n    ////////////////////////////////////////////////////////////////////////////\n    // lambda_\n    /// \\cond\n    namespace detail\n    {\n        template <typename T, int = 0>\n        struct protect_;\n\n        template <typename, int = 0>\n        struct vararg_;\n\n        template <typename T, int = 0>\n        struct is_valid_;\n\n        // Returns which branch to evaluate\n        template <typename If, typename... Ts>\n#ifdef META_CONCEPT\n        using lazy_if_ = lazy::_t<defer<_if_, If, protect_<Ts>...>>;\n#else\n        using lazy_if_ = lazy::_t<defer<_if_, list<If, protect_<Ts>...>>>;\n#endif\n\n        template <typename A, typename T, typename Fn, typename Ts>\n        struct subst1_\n        {\n            using type = list<list<T>>;\n        };\n        template <typename T, typename Fn, typename Ts>\n        struct subst1_<Fn, T, Fn, Ts>\n        {\n            using type = list<>;\n        };\n        template <typename A, typename T, typename Fn, typename Ts>\n        struct subst1_<vararg_<A>, T, Fn, Ts>\n        {\n            using type = list<Ts>;\n        };\n\n        template <typename As, typename Ts>\n        using substitutions_ = push_back<\n            join<transform<\n                concat<As, repeat_n_c<size<Ts>{} + 2 - size<As>{}, back<As>>>,\n                concat<Ts, repeat_n_c<2, back<As>>>,\n                bind_back<quote_trait<subst1_>, back<As>, drop_c<Ts, size<As>{} - 2>>>>,\n            list<back<As>>>;\n\n#ifdef META_CONCEPT\n        template <List As, List Ts>\n        requires (_v<size<Ts>> + 2 >= _v<size<As>>)\n        using substitutions = substitutions_<As, Ts>;\n#else // ^^^ concepts / no concepts vvv\n        template <typename As, typename Ts>\n        using substitutions =\n#ifdef META_WORKAROUND_MSVC_702792\n            invoke<if_c<(size<Ts>::value + 2 >= size<As>::value), quote<substitutions_>>, As,\n                    Ts>;\n#else // ^^^ workaround ^^^ / vvv no workaround vvv\n            invoke<if_c<(size<Ts>{} + 2 >= size<As>{}), quote<substitutions_>>, As, Ts>;\n#endif // META_WORKAROUND_MSVC_702792\n#endif // META_CONCEPT\n\n        template <typename T>\n        struct is_vararg_ : std::false_type\n        {\n        };\n        template <typename T>\n        struct is_vararg_<vararg_<T>> : std::true_type\n        {\n        };\n\n        template <META_TYPE_CONSTRAINT(List) Tags>\n        using is_variadic_ = is_vararg_<at<push_front<Tags, void>, dec<size<Tags>>>>;\n\n        template <META_TYPE_CONSTRAINT(List) Tags, bool IsVariadic = is_variadic_<Tags>::value>\n        struct lambda_;\n\n        // Non-variadic lambda implementation\n        template <typename... As>\n        struct lambda_<list<As...>, false>\n        {\n        private:\n            static constexpr std::size_t arity = sizeof...(As) - 1;\n            using Tags = list<As...>; // Includes the lambda body as the last arg!\n            using Fn = back<Tags>;\n            template <typename T, META_TYPE_CONSTRAINT(List) Args>\n            struct impl;\n            template <typename T, META_TYPE_CONSTRAINT(List) Args>\n            using lazy_impl_ = lazy::_t<defer<impl, T, protect_<Args>>>;\n#ifdef META_CONCEPT\n            template <typename, List>\n#else\n            template <typename, typename, typename = void>\n#endif\n            struct subst_\n            {\n            };\n            template <template <typename...> class C, typename... Ts, typename Args>\n#ifdef META_CONCEPT\n            requires Valid<C, _t<impl<Ts, Args>>...> struct subst_<defer<C, Ts...>, Args>\n#else\n            struct subst_<defer<C, Ts...>, Args, void_<C<_t<impl<Ts, Args>>...>>>\n#endif\n            {\n                using type = C<_t<impl<Ts, Args>>...>;\n            };\n            template <typename T, template <T...> class C, T... Is, typename Args>\n#ifdef META_CONCEPT\n            requires Valid_I<T, C, Is...> struct subst_<defer_i<T, C, Is...>, Args>\n#else\n            struct subst_<defer_i<T, C, Is...>, Args, void_<C<Is...>>>\n#endif\n            {\n                using type = C<Is...>;\n            };\n            template <typename T, META_TYPE_CONSTRAINT(List) Args>\n            struct impl : if_c<(reverse_find_index<Tags, T>() != npos()),\n                                lazy::at<Args, reverse_find_index<Tags, T>>, id<T>>\n            {\n            };\n            template <typename T, typename Args>\n            struct impl<protect_<T>, Args>\n            {\n                using type = T;\n            };\n            template <typename T, typename Args>\n            struct impl<is_valid_<T>, Args>\n            {\n                using type = is_trait<impl<T, Args>>;\n            };\n            template <typename If, typename... Ts, typename Args>\n            struct impl<defer<if_, If, Ts...>, Args> // Short-circuit if_\n              : impl<lazy_impl_<lazy_if_<If, Ts...>, Args>, Args>\n            {\n            };\n            template <typename B, typename... Bs, typename Args>\n            struct impl<defer<and_, B, Bs...>, Args> // Short-circuit and_\n              : impl<lazy_impl_<lazy_if_<B, lazy::and_<Bs...>, protect_<std::false_type>>, Args>,\n                     Args>\n            {\n            };\n            template <typename B, typename... Bs, typename Args>\n            struct impl<defer<or_, B, Bs...>, Args> // Short-circuit or_\n              : impl<lazy_impl_<lazy_if_<B, protect_<std::true_type>, lazy::or_<Bs...>>, Args>,\n                     Args>\n            {\n            };\n            template <template <typename...> class C, typename... Ts, typename Args>\n            struct impl<defer<C, Ts...>, Args> : subst_<defer<C, Ts...>, Args>\n            {\n            };\n            template <typename T, template <T...> class C, T... Is, typename Args>\n            struct impl<defer_i<T, C, Is...>, Args> : subst_<defer_i<T, C, Is...>, Args>\n            {\n            };\n            template <template <typename...> class C, typename... Ts, typename Args>\n            struct impl<C<Ts...>, Args> : subst_<defer<C, Ts...>, Args>\n            {\n            };\n            template <typename... Ts, typename Args>\n            struct impl<lambda_<list<Ts...>, false>, Args>\n            {\n                using type = compose<uncurry<lambda_<list<As..., Ts...>, false>>,\n                                        curry<bind_front<quote<concat>, Args>>>;\n            };\n            template <typename... Bs, typename Args>\n            struct impl<lambda_<list<Bs...>, true>, Args>\n            {\n                using type = compose<typename lambda_<list<As..., Bs...>, true>::thunk,\n                                        bind_front<quote<concat>, transform<Args, quote<list>>>,\n                                        curry<bind_front<quote<substitutions>, list<Bs...>>>>;\n            };\n\n        public:\n            template <typename... Ts>\n#ifdef META_CONCEPT\n                requires (sizeof...(Ts) == arity) using invoke = _t<impl<Fn, list<Ts..., Fn>>>;\n#else\n            using invoke = _t<if_c<sizeof...(Ts) == arity, impl<Fn, list<Ts..., Fn>>>>;\n#endif\n        };\n\n        // Lambda with variadic placeholder (broken out due to less efficient compile-time\n        // resource usage)\n        template <typename... As>\n        struct lambda_<list<As...>, true>\n        {\n        private:\n            template <META_TYPE_CONSTRAINT(List), bool>\n            friend struct lambda_;\n            using Tags = list<As...>; // Includes the lambda body as the last arg!\n            template <typename T, META_TYPE_CONSTRAINT(List) Args>\n            struct impl;\n            template <META_TYPE_CONSTRAINT(List) Args>\n            using eval_impl_ = bind_back<quote_trait<impl>, Args>;\n            template <typename T, META_TYPE_CONSTRAINT(List) Args>\n            using lazy_impl_ = lazy::_t<defer<impl, T, protect_<Args>>>;\n            template <template <typename...> class C, META_TYPE_CONSTRAINT(List) Args,\n                        META_TYPE_CONSTRAINT(List) Ts>\n            using try_subst_ = apply<quote<C>, join<transform<Ts, eval_impl_<Args>>>>;\n#ifdef META_CONCEPT\n            template <typename, List>\n#else\n            template <typename, typename, typename = void>\n#endif\n            struct subst_\n            {\n            };\n            template <template <typename...> class C, typename... Ts, typename Args>\n#ifdef META_CONCEPT\n            requires True<try_subst_<C, Args, list<Ts...>>> struct subst_<defer<C, Ts...>, Args>\n#else\n            struct subst_<defer<C, Ts...>, Args, void_<try_subst_<C, Args, list<Ts...>>>>\n#endif\n            {\n                using type = list<try_subst_<C, Args, list<Ts...>>>;\n            };\n            template <typename T, template <T...> class C, T... Is, typename Args>\n#ifdef META_CONCEPT\n            requires Valid_I<T, C, Is...> struct subst_<defer_i<T, C, Is...>, Args>\n#else\n            struct subst_<defer_i<T, C, Is...>, Args, void_<C<Is...>>>\n#endif\n            {\n                using type = list<C<Is...>>;\n            };\n            template <typename T, META_TYPE_CONSTRAINT(List) Args>\n            struct impl : if_c<(reverse_find_index<Tags, T>() != npos()),\n                                lazy::at<Args, reverse_find_index<Tags, T>>, id<list<T>>>\n            {\n            };\n            template <typename T, typename Args>\n            struct impl<protect_<T>, Args>\n            {\n                using type = list<T>;\n            };\n            template <typename T, typename Args>\n            struct impl<is_valid_<T>, Args>\n            {\n                using type = list<is_trait<impl<T, Args>>>;\n            };\n            template <typename If, typename... Ts, typename Args>\n            struct impl<defer<if_, If, Ts...>, Args> // Short-circuit if_\n              : impl<lazy_impl_<lazy_if_<If, Ts...>, Args>, Args>\n            {\n            };\n            template <typename B, typename... Bs, typename Args>\n            struct impl<defer<and_, B, Bs...>, Args> // Short-circuit and_\n              : impl<lazy_impl_<lazy_if_<B, lazy::and_<Bs...>, protect_<std::false_type>>, Args>,\n                     Args>\n            {\n            };\n            template <typename B, typename... Bs, typename Args>\n            struct impl<defer<or_, B, Bs...>, Args> // Short-circuit or_\n              : impl<lazy_impl_<lazy_if_<B, protect_<std::true_type>, lazy::or_<Bs...>>, Args>,\n                     Args>\n            {\n            };\n            template <template <typename...> class C, typename... Ts, typename Args>\n            struct impl<defer<C, Ts...>, Args> : subst_<defer<C, Ts...>, Args>\n            {\n            };\n            template <typename T, template <T...> class C, T... Is, typename Args>\n            struct impl<defer_i<T, C, Is...>, Args> : subst_<defer_i<T, C, Is...>, Args>\n            {\n            };\n            template <template <typename...> class C, typename... Ts, typename Args>\n            struct impl<C<Ts...>, Args> : subst_<defer<C, Ts...>, Args>\n            {\n            };\n            template <typename... Bs, bool IsVar, typename Args>\n            struct impl<lambda_<list<Bs...>, IsVar>, Args>\n            {\n                using type =\n                    list<compose<typename lambda_<list<As..., Bs...>, true>::thunk,\n                                    bind_front<quote<concat>, Args>,\n                                    curry<bind_front<quote<substitutions>, list<Bs...>>>>>;\n            };\n            struct thunk\n            {\n                template <typename S, typename R = _t<impl<back<Tags>, S>>>\n#ifdef META_CONCEPT\n                    requires (_v<size<R>> == 1) using invoke = front<R>;\n#else\n                using invoke = if_c<size<R>{} == 1, front<R>>;\n#endif\n            };\n\n        public:\n            template <typename... Ts>\n            using invoke = invoke<thunk, substitutions<Tags, list<Ts...>>>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // lambda\n    /// For creating anonymous Invocables.\n    /// \\code\n    /// using L = lambda<_a, _b, std::pair<_b, std::pair<_a, _a>>>;\n    /// using P = invoke<L, int, short>;\n    /// static_assert(std::is_same<P, std::pair<short, std::pair<int, int>>>::value, \"\");\n    /// \\endcode\n    /// \\ingroup trait\n    template <typename... Ts>\n#ifdef META_CONCEPT\n        requires (sizeof...(Ts) > 0) using lambda = detail::lambda_<list<Ts...>>;\n#else\n    using lambda = if_c<(sizeof...(Ts) > 0), detail::lambda_<list<Ts...>>>;\n#endif\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // is_valid\n    /// For testing whether a deferred computation will succeed in a \\c let or a \\c lambda.\n    /// \\ingroup trait\n    template <typename T>\n    using is_valid = detail::is_valid_<T>;\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // vararg\n    /// For defining variadic placeholders.\n    template <typename T>\n    using vararg = detail::vararg_<T>;\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // protect\n    /// For preventing the evaluation of a nested `defer`ed computation in a \\c let or\n    /// \\c lambda expression.\n    template <typename T>\n    using protect = detail::protect_<T>;\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // var\n    /// For use when defining local variables in \\c meta::let expressions\n    /// \\sa `meta::let`\n    template <typename Tag, typename Value>\n    struct var;\n\n    /// \\cond\n    namespace detail\n    {\n        template <typename...>\n        struct let_\n        {\n        };\n        template <typename Fn>\n        struct let_<Fn>\n        {\n            using type = lazy::invoke<lambda<Fn>>;\n        };\n        template <typename Tag, typename Value, typename... Rest>\n        struct let_<var<Tag, Value>, Rest...>\n        {\n            using type = lazy::invoke<lambda<Tag, _t<let_<Rest...>>>, Value>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// A lexically scoped expression with local variables.\n    ///\n    /// \\code\n    /// template <typename T, typename L>\n    /// using find_index_ = let<\n    ///     var<_a, L>,\n    ///     var<_b, lazy::find<_a, T>>,\n    ///     lazy::if_<\n    ///         std::is_same<_b, list<>>,\n    ///         meta::npos,\n    ///         lazy::minus<lazy::size<_a>, lazy::size<_b>>>>;\n    /// static_assert(find_index_<int, list<short, int, float>>{} == 1, \"\");\n    /// static_assert(find_index_<double, list<short, int, float>>{} == meta::npos{}, \"\");\n    /// \\endcode\n    /// \\ingroup trait\n    template <typename... As>\n    using let = _t<_t<detail::let_<As...>>>;\n\n    namespace lazy\n    {\n        /// \\sa `meta::let`\n        /// \\ingroup lazy_trait\n        template <typename... As>\n        using let = defer<let, As...>;\n    } // namespace lazy\n\n    // Some argument placeholders for use in \\c lambda expressions.\n    /// \\ingroup trait\n    inline namespace placeholders\n    {\n        // regular placeholders:\n        struct _a;\n        struct _b;\n        struct _c;\n        struct _d;\n        struct _e;\n        struct _f;\n        struct _g;\n        struct _h;\n        struct _i;\n\n        // variadic placeholders:\n        using _args = vararg<void>;\n        using _args_a = vararg<_a>;\n        using _args_b = vararg<_b>;\n        using _args_c = vararg<_c>;\n    } // namespace placeholders\n\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // cartesian_product\n    /// \\cond\n    namespace detail\n    {\n        template <typename M2, typename M>\n        struct cartesian_product_fn\n        {\n            template <typename X>\n            struct lambda0\n            {\n                template <typename Xs>\n                using lambda1 = list<push_front<Xs, X>>;\n                using type = join<transform<M2, quote<lambda1>>>;\n            };\n            using type = join<transform<M, quote_trait<lambda0>>>;\n        };\n    } // namespace detail\n    /// \\endcond\n\n    /// Given a list of lists \\p ListOfLists, return a new list of lists that is the Cartesian\n    /// Product. Like the `sequence` function from the Haskell Prelude.\n    /// \\par Complexity\n    /// \\f$ O(N \\times M) \\f$, where \\f$ N \\f$ is the size of the outer list, and\n    /// \\f$ M \\f$ is the size of the inner lists.\n    /// \\ingroup transformation\n    template <META_TYPE_CONSTRAINT(List) ListOfLists>\n    using cartesian_product =\n        reverse_fold<ListOfLists, list<list<>>, quote_trait<detail::cartesian_product_fn>>;\n\n    namespace lazy\n    {\n        /// \\sa 'meta::cartesian_product'\n        /// \\ingroup lazy_transformation\n        template <typename ListOfLists>\n        using cartesian_product = defer<cartesian_product, ListOfLists>;\n    } // namespace lazy\n\n    /// \\cond\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // add_const_if\n    namespace detail\n    {\n        template <bool>\n        struct add_const_if\n        {\n            template <typename T>\n            using invoke = T const;\n        };\n        template <>\n        struct add_const_if<false>\n        {\n            template <typename T>\n            using invoke = T;\n        };\n    } // namespace detail\n    template <bool If>\n    using add_const_if_c = detail::add_const_if<If>;\n    template <META_TYPE_CONSTRAINT(Integral) If>\n    using add_const_if = add_const_if_c<If::type::value>;\n    /// \\endcond\n\n    /// \\cond\n    ///////////////////////////////////////////////////////////////////////////////////////////\n    // const_if\n    template <bool If, typename T>\n    using const_if_c = invoke<add_const_if_c<If>, T>;\n    template <typename If, typename T>\n    using const_if = invoke<add_const_if<If>, T>;\n    /// \\endcond\n\n    /// \\cond\n    namespace detail\n    {\n        template <typename State, typename Ch>\n        using atoi_ = if_c<(Ch::value >= '0' && Ch::value <= '9'),\n                            std::integral_constant<typename State::value_type,\n                                                    State::value * 10 + (Ch::value - '0')>>;\n    }\n    /// \\endcond\n\n    inline namespace literals\n    {\n        /// A user-defined literal that generates objects of type \\c meta::size_t.\n        /// \\ingroup integral\n        template <char... Chs>\n        constexpr fold<list<char_<Chs>...>, meta::size_t<0>, quote<detail::atoi_>>\n            operator\"\" _z()\n        {\n            return {};\n        }\n    } // namespace literals\n} // namespace meta\n\n/// \\cond\n#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 1101\n\n_LIBCPP_BEGIN_NAMESPACE_STD\ntemplate <class>\nclass _LIBCPP_TYPE_VIS_ONLY allocator;\ntemplate <class, class>\nstruct _LIBCPP_TYPE_VIS_ONLY pair;\ntemplate <class>\nstruct _LIBCPP_TYPE_VIS_ONLY hash;\ntemplate <class>\nstruct _LIBCPP_TYPE_VIS_ONLY less;\ntemplate <class>\nstruct _LIBCPP_TYPE_VIS_ONLY equal_to;\ntemplate <class>\nstruct _LIBCPP_TYPE_VIS_ONLY char_traits;\ntemplate <class, class>\nclass _LIBCPP_TYPE_VIS_ONLY list;\ntemplate <class, class>\nclass _LIBCPP_TYPE_VIS_ONLY forward_list;\ntemplate <class, class>\nclass _LIBCPP_TYPE_VIS_ONLY vector;\ntemplate <class, class>\nclass _LIBCPP_TYPE_VIS_ONLY deque;\ntemplate <class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY basic_string;\ntemplate <class, class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY map;\ntemplate <class, class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY multimap;\ntemplate <class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY set;\ntemplate <class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY multiset;\ntemplate <class, class, class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY unordered_map;\ntemplate <class, class, class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY unordered_multimap;\ntemplate <class, class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY unordered_set;\ntemplate <class, class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY unordered_multiset;\ntemplate <class, class>\nclass _LIBCPP_TYPE_VIS_ONLY queue;\ntemplate <class, class, class>\nclass _LIBCPP_TYPE_VIS_ONLY priority_queue;\ntemplate <class, class>\nclass _LIBCPP_TYPE_VIS_ONLY stack;\n_LIBCPP_END_NAMESPACE_STD\n\nnamespace meta\n{\n    namespace detail\n    {\n        template <typename T, typename A = std::allocator<T>>\n        using std_list = std::list<T, A>;\n        template <typename T, typename A = std::allocator<T>>\n        using std_forward_list = std::forward_list<T, A>;\n        template <typename T, typename A = std::allocator<T>>\n        using std_vector = std::vector<T, A>;\n        template <typename T, typename A = std::allocator<T>>\n        using std_deque = std::deque<T, A>;\n        template <typename T, typename C = std::char_traits<T>, typename A = std::allocator<T>>\n        using std_basic_string = std::basic_string<T, C, A>;\n        template <typename K, typename V, typename C = std::less<K>,\n                    typename A = std::allocator<std::pair<K const, V>>>\n        using std_map = std::map<K, V, C, A>;\n        template <typename K, typename V, typename C = std::less<K>,\n                    typename A = std::allocator<std::pair<K const, V>>>\n        using std_multimap = std::multimap<K, V, C, A>;\n        template <typename K, typename C = std::less<K>, typename A = std::allocator<K>>\n        using std_set = std::set<K, C, A>;\n        template <typename K, typename C = std::less<K>, typename A = std::allocator<K>>\n        using std_multiset = std::multiset<K, C, A>;\n        template <typename K, typename V, typename H = std::hash<K>,\n                    typename C = std::equal_to<K>,\n                    typename A = std::allocator<std::pair<K const, V>>>\n        using std_unordered_map = std::unordered_map<K, V, H, C, A>;\n        template <typename K, typename V, typename H = std::hash<K>,\n                    typename C = std::equal_to<K>,\n                    typename A = std::allocator<std::pair<K const, V>>>\n        using std_unordered_multimap = std::unordered_multimap<K, V, H, C, A>;\n        template <typename K, typename H = std::hash<K>, typename C = std::equal_to<K>,\n                    typename A = std::allocator<K>>\n        using std_unordered_set = std::unordered_set<K, H, C, A>;\n        template <typename K, typename H = std::hash<K>, typename C = std::equal_to<K>,\n                    typename A = std::allocator<K>>\n        using std_unordered_multiset = std::unordered_multiset<K, H, C, A>;\n        template <typename T, typename C = std_deque<T>>\n        using std_queue = std::queue<T, C>;\n        template <typename T, typename C = std_vector<T>,\n                    class D = std::less<typename C::value_type>>\n        using std_priority_queue = std::priority_queue<T, C, D>;\n        template <typename T, typename C = std_deque<T>>\n        using std_stack = std::stack<T, C>;\n    } // namespace detail\n\n    template <>\n    struct quote<::std::list> : quote<detail::std_list>\n    {\n    };\n    template <>\n    struct quote<::std::deque> : quote<detail::std_deque>\n    {\n    };\n    template <>\n    struct quote<::std::forward_list> : quote<detail::std_forward_list>\n    {\n    };\n    template <>\n    struct quote<::std::vector> : quote<detail::std_vector>\n    {\n    };\n    template <>\n    struct quote<::std::basic_string> : quote<detail::std_basic_string>\n    {\n    };\n    template <>\n    struct quote<::std::map> : quote<detail::std_map>\n    {\n    };\n    template <>\n    struct quote<::std::multimap> : quote<detail::std_multimap>\n    {\n    };\n    template <>\n    struct quote<::std::set> : quote<detail::std_set>\n    {\n    };\n    template <>\n    struct quote<::std::multiset> : quote<detail::std_multiset>\n    {\n    };\n    template <>\n    struct quote<::std::unordered_map> : quote<detail::std_unordered_map>\n    {\n    };\n    template <>\n    struct quote<::std::unordered_multimap> : quote<detail::std_unordered_multimap>\n    {\n    };\n    template <>\n    struct quote<::std::unordered_set> : quote<detail::std_unordered_set>\n    {\n    };\n    template <>\n    struct quote<::std::unordered_multiset> : quote<detail::std_unordered_multiset>\n    {\n    };\n    template <>\n    struct quote<::std::queue> : quote<detail::std_queue>\n    {\n    };\n    template <>\n    struct quote<::std::priority_queue> : quote<detail::std_priority_queue>\n    {\n    };\n    template <>\n    struct quote<::std::stack> : quote<detail::std_stack>\n    {\n    };\n} // namespace meta\n\n#endif\n/// \\endcond\n\n#ifdef __clang__\n#pragma GCC diagnostic pop\n#endif\n#endif\n"
  },
  {
    "path": "include/meta/meta_fwd.hpp",
    "content": "/// \\file meta_fwd.hpp Forward declarations\n//\n// Meta library\n//\n//  Copyright Eric Niebler 2014-present\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/meta\n//\n\n#ifndef META_FWD_HPP\n#define META_FWD_HPP\n\n#include <type_traits>\n#include <utility>\n\n#ifdef __clang__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wmissing-variable-declarations\"\n#endif\n\n#define META_CXX_STD_14 201402L\n#define META_CXX_STD_17 201703L\n\n#if defined(_MSVC_LANG) && _MSVC_LANG > __cplusplus // Older clangs define _MSVC_LANG < __cplusplus\n#define META_CXX_VER _MSVC_LANG\n#else\n#define META_CXX_VER __cplusplus\n#endif\n\n#if defined(__apple_build_version__) || defined(__clang__)\n#if defined(__apple_build_version__) || (defined(__clang__) && __clang_major__ < 6)\n#define META_WORKAROUND_LLVM_28385 // https://llvm.org/bugs/show_bug.cgi?id=28385\n#endif\n\n#elif defined(_MSC_VER)\n#define META_HAS_MAKE_INTEGER_SEQ 1\n#if _MSC_VER < 1921\n#define META_WORKAROUND_MSVC_756112 // fold expression + alias templates in template argument (Fixed in next VS2019 toolset update)\n#if _MSC_VER < 1920\n#define META_WORKAROUND_MSVC_702792 // Fixed in VS2019 Preview 2\n#define META_WORKAROUND_MSVC_703656 // Fixed in VS2019 Preview 2\n#endif // _MSC_VER < 1920\n#endif // _MSC_VER < 1921\n\n#elif defined(__GNUC__)\n#define META_WORKAROUND_GCC_86356 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356\n#if __GNUC__ >= 8\n#define META_HAS_INTEGER_PACK 1\n#else\n#define META_WORKAROUND_GCC_UNKNOWN1 // Older GCCs don't like fold + debug + -march=native\n#endif\n#if __GNUC__ == 5 && __GNUC_MINOR__ == 1\n#define META_WORKAROUND_GCC_66405 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66405\n#endif\n#if __GNUC__ < 5\n#define META_WORKAROUND_CWG_1558 // https://wg21.link/cwg1558\n#endif\n#endif\n\n#ifndef META_CXX_VARIABLE_TEMPLATES\n#ifdef __cpp_variable_templates\n#define META_CXX_VARIABLE_TEMPLATES __cpp_variable_templates\n#else\n#define META_CXX_VARIABLE_TEMPLATES (META_CXX_VER >= META_CXX_STD_14)\n#endif\n#endif\n\n#ifndef META_CXX_INLINE_VARIABLES\n#ifdef __cpp_inline_variables\n#define META_CXX_INLINE_VARIABLES __cpp_inline_variables\n#else\n#define META_CXX_INLINE_VARIABLES (META_CXX_VER >= META_CXX_STD_17)\n#endif\n#endif\n\n#ifndef META_INLINE_VAR\n#if META_CXX_INLINE_VARIABLES\n#define META_INLINE_VAR inline\n#else\n#define META_INLINE_VAR\n#endif\n#endif\n\n#ifndef META_CXX_INTEGER_SEQUENCE\n#ifdef __cpp_lib_integer_sequence\n#define META_CXX_INTEGER_SEQUENCE __cpp_lib_integer_sequence\n#else\n#define META_CXX_INTEGER_SEQUENCE (META_CXX_VER >= META_CXX_STD_14)\n#endif\n#endif\n\n#ifndef META_HAS_MAKE_INTEGER_SEQ\n#ifdef __has_builtin\n#if __has_builtin(__make_integer_seq)\n#define META_HAS_MAKE_INTEGER_SEQ 1\n#endif\n#endif\n#endif\n#ifndef META_HAS_MAKE_INTEGER_SEQ\n#define META_HAS_MAKE_INTEGER_SEQ 0\n#endif\n\n#ifndef META_HAS_INTEGER_PACK\n#define META_HAS_INTEGER_PACK 0\n#endif\n\n#ifndef META_HAS_TYPE_PACK_ELEMENT\n#ifdef __has_builtin\n#if __has_builtin(__type_pack_element)\n#define META_HAS_TYPE_PACK_ELEMENT 1\n#endif\n#endif\n#endif\n#ifndef META_HAS_TYPE_PACK_ELEMENT\n#define META_HAS_TYPE_PACK_ELEMENT 0\n#endif\n\n#if !defined(META_DEPRECATED) && !defined(META_DISABLE_DEPRECATED_WARNINGS)\n#if defined(__cpp_attribute_deprecated) || META_CXX_VER >= META_CXX_STD_14\n#define META_DEPRECATED(...) [[deprecated(__VA_ARGS__)]]\n#elif defined(__clang__) || defined(__GNUC__)\n#define META_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__)))\n#endif\n#endif\n#ifndef META_DEPRECATED\n#define META_DEPRECATED(...)\n#endif\n\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64970\n#if(defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)\n#define META_WORKAROUND_GCC_64970\n#endif\n\n#ifndef META_CXX_FOLD_EXPRESSIONS\n#ifdef __cpp_fold_expressions\n#define META_CXX_FOLD_EXPRESSIONS __cpp_fold_expressions\n#else\n#define META_CXX_FOLD_EXPRESSIONS (META_CXX_VER >= META_CXX_STD_17)\n#endif\n#endif\n\n#if META_CXX_FOLD_EXPRESSIONS\n#if !META_CXX_VARIABLE_TEMPLATES\n#error Fold expressions, but no variable templates?\n#endif\n#endif\n\n#if defined(__cpp_concepts) && __cpp_concepts > 0\n#if !META_CXX_VARIABLE_TEMPLATES\n#error Concepts, but no variable templates?\n#endif\n#if __cpp_concepts <= 201507L\n#define META_CONCEPT concept bool\n// TS concepts subsumption barrier for atomic expressions\n#define META_CONCEPT_BARRIER(...) ::meta::detail::barrier<__VA_ARGS__>\n#else\n#define META_CONCEPT concept\n#define META_CONCEPT_BARRIER(...) __VA_ARGS__\n#if __cpp_concepts >= 201811L\n#define META_HAS_P1084\n#endif\n#endif\n#define META_TYPE_CONSTRAINT(...) __VA_ARGS__\n#else\n#define META_TYPE_CONSTRAINT(...) typename\n#endif\n\nnamespace meta\n{\n#if META_CXX_INTEGER_SEQUENCE\n    using std::integer_sequence;\n#else\n    template <typename T, T...>\n    struct integer_sequence;\n#endif\n\n    template <typename... Ts>\n    struct list;\n\n    template <typename T>\n    struct id;\n\n    template <template <typename...> class>\n    struct quote;\n\n    template <typename T, template <T...> class F>\n    struct quote_i;\n\n    template <template <typename...> class C, typename... Ts>\n    struct defer;\n\n    template <typename T, template <T...> class C, T... Is>\n    struct defer_i;\n\n#if META_CXX_VARIABLE_TEMPLATES || defined(META_DOXYGEN_INVOKED)\n    /// is_v\n    /// Test whether a type \\p T is an instantiation of class\n    /// template \\p C.\n    /// \\ingroup trait\n    template <typename, template <typename...> class>\n    META_INLINE_VAR constexpr bool is_v = false;\n    template <typename... Ts, template <typename...> class C>\n    META_INLINE_VAR constexpr bool is_v<C<Ts...>, C> = true;\n#endif\n\n#ifdef META_CONCEPT\n    namespace detail\n    {\n        template <bool B>\n        META_INLINE_VAR constexpr bool barrier = B;\n\n        template <auto> struct require_constant; // not defined\n    }\n\n    template <typename...>\n    META_CONCEPT True = META_CONCEPT_BARRIER(true);\n\n    template <typename T, typename U>\n    META_CONCEPT Same =\n#if defined(__clang__)\n        META_CONCEPT_BARRIER(__is_same(T, U));\n#elif defined(__GNUC__) && __GNUC__ >= 6\n        META_CONCEPT_BARRIER(__is_same_as(T, U));\n#else\n        META_CONCEPT_BARRIER(std::is_same_v<T, U>);\n#endif\n\n    template <template <typename...> class C, typename... Ts>\n    META_CONCEPT Valid = requires\n    {\n        typename C<Ts...>;\n    };\n\n    template <typename T, template <T...> class C, T... Is>\n    META_CONCEPT Valid_I = requires\n    {\n        typename C<Is...>;\n    };\n\n    template <typename T>\n    META_CONCEPT Trait = requires\n    {\n        typename T::type;\n    };\n\n    template <typename T>\n    META_CONCEPT Invocable = requires\n    {\n        typename quote<T::template invoke>;\n    };\n\n    template <typename T>\n    META_CONCEPT List = is_v<T, list>;\n\n    // clang-format off\n    template <typename T>\n    META_CONCEPT Integral = requires\n    {\n        typename T::type;\n        typename T::value_type;\n        typename T::type::value_type;\n    }\n    && Same<typename T::value_type, typename T::type::value_type>\n    && std::is_integral_v<typename T::value_type>\n    && requires\n    {\n#ifdef META_HAS_P1084\n        { T::value } -> Same<const typename T::value_type&>;\n#else\n        T::value;\n        requires Same<decltype(T::value), const typename T::value_type>;\n#endif\n        typename detail::require_constant<T::value>;\n\n#ifdef META_HAS_P1084\n        { T::type::value } -> Same<const typename T::value_type&>;\n#else\n        T::type::value;\n        requires Same<decltype(T::type::value), const typename T::value_type>;\n#endif\n        typename detail::require_constant<T::type::value>;\n        requires T::value == T::type::value;\n\n#ifdef META_HAS_P1084\n        { T{}() } -> Same<typename T::value_type>;\n#else\n        T{}();\n        requires Same<decltype(T{}()), typename T::value_type>;\n#endif\n        typename detail::require_constant<T{}()>;\n        requires T{}() == T::value;\n\n        requires std::is_convertible_v<T, typename T::value_type>;\n    };\n    // clang-format on\n#endif // META_CONCEPT\n\n    namespace extension\n    {\n        template <META_TYPE_CONSTRAINT(Invocable) F, typename L>\n        struct apply;\n    }\n} // namespace meta\n\n#ifdef __clang__\n#pragma GCC diagnostic pop\n#endif\n\n#endif\n"
  },
  {
    "path": "include/stl2/algorithm.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_ALGORITHM_HPP\n#define STL2_ALGORITHM_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n\n#include <stl2/detail/algorithm/adjacent_find.hpp>\n#include <stl2/detail/algorithm/all_of.hpp>\n#include <stl2/detail/algorithm/any_of.hpp>\n#include <stl2/detail/algorithm/binary_search.hpp>\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/copy_backward.hpp>\n#include <stl2/detail/algorithm/copy_if.hpp>\n#include <stl2/detail/algorithm/copy_n.hpp>\n#include <stl2/detail/algorithm/count.hpp>\n#include <stl2/detail/algorithm/count_if.hpp>\n#include <stl2/detail/algorithm/equal.hpp>\n#include <stl2/detail/algorithm/equal_range.hpp>\n#include <stl2/detail/algorithm/fill.hpp>\n#include <stl2/detail/algorithm/fill_n.hpp>\n#include <stl2/detail/algorithm/find.hpp>\n#include <stl2/detail/algorithm/find_end.hpp>\n#include <stl2/detail/algorithm/find_first_of.hpp>\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/algorithm/find_if_not.hpp>\n#include <stl2/detail/algorithm/for_each.hpp>\n#include <stl2/detail/algorithm/generate.hpp>\n#include <stl2/detail/algorithm/generate_n.hpp>\n#include <stl2/detail/algorithm/includes.hpp>\n#include <stl2/detail/algorithm/inplace_merge.hpp>\n#include <stl2/detail/algorithm/is_heap.hpp>\n#include <stl2/detail/algorithm/is_heap_until.hpp>\n#include <stl2/detail/algorithm/is_partitioned.hpp>\n#include <stl2/detail/algorithm/is_permutation.hpp>\n#include <stl2/detail/algorithm/is_sorted.hpp>\n#include <stl2/detail/algorithm/is_sorted_until.hpp>\n#include <stl2/detail/algorithm/lexicographical_compare.hpp>\n#include <stl2/detail/algorithm/lower_bound.hpp>\n#include <stl2/detail/algorithm/make_heap.hpp>\n#include <stl2/detail/algorithm/max.hpp>\n#include <stl2/detail/algorithm/max_element.hpp>\n#include <stl2/detail/algorithm/merge.hpp>\n#include <stl2/detail/algorithm/min.hpp>\n#include <stl2/detail/algorithm/min_element.hpp>\n#include <stl2/detail/algorithm/minmax.hpp>\n#include <stl2/detail/algorithm/minmax_element.hpp>\n#include <stl2/detail/algorithm/mismatch.hpp>\n#include <stl2/detail/algorithm/move.hpp>\n#include <stl2/detail/algorithm/move_backward.hpp>\n#include <stl2/detail/algorithm/next_permutation.hpp>\n#include <stl2/detail/algorithm/none_of.hpp>\n#include <stl2/detail/algorithm/nth_element.hpp>\n#include <stl2/detail/algorithm/partial_sort.hpp>\n#include <stl2/detail/algorithm/partial_sort_copy.hpp>\n#include <stl2/detail/algorithm/partition.hpp>\n#include <stl2/detail/algorithm/partition_copy.hpp>\n#include <stl2/detail/algorithm/partition_point.hpp>\n#include <stl2/detail/algorithm/pop_heap.hpp>\n#include <stl2/detail/algorithm/prev_permutation.hpp>\n#include <stl2/detail/algorithm/push_heap.hpp>\n#include <stl2/detail/algorithm/remove.hpp>\n#include <stl2/detail/algorithm/remove_copy.hpp>\n#include <stl2/detail/algorithm/remove_copy_if.hpp>\n#include <stl2/detail/algorithm/remove_if.hpp>\n#include <stl2/detail/algorithm/replace.hpp>\n#include <stl2/detail/algorithm/replace_copy.hpp>\n#include <stl2/detail/algorithm/replace_copy_if.hpp>\n#include <stl2/detail/algorithm/replace_if.hpp>\n#include <stl2/detail/algorithm/reverse.hpp>\n#include <stl2/detail/algorithm/reverse_copy.hpp>\n#include <stl2/detail/algorithm/rotate.hpp>\n#include <stl2/detail/algorithm/rotate_copy.hpp>\n#include <stl2/detail/algorithm/search.hpp>\n#include <stl2/detail/algorithm/search_n.hpp>\n#include <stl2/detail/algorithm/set_difference.hpp>\n#include <stl2/detail/algorithm/set_intersection.hpp>\n#include <stl2/detail/algorithm/set_symmetric_difference.hpp>\n#include <stl2/detail/algorithm/set_union.hpp>\n#include <stl2/detail/algorithm/shuffle.hpp>\n#include <stl2/detail/algorithm/sort.hpp>\n#include <stl2/detail/algorithm/sort_heap.hpp>\n#include <stl2/detail/algorithm/stable_partition.hpp>\n#include <stl2/detail/algorithm/stable_sort.hpp>\n#include <stl2/detail/algorithm/swap_ranges.hpp>\n#include <stl2/detail/algorithm/transform.hpp>\n#include <stl2/detail/algorithm/unique.hpp>\n#include <stl2/detail/algorithm/unique_copy.hpp>\n#include <stl2/detail/algorithm/upper_bound.hpp>\n\n#endif\n"
  },
  {
    "path": "include/stl2/concepts.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_CONCEPTS_HPP\n#define STL2_CONCEPTS_HPP\n\n#include <stl2/detail/swap.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/function.hpp>\n#include <stl2/detail/concepts/fundamental.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/concepts/urng.hpp>\n#include <stl2/detail/iostream/concepts.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/adjacent_find.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_ADJACENT_FIND_HPP\n#define STL2_DETAIL_ALGORITHM_ADJACENT_FIND_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// adjacent_find [alg.adjacent.find]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __adjacent_find_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_relation<projected<I, Proj>> Pred = equal_to>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Pred pred = {}, Proj proj = {}) const {\n\t\t\tif (first == last) {\n\t\t\t\treturn first;\n\t\t\t}\n\n\t\t\tauto next = first;\n\t\t\tfor (; ++next != last; first = next) {\n\t\t\t\tif (__stl2::invoke(pred,\n\t\t\t\t\t\t__stl2::invoke(proj, *first),\n\t\t\t\t\t\t__stl2::invoke(proj, *next))) {\n\t\t\t\t\treturn first;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn next;\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_relation<projected<iterator_t<R>, Proj>> Pred = equal_to>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Pred pred = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __adjacent_find_fn adjacent_find{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/all_of.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n// Algorithm adapted (stolen) from Range v3 library\n//\n//  Copyright Andrew Sutton 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_ALL_OF_HPP\n#define STL2_DETAIL_ALGORITHM_ALL_OF_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n////////////////////////////////////////////////////////////////////////////////\n// all_of [alg.all_of]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __all_of_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr bool operator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (!bool(__stl2::invoke(pred, __stl2::invoke(proj, *first)))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\tconstexpr bool operator()(R&& rng, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(rng), end(rng), __stl2::ref(pred), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __all_of_fn all_of{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/any_of.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Andrew Sutton 2014\n//  Copyright Gonzalo Brito Gadeschi 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_ANY_OF_HPP\n#define STL2_DETAIL_ALGORITHM_ANY_OF_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n////////////////////////////////////////////////////////////////////////////////\n// any_of [alg.any_of]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __any_of_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr bool operator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *first))) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\tconstexpr bool operator()(R&& rng, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(rng), end(rng), __stl2::ref(pred), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __any_of_fn any_of{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/binary_search.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_BINARY_SEARCH_HPP\n#define STL2_DETAIL_ALGORITHM_BINARY_SEARCH_HPP\n\n#include <stl2/detail/algorithm/lower_bound.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// binary_search [binary.search]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __binary_search_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<const T*, projected<I, Proj>> Comp = less>\n\t\tconstexpr bool operator()(I first, S last, const T& value,\n\t\t\tComp comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\tauto result = lower_bound(std::move(first), last, value,\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn bool(result != last) &&\n\t\t\t\t!bool(__stl2::invoke(comp, value, __stl2::invoke(proj, *result)));\n\t\t}\n\n\t\ttemplate<forward_range R, class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<const T*,\n\t\t\t\tprojected<iterator_t<R>, Proj>> Comp = less>\n\t\tconstexpr bool operator()(R&& r, const T& value, Comp comp = {},\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r), end(r), value, static_cast<Comp&&>(comp),\n\t\t\t\tstatic_cast<Proj&&>(proj));\n\t\t}\n\t};\n\n\tinline constexpr __binary_search_fn binary_search{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_COPY_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// copy [alg.copy]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing copy_result = __in_out_result<I, O>;\n\n\tstruct __copy_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O>\n\t\trequires indirectly_copyable<I, O>\n\t\tconstexpr copy_result<I, O>\n\t\toperator()(I first, S last, O result) const {\n\t\t\tfor (; first != last; (void) ++first, (void) ++result) {\n\t\t\t\t*result = *first;\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O>\n\t\trequires indirectly_copyable<iterator_t<R>, O>\n\t\tconstexpr copy_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(result));\n\t\t}\n\t};\n\n\tinline constexpr __copy_fn copy{};\n\n\tnamespace ext {\n\t\tstruct __copy_fn : private __niebloid {\n\t\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O>\n\t\t\trequires indirectly_copyable<I, O>\n\t\t\tconstexpr copy_result<I, O>\n\t\t\toperator()(I first, S last, O result) const {\n\t\t\t\tfor (; first != last; (void) ++first, (void) ++result) {\n\t\t\t\t\t*result = *first;\n\t\t\t\t}\n\t\t\t\treturn {std::move(first), std::move(result)};\n\t\t\t}\n\n\t\t\ttemplate<input_range R, class O>\n\t\t\trequires (!range<O> && weakly_incrementable<__f<O>>\n\t\t\t\t&& indirectly_copyable<iterator_t<R>, __f<O>>)\n\t\t\tconstexpr copy_result<safe_iterator_t<R>, __f<O>>\n\t\t\toperator()(R&& r, O&& result_) const {\n\t\t\t\tauto result = std::forward<O>(result_);\n\t\t\t\treturn (*this)(begin(r), end(r), std::move(result));\n\t\t\t}\n\n\t\t\t// Extension\n\t\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_or_output_iterator I2, sentinel_for<I2> S2>\n\t\t\trequires indirectly_copyable<I1, I2>\n\t\t\tconstexpr copy_result<I1, I2>\n\t\t\toperator()(I1 first, S1 last, I2 rfirst, S2 rlast) const {\n\t\t\t\tfor (; first != last && rfirst != rlast; (void) ++first, (void)++rfirst) {\n\t\t\t\t\t*rfirst = *first;\n\t\t\t\t}\n\t\t\t\treturn {std::move(first), std::move(rfirst)};\n\t\t\t}\n\n\t\t\t// Extension\n\t\t\ttemplate<input_range R1, range R2>\n\t\t\trequires indirectly_copyable<iterator_t<R1>, iterator_t<R2>>\n\t\t\tconstexpr copy_result<safe_iterator_t<R1>, safe_iterator_t<R2>>\n\t\t\toperator()(R1&& r1, R2&& r2) const {\n\t\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2));\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __copy_fn copy{};\n\t} // namespace ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/copy_backward.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2013-2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_COPY_BACKWARD_HPP\n#define STL2_DETAIL_ALGORITHM_COPY_BACKWARD_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// copy_backward [alg.copy]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing copy_backward_result = __in_out_result<I, O>;\n\n\tstruct __copy_backward_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2>\n\t\trequires indirectly_copyable<I1, I2>\n\t\tconstexpr copy_backward_result<I1, I2>\n\t\toperator()(I1 first, S1 sent, I2 out) const {\n\t\t\tauto last = next(first, static_cast<S1&&>(sent));\n\t\t\tauto i = last;\n\t\t\twhile (i != first) {\n\t\t\t\t*--out = *--i;\n\t\t\t}\n\t\t\treturn {static_cast<I1&&>(last), static_cast<I2&&>(out)};\n\t\t}\n\n\t\ttemplate<bidirectional_range R, bidirectional_iterator I>\n\t\tconstexpr copy_backward_result<safe_iterator_t<R>, I>\n\t\toperator()(R&& r, I result) const {\n\t\t\treturn (*this)(begin(r), end(r), static_cast<I&&>(result));\n\t\t}\n\t};\n\n\tinline constexpr __copy_backward_fn copy_backward{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/copy_if.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_COPY_IF_HPP\n#define STL2_DETAIL_ALGORITHM_COPY_IF_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// copy_if [alg.copy]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing copy_if_result = __in_out_result<I, O>;\n\n\tstruct __copy_if_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O,\n\t\t\tclass Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>\n\t\trequires indirectly_copyable<I, O>\n\t\tconstexpr copy_if_result<I, O>\n\t\toperator()(I first, S last, O result, Pred pred, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, v))) {\n\t\t\t\t\t*result = static_cast<iter_reference_t<I>&&>(v);\n\t\t\t\t\t++result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {static_cast<I&&>(first), static_cast<O&&>(result)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\trequires indirectly_copyable<iterator_t<R>, O>\n\t\tconstexpr copy_if_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), static_cast<O&&>(result),\n\t\t\t\tstatic_cast<Pred&&>(pred), static_cast<Proj&&>(proj));\n\t\t}\n\t};\n\n\tinline constexpr __copy_if_fn copy_if{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/copy_n.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_COPY_N_HPP\n#define STL2_DETAIL_ALGORITHM_COPY_N_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// copy_n [alg.copy]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing copy_n_result = __in_out_result<I, O>;\n\n\tstruct __copy_n_fn : private __niebloid {\n\t\ttemplate<input_iterator I, weakly_incrementable O>\n\t\trequires indirectly_copyable<I, O>\n\t\tconstexpr copy_n_result<I, O>\n\t\toperator()(I first_, iter_difference_t<I> n, O result) const {\n\t\t\tif (n < 0) n = 0;\n\t\t\tauto norig = n;\n\t\t\tauto first = ext::uncounted(first_);\n\t\t\tfor(; n > 0; (void) ++first, (void) ++result, --n) {\n\t\t\t\t*result = *first;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\text::recounted(first_, first, norig),\n\t\t\t\tstatic_cast<O&&>(result)\n\t\t\t};\n\t\t}\n\t};\n\n\tinline constexpr __copy_n_fn copy_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/count.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_COUNT_HPP\n#define STL2_DETAIL_ALGORITHM_COUNT_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// count [alg.count]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __count_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>\n\t\trequires indirect_relation<equal_to, projected<I, Proj>, const T*>\n\t\tconstexpr iter_difference_t<I>\n\t\toperator()(I first, S last, const T& value, Proj proj = {}) const {\n\t\t\titer_difference_t<I> n = 0;\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(proj, *first) == value) {\n\t\t\t\t\t++n;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n;\n\t\t}\n\n\t\ttemplate<input_range R, class T, class Proj = identity>\n\t\trequires indirect_relation<equal_to, projected<iterator_t<R>, Proj>, const T*>\n\t\tconstexpr iter_difference_t<iterator_t<R>>\n\t\toperator()(R&& r, const T& value, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), value, __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __count_fn count{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/count_if.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_COUNT_IF_HPP\n#define STL2_DETAIL_ALGORITHM_COUNT_IF_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// count_if [alg.count]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __count_if_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr iter_difference_t<I>\n\t\toperator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tauto n = iter_difference_t<I>{0};\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *first))) {\n\t\t\t\t\t++n;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n;\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\tconstexpr iter_difference_t<iterator_t<R>>\n\t\toperator()(R&& r, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(pred), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __count_if_fn count_if{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/equal.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_EQUAL_HPP\n#define STL2_DETAIL_ALGORITHM_EQUAL_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// equal [alg.equal]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __equal_fn : private __niebloid {\n\tprivate:\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tclass Pred, class Proj1, class Proj2>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tstatic constexpr bool __equal_3(I1 first1, S1 last1, I2 first2,\n\t\t\tPred& pred, Proj1& proj1, Proj2& proj2)\n\t\t{\n\t\t\tfor (; first1 != last1; (void) ++first1, (void) ++first2) {\n\t\t\t\tif (!__stl2::invoke(pred,\n\t\t\t\t\t\t__stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, class Pred, class Proj1, class Proj2>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tstatic constexpr bool __equal_4(I1 first1, S1 last1, I2 first2, S2 last2,\n\t\t\tPred& pred, Proj1& proj1, Proj2& proj2)\n\t\t{\n\t\t\twhile (true) {\n\t\t\t\tconst bool b = first2 == last2;\n\t\t\t\tif (first1 == last1) return b;\n\t\t\t\tif (b) return false;\n\t\t\t\tif (!__stl2::invoke(pred,\n\t\t\t\t\t\t__stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2))) return false;\n\t\t\t\t++first1;\n\t\t\t\t++first2;\n\t\t\t}\n\t\t}\n\tpublic:\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,\n\t\t\tclass Pred = equal_to, class Proj1 = identity, class Proj2 = identity>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tconstexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S1, I1> && sized_sentinel_for<S2, I2>) {\n\t\t\t\tauto len1 = distance(first1, last1);\n\t\t\t\tauto len2 = distance(first2, std::move(last2));\n\t\t\t\treturn len1 == len2 &&\n\t\t\t\t\t__equal_3(std::move(first1), std::move(last1),\n\t\t\t\t\t\tstd::move(first2), pred, proj1, proj2);\n\t\t\t} else {\n\t\t\t\treturn __equal_4(\n\t\t\t\t\tstd::move(first1), std::move(last1),\n\t\t\t\t\tstd::move(first2), std::move(last2),\n\t\t\t\t\tpred, proj1, proj2);\n\t\t\t}\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, class Pred = equal_to,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>\n\t\tconstexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tif constexpr (sized_range<R1> && sized_range<R2>) {\n\t\t\t\treturn distance(r1) == distance(r2) &&\n\t\t\t\t\t__equal_3(\n\t\t\t\t\t\tbegin(r1), end(r1),\n\t\t\t\t\t\tbegin(r2), pred, proj1, proj2);\n\t\t\t} else {\n\t\t\t\treturn __equal_4(\n\t\t\t\t\tbegin(r1), end(r1),\n\t\t\t\t\tbegin(r2), end(r2),\n\t\t\t\t\tpred, proj1, proj2);\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __equal_fn equal{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/equal_range.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_EQUAL_RANGE_HPP\n#define STL2_DETAIL_ALGORITHM_EQUAL_RANGE_HPP\n\n#include <stl2/detail/algorithm/lower_bound.hpp>\n#include <stl2/detail/algorithm/upper_bound.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/view/subrange.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// equal_range [equal.range]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\tstruct __equal_range_n_fn {\n\t\t\ttemplate<forward_iterator I, class T, class Comp = less, class Proj = identity>\n\t\t\trequires indirect_strict_weak_order<Comp, const T*, projected<I, Proj>>\n\t\t\tconstexpr subrange<I>\n\t\t\toperator()(I first, iter_difference_t<I> dist, const T& value,\n\t\t\t\tComp comp = {}, Proj proj = {}) const {\n\t\t\t\tif (0 < dist) {\n\t\t\t\t\tdo {\n\t\t\t\t\t\tauto half = dist / 2;\n\t\t\t\t\t\tauto middle = next(first, half);\n\t\t\t\t\t\tauto&& v = *middle;\n\t\t\t\t\t\tauto&& pv = __stl2::invoke(proj, std::forward<decltype(v)>(v));\n\t\t\t\t\t\tif (__stl2::invoke(comp, pv, value)) {\n\t\t\t\t\t\t\tfirst = std::move(middle);\n\t\t\t\t\t\t\t++first;\n\t\t\t\t\t\t\tdist -= half + 1;\n\t\t\t\t\t\t} else if (__stl2::invoke(comp, value, pv)) {\n\t\t\t\t\t\t\tdist = half;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\text::lower_bound_n(\n\t\t\t\t\t\t\t\t\tstd::move(first), half, value,\n\t\t\t\t\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj)),\n\t\t\t\t\t\t\t\text::upper_bound_n(next(middle),\n\t\t\t\t\t\t\t\t\tdist - (half + 1), value,\n\t\t\t\t\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj))\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} while (0 != dist);\n\t\t\t\t}\n\t\t\t\treturn {first, first};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __equal_range_n_fn equal_range_n{};\n\t} // namespace ext\n\n\tstruct __equal_range_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class T, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires indirect_strict_weak_order<Comp, const T*, projected<I, Proj>>\n\t\tconstexpr subrange<I> operator()(I first, S last, const T& value,\n\t\t\tComp comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\tauto len = distance(first, std::move(last));\n\t\t\t\treturn ext::equal_range_n(std::move(first), len, value,\n\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\t// Probe exponentially for either end-of-range, an iterator that\n\t\t\t\t// is past the equal range (i.e., denotes an element greater\n\t\t\t\t// than value), or is in the equal range (denotes an element equal\n\t\t\t\t// to value).\n\t\t\t\tauto dist = iter_difference_t<I>{1};\n\t\t\t\twhile (true) {\n\t\t\t\t\tauto mid = first;\n\t\t\t\t\tauto d = advance(mid, dist, last);\n\t\t\t\t\tSTL2_EXPECT(d >= 0);\n\t\t\t\t\tif (d || mid == last) {\n\t\t\t\t\t\t// at the end of the input range\n\t\t\t\t\t\treturn ext::equal_range_n(\n\t\t\t\t\t\t\tstd::move(first), dist - d, value,\n\t\t\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t\t\t}\n\t\t\t\t\tauto&& v = *mid;\n\t\t\t\t\tauto&& pv = __stl2::invoke(proj, std::forward<decltype(v)>(v));\n\t\t\t\t\t// if value < *mid, mid is after the target range.\n\t\t\t\t\tif (__stl2::invoke(comp, value, pv)) {\n\t\t\t\t\t\treturn ext::equal_range_n(\n\t\t\t\t\t\t\tstd::move(first), dist, value,\n\t\t\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t\t\t} else if (!__stl2::invoke(comp, pv, value)) {\n\t\t\t\t\t\t// *mid == value: the lower bound is <= mid, and the upper bound is > mid.\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\text::lower_bound_n(std::move(first), dist, value,\n\t\t\t\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj)),\n\t\t\t\t\t\t\tupper_bound(std::move(mid), std::move(last),\n\t\t\t\t\t\t\t\tvalue, __stl2::ref(comp), __stl2::ref(proj))\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\t// *mid < value, mid is before the target range.\n\t\t\t\t\tfirst = std::move(mid);\n\t\t\t\t\t++first;\n\t\t\t\t\tdist *= 2;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range Rng, class T, class Comp = less, class Proj = identity>\n\t\trequires indirect_strict_weak_order<Comp, const T*, projected<iterator_t<Rng>, Proj>>\n\t\tconstexpr safe_subrange_t<Rng>\n\t\toperator()(Rng&& rng, const T& value, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif constexpr (sized_range<Rng>) {\n\t\t\t\treturn ext::equal_range_n(begin(rng), size(rng), value, __stl2::ref(comp),\n\t\t\t\t\t__stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\treturn (*this)(begin(rng), end(rng), value, __stl2::ref(comp),\n\t\t\t\t\t__stl2::ref(proj));\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __equal_range_fn equal_range{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/fill.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FILL_HPP\n#define STL2_DETAIL_ALGORITHM_FILL_HPP\n\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// fill [alg.fill]\nSTL2_OPEN_NAMESPACE {\n\tstruct __fill_fn : private __niebloid {\n\t\ttemplate<class T, output_iterator<const T&> O, sentinel_for<O> S>\n\t\tconstexpr O operator()(O first, S last, const T& value) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\t*first = value;\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<class T, output_range<const T&> R>\n\t\tconstexpr safe_iterator_t<R> operator()(R&& r, const T& value) const {\n\t\t\treturn (*this)(begin(r), end(r), value);\n\t\t}\n\t};\n\n\tinline constexpr __fill_fn fill{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/fill_n.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FILL_N_HPP\n#define STL2_DETAIL_ALGORITHM_FILL_N_HPP\n\n#include <stl2/detail/iterator/concepts.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// fill_n [alg.fill]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __fill_n_fn : private __niebloid {\n\t\ttemplate<class T, output_iterator<const T&> O>\n\t\tconstexpr O\n\t\toperator()(O first, iter_difference_t<O> n, const T& value) const {\n\t\t\tfor (; n > 0; --n, (void)++first) {\n\t\t\t\t*first = value;\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\t};\n\n\tinline constexpr __fill_n_fn fill_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/find.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FIND_HPP\n#define STL2_DETAIL_ALGORITHM_FIND_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// find [alg.find]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __find_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>\n\t\trequires indirect_relation<equal_to, projected<I, Proj>, const T*>\n\t\tconstexpr I\n\t\toperator()(I first, S last, const T& value, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(proj, *first) == value) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<input_range R, class T, class Proj = identity>\n\t\trequires indirect_relation<equal_to, projected<iterator_t<R>, Proj>, const T*>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, const T& value, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), value, __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __find_fn find{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/find_end.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FIND_END_HPP\n#define STL2_DETAIL_ALGORITHM_FIND_END_HPP\n\n#include <optional>\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// find_end [alg.find.end]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __find_end_fn : private __niebloid {\n\t\ttemplate<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,\n\t\t\tsentinel_for<I2> S2, class Pred = equal_to, class Proj1 = identity,\n\t\t\tclass Proj2 = identity>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tconstexpr I1 operator()(I1 first1, S1 last1, I2 first2, S2 last2,\n\t\t\tPred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tif (first2 == last2) {\n\t\t\t\treturn next(first1, last1);\n\t\t\t}\n\n\t\t\tif constexpr (bidirectional_iterator<I1> && bidirectional_iterator<I2>) {\n\t\t\t\tauto end1 = next(first1, last1);\n\t\t\t\tauto end2 = next(first2, last2);\n\n\t\t\t\tif constexpr (random_access_iterator<I1> && random_access_iterator<I2>) {\n\t\t\t\t\t// Take advantage of knowing source and pattern lengths.\n\t\t\t\t\t// Stop short when source is smaller than pattern\n\t\t\t\t\tconst auto len2 = end2 - first2;\n\t\t\t\t\tif (end1 - first1 < len2) {\n\t\t\t\t\t\treturn end1;\n\t\t\t\t\t}\n\n\t\t\t\t\t// End of pattern match can't go before here\n\t\t\t\t\tconst auto s = first1 + (len2 - 1);\n\n\t\t\t\t\tfor (auto l1 = end1; l1 != s; --l1) {\n\t\t\t\t\t\tauto m1 = l1;\n\t\t\t\t\t\tauto m2 = end2;\n\t\t\t\t\t\twhile (__stl2::invoke(pred,\n\t\t\t\t\t\t\t\t__stl2::invoke(proj1, *--m1),\n\t\t\t\t\t\t\t\t__stl2::invoke(proj2, *--m2))) {\n\t\t\t\t\t\t\tif (m2 == first2) {\n\t\t\t\t\t\t\t\treturn m1;\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\treturn end1;\n\t\t\t\t} else {\n\t\t\t\t\t--end2;\n\t\t\t\t\tauto l1 = end1;\n\t\t\t\t\twhile (l1 != first1) {\n\t\t\t\t\t\tif (__stl2::invoke(pred,\n\t\t\t\t\t\t\t\t__stl2::invoke(proj1, *--l1),\n\t\t\t\t\t\t\t\t__stl2::invoke(proj2, *end2))) {\n\t\t\t\t\t\t\tauto m1 = l1;\n\t\t\t\t\t\t\tauto m2 = end2;\n\t\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t\tif (m2 == first2) {\n\t\t\t\t\t\t\t\t\treturn m1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (m1 == first1) {\n\t\t\t\t\t\t\t\t\treturn end1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} while (__stl2::invoke(pred,\n\t\t\t\t\t\t\t\t\t\t__stl2::invoke(proj1, *--m1),\n\t\t\t\t\t\t\t\t\t\t__stl2::invoke(proj2, *--m2)));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn end1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstd::optional<I1> res;\n\t\t\t\tfor (; first1 != last1; ++first1) {\n\t\t\t\t\tif (__stl2::invoke(pred,\n\t\t\t\t\t\t\t__stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t\t__stl2::invoke(proj2, *first2))) {\n\t\t\t\t\t\tauto m1 = first1;\n\t\t\t\t\t\tauto m2 = first2;\n\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\tif (++m2 == last2) {\n\t\t\t\t\t\t\t\tres = first1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (++m1 == last1) {\n\t\t\t\t\t\t\t\treturn std::move(res).value_or(std::move(m1));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while (__stl2::invoke(pred,\n\t\t\t\t\t\t\t\t\t__stl2::invoke(proj1, *m1),\n\t\t\t\t\t\t\t\t\t__stl2::invoke(proj2, *m2)));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn std::move(res).value_or(std::move(first1));\n\t\t\t}\n\t\t}\n\n\n\t\ttemplate<forward_range R1, forward_range R2,\n\t\t\tclass Pred = equal_to, class Proj1 = identity, class Proj2 = identity>\n\t\trequires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>\n\t\tconstexpr safe_iterator_t<R1> operator()(R1&& r1, R2&& r2,\n\t\t\tPred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __find_end_fn find_end{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/find_first_of.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FIND_FIRST_OF_HPP\n#define STL2_DETAIL_ALGORITHM_FIND_FIRST_OF_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// find_first_of [alg.find.first.of]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __find_first_of_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, forward_iterator I2, sentinel_for<I2> S2,\n\t\t\tclass Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_relation<projected<I1, Proj1>,\tprojected<I2, Proj2>> Pred = equal_to>\n\t\tconstexpr I1 operator()(I1 first1, S1 last1, I2 first2, S2 last2,\n\t\t\tPred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tfor (; first1 != last1; ++first1) {\n\t\t\t\tfor (auto pos = first2; pos != last2; ++pos) {\n\t\t\t\t\tif (__stl2::invoke(pred,\n\t\t\t\t\t\t\t__stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t\t__stl2::invoke(proj2, *pos))) {\n\t\t\t\t\t\treturn first1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first1;\n\t\t}\n\n\t\ttemplate<input_range R1, forward_range R2,\n\t\t\tclass Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_relation<\n\t\t\t\tprojected<iterator_t<R1>, Proj1>,\n\t\t\t\tprojected<iterator_t<R2>, Proj2>> Pred = equal_to>\n\t\tconstexpr safe_iterator_t<R1>\n\t\toperator()(R1&& r1, R2&& r2, Pred pred = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __find_first_of_fn find_first_of{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/find_if.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FIND_IF_HPP\n#define STL2_DETAIL_ALGORITHM_FIND_IF_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// find_if [alg.find]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __find_if_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *first))) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __find_if_fn find_if{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/find_if_not.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FIND_IF_NOT_HPP\n#define STL2_DETAIL_ALGORITHM_FIND_IF_NOT_HPP\n\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// find_if_not [alg.find]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __find_if_not_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\treturn find_if(std::move(first), std::move(last),\n\t\t\t\t__stl2::not_fn(__stl2::ref(pred)), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Pred pred, Proj proj = {}) const {\n\t\t\treturn find_if(begin(r), end(r),\n\t\t\t\t__stl2::not_fn(__stl2::ref(pred)), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __find_if_not_fn find_if_not{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/for_each.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_FOR_EACH_HPP\n#define STL2_DETAIL_ALGORITHM_FOR_EACH_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// for_each [alg.foreach]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class F>\n\tusing for_each_result = __in_fun_result<I, F>;\n\n\tstruct __for_each_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_invocable<projected<I, Proj>> F>\n\t\tconstexpr for_each_result<I, F>\n\t\toperator()(I first, S last, F fun, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\t__stl2::invoke(fun, __stl2::invoke(proj, *first));\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(fun)};\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_unary_invocable<projected<iterator_t<R>, Proj>> F>\n\t\tconstexpr for_each_result<safe_iterator_t<R>, F>\n\t\toperator()(R&& r, F fun, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(fun), std::move(proj));\n\t\t}\n\t};\n\n\tinline constexpr __for_each_fn for_each{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/generate.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-present\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_GENERATE_HPP\n#define STL2_DETAIL_ALGORITHM_GENERATE_HPP\n\n#include <stl2/detail/concepts/function.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// generate [alg.generate]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __generate_fn : private __niebloid {\n\t\ttemplate<input_or_output_iterator O, sentinel_for<O> S, copy_constructible F>\n\t\trequires invocable<F&> && writable<O, invoke_result_t<F&>>\n\t\tconstexpr O operator()(O first, S last, F gen) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\t*first = gen();\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<class R, copy_constructible F>\n\t\trequires invocable<F&> && output_range<R, invoke_result_t<F&>>\n\t\tconstexpr safe_iterator_t<R> operator()(R&& r, F gen) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(gen));\n\t\t}\n\t};\n\n\tinline constexpr __generate_fn generate{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/generate_n.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-present\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_GENERATE_N_HPP\n#define STL2_DETAIL_ALGORITHM_GENERATE_N_HPP\n\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/concepts/function.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// generate_n [alg.generate]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __generate_n_fn : private __niebloid {\n\t\ttemplate<input_or_output_iterator O, copy_constructible F>\n\t\trequires invocable<F&> && writable<O, invoke_result_t<F&>>\n\t\tconstexpr O operator()(O first, iter_difference_t<O> n, F gen) const {\n\t\t\tfor (; n > 0; (void) ++first, --n) {\n\t\t\t\t*first = gen();\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\t};\n\n\tinline constexpr __generate_n_fn generate_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/heap_sift.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_HEAP_SIFT_HPP\n#define STL2_DETAIL_ALGORITHM_HEAP_SIFT_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// detail::sift_up_n and detail::sift_down_n\n// (heap implementation details)\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct __sift_up_n_fn {\n\t\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\t\trequires sortable<I, Comp, Proj>\n\t\t\tconstexpr void operator()(I first, iter_difference_t<I> n,\n\t\t\t\tComp comp, Proj proj) const\n\t\t\t{\n\t\t\t\tif (n <= 1) return;\n\n\t\t\t\tauto pred = [&](auto&& lhs, auto&& rhs) -> bool {\n\t\t\t\t\treturn __stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(lhs)>(lhs)),\n\t\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(rhs)>(rhs)));\n\t\t\t\t};\n\n\t\t\t\tI last = first + n;\n\t\t\t\tn = (n - 2) / 2;\n\t\t\t\tI i = first + n;\n\t\t\t\tif (!pred(*i, *--last)) return;\n\n\t\t\t\titer_value_t<I> v = iter_move(last);\n\t\t\t\tdo {\n\t\t\t\t\t*last = iter_move(i);\n\t\t\t\t\tlast = i;\n\t\t\t\t\tif (n == 0) break;\n\t\t\t\t\tn = (n - 1) / 2;\n\t\t\t\t\ti = first + n;\n\t\t\t\t} while(pred(*i, v));\n\n\t\t\t\t*last = std::move(v);\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __sift_up_n_fn sift_up_n{};\n\n\t\tstruct __sift_down_n_fn {\n\t\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\t\trequires sortable<I, Comp, Proj>\n\t\t\tconstexpr void operator()(I first, iter_difference_t<I> n, I start,\n\t\t\t\tComp comp, Proj proj) const\n\t\t\t{\n\t\t\t\t// left-child of start is at 2 * start + 1\n\t\t\t\t// right-child of start is at 2 * start + 2\n\t\t\t\tauto child = start - first;\n\n\t\t\t\tif (n < 2 || (n - 2) / 2 < child) return;\n\n\t\t\t\tauto pred = [&](auto&& lhs, auto&& rhs) -> bool {\n\t\t\t\t\treturn __stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(lhs)>(lhs)),\n\t\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(rhs)>(rhs)));\n\t\t\t\t};\n\n\t\t\t\tchild = 2 * child + 1;\n\t\t\t\tI child_i = first + child;\n\n\t\t\t\tif ((child + 1) < n && pred(*child_i, *(child_i + 1))) {\n\t\t\t\t\t// right-child exists and is greater than left-child\n\t\t\t\t\t++child_i;\n\t\t\t\t\t++child;\n\t\t\t\t}\n\n\t\t\t\t// check if we are in heap-order\n\t\t\t\tif (pred(*child_i, *start)) {\n\t\t\t\t\t// we are, start is larger than its largest child\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\titer_value_t<I> top = iter_move(start);\n\t\t\t\tdo {\n\t\t\t\t\t// we are not in heap-order, swap the parent with its largest child\n\t\t\t\t\t*start = iter_move(child_i);\n\t\t\t\t\tstart = child_i;\n\n\t\t\t\t\tif ((n - 2) / 2 < child) break;\n\n\t\t\t\t\t// recompute the child based off of the updated parent\n\t\t\t\t\tchild = 2 * child + 1;\n\t\t\t\t\tchild_i = first + child;\n\n\t\t\t\t\tif ((child + 1) < n && pred(*child_i, *(child_i + 1))) {\n\t\t\t\t\t\t// right-child exists and is greater than left-child\n\t\t\t\t\t\t++child_i;\n\t\t\t\t\t\t++child;\n\t\t\t\t\t}\n\n\t\t\t\t\t// check if we are in heap-order\n\t\t\t\t} while (!pred(*child_i, top));\n\n\t\t\t\t*start = std::move(top);\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __sift_down_n_fn sift_down_n{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/includes.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_INCLUDES_HPP\n#define STL2_DETAIL_ALGORITHM_INCLUDES_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// includes [includes]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __includes_fn : private  __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_strict_weak_order<projected<I1, Proj1>,\n\t\t\t\tprojected<I2, Proj2>> Comp = less>\n\t\tconstexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (true) {\n\t\t\t\tif (first2 == last2) return true;\n\t\t\t\tif (first1 == last1) return false;\n\t\t\t\tif (__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2),\n\t\t\t\t\t\t__stl2::invoke(proj1, *first1))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2))) {\n\t\t\t\t\t++first2;\n\t\t\t\t}\n\t\t\t\t++first1;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, class Proj1 = identity,\n\t\t\tclass Proj2 = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R1>, Proj1>,\n\t\t\t\tprojected<iterator_t<R2>, Proj2>> Comp = less>\n\t\tconstexpr bool operator()(R1&& r1, R2&& r2, Comp comp = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __includes_fn includes{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/inplace_merge.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_INPLACE_MERGE_HPP\n#define STL2_DETAIL_ALGORITHM_INPLACE_MERGE_HPP\n\n#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/temporary_vector.hpp>\n#include <stl2/detail/algorithm/lower_bound.hpp>\n#include <stl2/detail/algorithm/merge.hpp>\n#include <stl2/detail/algorithm/min.hpp>\n#include <stl2/detail/algorithm/move.hpp>\n#include <stl2/detail/algorithm/rotate.hpp>\n#include <stl2/detail/algorithm/upper_bound.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <stl2/detail/iterator/move_iterator.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// inplace_merge [alg.merge]\n//\n// TODO:\n// * sized_range overload; downgrade the enumerate call to a distance?\n// * Forward ranges.\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct merge_adaptive_fn {\n\t\t\ttemplate<bidirectional_iterator I, class C, class P>\n\t\t\trequires sortable<I, __f<C>, __f<P>>\n\t\t\tvoid operator()(I begin, I middle, I end, iter_difference_t<I> len1, iter_difference_t<I> len2,\n\t\t\t\tdetail::temporary_buffer<iter_value_t<I>>& buf, C pred, P proj) const\n\t\t\t{\n\t\t\t\t// Pre: len1 == distance(begin, midddle)\n\t\t\t\t// Pre: len2 == distance(middle, end)\n\t\t\t\tusing D = iter_difference_t<I>;\n\t\t\t\twhile (true) {\n\t\t\t\t\t// if middle == end, we're done\n\t\t\t\t\tif (len2 == 0) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// shrink [begin, middle) as much as possible (with no moves),\n\t\t\t\t\t// returning if it shrinks to 0\n\t\t\t\t\tfor (; true; ++begin, --len1) {\n\t\t\t\t\t\tif (len1 == 0) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *middle), __stl2::invoke(proj, *begin))) {\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\tif (len1 <= buf.size() || len2 <= buf.size()) {\n\t\t\t\t\t\timpl(std::move(begin), std::move(middle),\n\t\t\t\t\t\t\tstd::move(end), len1, len2, buf, pred, proj);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// begin < middle < end\n\t\t\t\t\t// *begin > *middle\n\t\t\t\t\t// partition [begin, m1) [m1, middle) [middle, m2) [m2, end) such that\n\t\t\t\t\t//     all elements in:\n\t\t\t\t\t//         [begin, m1)  <= [middle, m2)\n\t\t\t\t\t//         [middle, m2) <  [m1, middle)\n\t\t\t\t\t//         [m1, middle) <= [m2, end)\n\t\t\t\t\t//     and m1 or m2 is in the middle of its range\n\t\t\t\t\tI m1;  // \"median\" of [begin, middle)\n\t\t\t\t\tI m2;  // \"median\" of [middle, end)\n\t\t\t\t\tD len11;      // distance(begin, m1)\n\t\t\t\t\tD len21;      // distance(middle, m2)\n\t\t\t\t\t// binary search smaller range\n\t\t\t\t\tif (len1 < len2) {\n\t\t\t\t\t\t// len >= 1, len2 >= 2\n\t\t\t\t\t\tlen21 = len2 / 2;\n\t\t\t\t\t\tm2 = next(middle, len21);\n\t\t\t\t\t\tm1 = upper_bound(begin, middle, __stl2::invoke(proj, *m2),\n\t\t\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t\t\t\tlen11 = distance(begin, m1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (len1 == 1) {\n\t\t\t\t\t\t\t// len1 >= len2 && len2 > 0, therefore len2 == 1\n\t\t\t\t\t\t\t// It is known *begin > *middle\n\t\t\t\t\t\t\titer_swap(begin, middle);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// len1 >= 2, len2 >= 1\n\t\t\t\t\t\tlen11 = len1 / 2;\n\t\t\t\t\t\tm1 = next(begin, len11);\n\t\t\t\t\t\tm2 = lower_bound(middle, end, __stl2::invoke(proj, *m1),\n\t\t\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t\t\t\tlen21 = distance(middle, m2);\n\t\t\t\t\t}\n\t\t\t\t\tD len12 = len1 - len11;  // distance(m1, middle)\n\t\t\t\t\tD len22 = len2 - len21;  // distance(m2, end)\n\t\t\t\t\t// [begin, m1) [m1, middle) [middle, m2) [m2, end)\n\t\t\t\t\t// swap middle two partitions\n\t\t\t\t\tmiddle = rotate(m1, std::move(middle), m2).begin();\n\t\t\t\t\t// len12 and len21 now have swapped meanings\n\t\t\t\t\t// merge smaller range with recursive call and larger with tail recursion elimination\n\t\t\t\t\tif(len11 + len21 < len12 + len22) {\n\t\t\t\t\t\t(*this)(std::move(begin), std::move(m1), middle, len11, len21, buf,\n\t\t\t\t\t\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t\t\t\tbegin = std::move(middle);\n\t\t\t\t\t\tmiddle = std::move(m2);\n\t\t\t\t\t\tlen1 = len12;\n\t\t\t\t\t\tlen2 = len22;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t(*this)(middle, std::move(m2), std::move(end), len12, len22, buf,\n\t\t\t\t\t\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t\t\t\tend = std::move(middle);\n\t\t\t\t\t\tmiddle = std::move(m1);\n\t\t\t\t\t\tlen1 = len11;\n\t\t\t\t\t\tlen2 = len21;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tprivate:\n\t\t\ttemplate<bidirectional_iterator I, class C, class P>\n\t\t\trequires sortable<I, C, P>\n\t\t\tstatic void impl(I first, I middle, I last, iter_difference_t<I> len1,\n\t\t\t\titer_difference_t<I> len2, temporary_buffer<iter_value_t<I>>& buf,\n\t\t\t\tC& pred, P& proj)\n\t\t\t{\n\t\t\t\tSTL2_EXPENSIVE_ASSERT(len1 == distance(first, midddle));\n\t\t\t\tSTL2_EXPENSIVE_ASSERT(len2 == distance(middle, last));\n\t\t\t\ttemporary_vector<iter_value_t<I>> vec{buf};\n\t\t\t\tif (len1 <= len2) {\n\t\t\t\t\tmove(first, middle, __stl2::back_inserter(vec));\n\t\t\t\t\tmerge(\n\t\t\t\t\t\t__stl2::make_move_iterator(begin(vec)),\n\t\t\t\t\t\t__stl2::make_move_iterator(end(vec)),\n\t\t\t\t\t\t__stl2::make_move_iterator(std::move(middle)),\n\t\t\t\t\t\t__stl2::make_move_iterator(std::move(last)),\n\t\t\t\t\t\tstd::move(first), __stl2::ref(pred),\n\t\t\t\t\t\t__stl2::ref(proj), __stl2::ref(proj));\n\t\t\t\t} else {\n\t\t\t\t\tmove(middle, last, __stl2::back_inserter(vec));\n\t\t\t\t\tusing RBi = reverse_iterator<I>;\n\t\t\t\t\tmerge(\n\t\t\t\t\t\t__stl2::make_move_iterator(RBi{std::move(middle)}),\n\t\t\t\t\t\t__stl2::make_move_iterator(RBi{std::move(first)}),\n\t\t\t\t\t\t__stl2::make_move_iterator(rbegin(vec)),\n\t\t\t\t\t\t__stl2::make_move_iterator(rend(vec)),\n\t\t\t\t\t\tRBi{std::move(last)},\n\t\t\t\t\t\t__stl2::not_fn(__stl2::ref(pred)),\n\t\t\t\t\t\t__stl2::ref(proj), __stl2::ref(proj));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr merge_adaptive_fn merge_adaptive{};\n\n\t\tstruct inplace_merge_no_buffer_fn\n\t\t{\n\t\t\ttemplate<bidirectional_iterator I, class C = less, class P = identity>\n\t\t\trequires sortable<I, __f<C>, __f<P>>\n\t\t\tvoid operator()(I begin, I middle, I end, iter_difference_t<I> len1,\n\t\t\t\titer_difference_t<I> len2, C pred = {}, P proj = {}) const\n\t\t\t{\n\t\t\t\ttemporary_buffer<iter_value_t<I>> no_buffer;\n\t\t\t\tmerge_adaptive(std::move(begin), std::move(middle), std::move(end),\n\t\t\t\t\tlen1, len2, no_buffer, __stl2::ref(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr inplace_merge_no_buffer_fn inplace_merge_no_buffer{};\n\t}\n\n\tstruct __inplace_merge_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tI operator()(I first, I middle, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto len1 = distance(first, middle);\n\t\t\tauto len2_and_end = ext::enumerate(middle, std::move(last));\n\t\t\tauto buf_size = min(len1, len2_and_end.count);\n\t\t\tdetail::temporary_buffer<iter_value_t<I>> buf;\n\t\t\tif (std::is_trivially_move_assignable_v<iter_value_t<I>> && 8 < buf_size) {\n\t\t\t\tbuf = detail::temporary_buffer<iter_value_t<I>>{buf_size};\n\t\t\t}\n\t\t\tdetail::merge_adaptive(std::move(first), std::move(middle), len2_and_end.end,\n\t\t\t\tlen1, len2_and_end.count, buf, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn len2_and_end.end;\n\t\t}\n\n\t\ttemplate<bidirectional_range Rng, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<Rng>, Comp, Proj>\n\t\tsafe_iterator_t<Rng>\n\t\toperator()(Rng&& rng, iterator_t<Rng> middle, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(rng), std::move(middle), end(rng), __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __inplace_merge_fn inplace_merge{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/is_heap.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_IS_HEAP_HPP\n#define STL2_DETAIL_ALGORITHM_IS_HEAP_HPP\n\n#include <stl2/detail/algorithm/is_heap_until.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// is_heap [is.heap]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __is_heap_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\tconstexpr bool\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn last == is_heap_until(std::move(first), last,\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<random_access_range Rng, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<Rng>, Proj>> Comp = less>\n\t\tconstexpr bool\n\t\toperator()(Rng&& rng, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn end(rng) ==\n\t\t\t\tis_heap_until(rng, __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __is_heap_fn is_heap{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/is_heap_until.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_IS_HEAP_UNTIL_HPP\n#define STL2_DETAIL_ALGORITHM_IS_HEAP_UNTIL_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// is_heap_until [is.heap]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct __is_heap_until_n_fn {\n\t\t\ttemplate<random_access_iterator I, class Proj = identity,\n\t\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\t\tconstexpr I operator()(I first, const iter_difference_t<I> n,\n\t\t\t\tComp comp = {}, Proj proj = {}) const\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(0 <= n);\n\t\t\t\titer_difference_t<I> p = 0, c = 1;\n\t\t\t\tI pp = first;\n\t\t\t\twhile (c < n) {\n\t\t\t\t\tI cp = first + c;\n\t\t\t\t\tif (__stl2::invoke(comp,\n\t\t\t\t\t\t\t__stl2::invoke(proj, *pp),\n\t\t\t\t\t\t\t__stl2::invoke(proj, *cp))) {\n\t\t\t\t\t\treturn cp;\n\t\t\t\t\t}\n\t\t\t\t\t++c;\n\t\t\t\t\t++cp;\n\t\t\t\t\tif (c == n || __stl2::invoke(comp,\n\t\t\t\t\t\t\t__stl2::invoke(proj, *pp),\n\t\t\t\t\t\t\t__stl2::invoke(proj, *cp))) {\n\t\t\t\t\t\treturn cp;\n\t\t\t\t\t}\n\t\t\t\t\t++p;\n\t\t\t\t\t++pp;\n\t\t\t\t\tc = 2 * p + 1;\n\t\t\t\t}\n\t\t\t\treturn first + n;\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __is_heap_until_n_fn is_heap_until_n{};\n\t}\n\n\tstruct __is_heap_until_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(first, std::move(last));\n\t\t\treturn detail::is_heap_until_n(std::move(first), n,\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<random_access_range Rng, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<Rng>, Proj>> Comp = less>\n\t\tconstexpr safe_iterator_t<Rng>\n\t\toperator()(Rng&& rng, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn detail::is_heap_until_n(begin(rng), distance(rng),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __is_heap_until_fn is_heap_until{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/is_partitioned.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_IS_PARTITIONED_HPP\n#define STL2_DETAIL_ALGORITHM_IS_PARTITIONED_HPP\n\n#include <stl2/detail/algorithm/find_if_not.hpp>\n#include <stl2/detail/algorithm/none_of.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// is_partitioned [alg.partitions]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __is_partitioned_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr bool\n\t\toperator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tfirst = find_if_not(std::move(first), last,\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\treturn none_of(std::move(first), std::move(last),\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<input_range Rng, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<Rng>, Proj>> Pred>\n\t\tconstexpr bool\n\t\toperator()(Rng&& rng, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(rng), end(rng), __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __is_partitioned_fn is_partitioned{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/is_permutation.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015, 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_IS_PERMUTATION_HPP\n#define STL2_DETAIL_ALGORITHM_IS_PERMUTATION_HPP\n\n#include <limits>\n\n#include <stl2/detail/algorithm/count_if.hpp>\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/algorithm/mismatch.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/iterator/unreachable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// is_permutation [alg.is_permutation]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __is_permutation_fn : private __niebloid {\n\t\ttemplate<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,\n\t\t\tsentinel_for<I2> S2, class Pred = equal_to, class Proj1 = identity,\n\t\t\tclass Proj2 = identity>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tconstexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2,\n\t\t\tPred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S1, I1> || sized_sentinel_for<S2, I2>) {\n\t\t\t\titer_difference_t<I1> count1;\n\t\t\t\tif constexpr (sized_sentinel_for<S1, I1>) {\n\t\t\t\t\tcount1 = last1 - first1;\n\t\t\t\t\tif (!__has_length(first2, last2, count1)) return false;\n\t\t\t\t} else {\n\t\t\t\t\tconst auto count2 = last2 - first2;\n\t\t\t\t\tif (!__has_length(first1, last1, count2)) return false;\n\t\t\t\t\tcount1 = static_cast<decltype(count1)>(count2);\n\t\t\t\t}\n\t\t\t\treturn __is_permutation_trim(std::move(first1), std::move(first2),\n\t\t\t\t\tcount1, pred, proj1, proj2);\n\t\t\t} else {\n\t\t\t\t// shorten sequences by removing equal prefixes\n\t\t\t\tauto [mid1, mid2] = mismatch(\n\t\t\t\t\tstd::move(first1), last1, std::move(first2), last2,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\n\t\t\t\tauto [same_length, count] =\n\t\t\t\t\t__common_range_length(mid1, std::move(last1), mid2, std::move(last2));\n\t\t\t\tif (!same_length) return false;\n\n\t\t\t\treturn __is_permutation_tail(std::move(mid1), std::move(mid2),\n\t\t\t\t\tcount, pred, proj1, proj2);\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range R1, forward_range R2, class Pred = equal_to,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred,\n\t\t\tProj1, Proj2>\n\t\tconstexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tif constexpr (sized_range<R1> || sized_range<R2>) {\n\t\t\t\tusing D = iter_difference_t<iterator_t<R1>>;\n\t\t\t\tD count1;\n\t\t\t\tif constexpr (sized_range<R1>) {\n\t\t\t\t\tcount1 = distance(r1);\n\t\t\t\t\tif (!__has_length(r2, count1)) return false;\n\t\t\t\t} else {\n\t\t\t\t\tconst auto count2 = distance(r2);\n\t\t\t\t\tif (!__has_length(r1, count2)) return false;\n\t\t\t\t\tcount1 = static_cast<D>(count2);\n\t\t\t\t}\n\t\t\t\treturn __is_permutation_trim(begin(r1), begin(r2),\n\t\t\t\t\tcount1, pred, proj1, proj2);\n\t\t\t} else {\n\t\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t\t}\n\t\t}\n\tprivate:\n\t\ttemplate<integral To, integral From>\n\t\tstatic constexpr bool __can_represent(const From value) noexcept {\n\t\t\tusing C = decltype(true ? value : To{});\n\t\t\tif constexpr (same_as<To, C> && (signed_integral<To> || unsigned_integral<From>)) {\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\tif constexpr (signed_integral<From>) {\n\t\t\t\t\tif constexpr (unsigned_integral<To>) {\n\t\t\t\t\t\tif (value < 0) return false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (C(value) < C(std::numeric_limits<To>::min())) return false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn C(value) <= C(std::numeric_limits<To>::max());\n\t\t\t}\n\t\t}\n\n\t\t// Does distance(first, last) == n?\n\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S, signed_integral D>\n\t\tstatic constexpr bool __has_length(const I first, const S last, const D n) {\n\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\treturn n == last - first;\n\t\t\t} else {\n\t\t\t\tif (__can_represent<iter_difference_t<I>>(n)) {\n\t\t\t\t\treturn advance(first, n, last) == 0 &&\n\t\t\t\t\t\tfirst == last;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t// Does distance(rng) == n?\n\t\ttemplate<range Rng, signed_integral D>\n\t\tstatic constexpr bool __has_length(Rng&& rng, const D n) {\n\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\tif constexpr (sized_range<Rng>) {\n\t\t\t\treturn n == distance(rng);\n\t\t\t} else {\n\t\t\t\treturn __has_length(begin(rng), end(rng), n);\n\t\t\t}\n\t\t}\n\n\t\t// Do the two ranges have the same length, and if so what is it?\n\t\ttemplate<input_or_output_iterator I1, sentinel_for<I1> S1,\n\t\t\tinput_or_output_iterator I2, sentinel_for<I2> S2>\n\t\tstatic constexpr std::pair<bool, iter_difference_t<I1>>\n\t\t__common_range_length(I1 first1, S1 last1, I2 first2, S2 last2) {\n\t\t\tusing D = iter_difference_t<I1>;\n\n\t\t\tif constexpr (sized_sentinel_for<S1, I1>) {\n\t\t\t\tconst auto count = last1 - first1;\n\t\t\t\treturn {__has_length(first2, last2, count), count};\n\t\t\t} else if constexpr (sized_sentinel_for<S2, I2>) {\n\t\t\t\tconst auto count = last2 - first2;\n\t\t\t\treturn {__has_length(first1, last1, count), static_cast<D>(count)};\n\t\t\t} else {\n\t\t\t\tfor (D count = 0;; ++first1, (void)++count, ++first2) {\n\t\t\t\t\tconst bool end_of_second = first2 == last2;\n\t\t\t\t\tif (first1 == last1) return {end_of_second, count};\n\t\t\t\t\tif (end_of_second) return {false, count};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttemplate<range Rng1, range Rng2>\n\t\tstatic constexpr std::pair<bool, iter_difference_t<iterator_t<Rng1>>>\n\t\t__common_range_length(Rng1&& rng1, Rng2&& rng2) {\n\t\t\tusing D = iter_difference_t<iterator_t<Rng1>>;\n\n\t\t\tif constexpr (sized_range<Rng1>) {\n\t\t\t\tauto count = distance(rng1);\n\t\t\t\treturn {__has_length(rng2, count), count};\n\t\t\t} else if constexpr (sized_range<Rng2>) {\n\t\t\t\tauto count = distance(rng2);\n\t\t\t\treturn {__has_length(rng1, count), static_cast<D>(count)};\n\t\t\t} else {\n\t\t\t\treturn __common_range_length(\n\t\t\t\t\tbegin(rng1), end(rng1),\n\t\t\t\t\tbegin(rng2), end(rng2));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_iterator I1, forward_iterator I2,\n\t\t\tclass Pred, class Proj1, class Proj2>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tstatic bool __is_permutation_tail(const I1 first1, const I2 first2,\n\t\t\tconst iter_difference_t<I1> n, Pred& pred, Proj1& proj1, Proj2& proj2)\n\t\t{\n\t\t\t// Pre: [first1, n) and [first2, n) are valid ranges.\n\t\t\t// Pre: n == 0 or *first1 != *first2.\n\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\tif (n == 0) return true;\n\t\t\tSTL2_ASSERT(!__stl2::invoke(pred, __stl2::invoke(proj1, *first1), __stl2::invoke(proj2, *first2)));\n\t\t\tif (n == 1) return false;\n\n\t\t\t// For each element in [first1, n), see if there are the same number of\n\t\t\t// equal elements in [first2, n)\n\t\t\tcounted_iterator<I1> i{first1, n};\n\t\t\twhile (i.count()) {\n\t\t\t\tauto&& e = __stl2::invoke(proj1, *i);\n\t\t\t\tauto match_predicate = [&pred, &e](auto&& x) {\n\t\t\t\t\treturn __stl2::invoke(pred, e, static_cast<decltype(x)&&>(x));\n\t\t\t\t};\n\n\t\t\t\t// If for some j in [first1, i.base()), *j == e, we've already\n\t\t\t\t// validated the counts of elements equal to e.\n\t\t\t\tauto match = find_if(counted_iterator{first1, n - i.count()},\n\t\t\t\t\tdefault_sentinel, match_predicate, __stl2::ref(proj1));\n\t\t\t\t++i;\n\t\t\t\tif (match.count()) continue;\n\n\t\t\t\t// Count number of e in [first2, n)\n\t\t\t\tconst auto c2 = count_if(counted_iterator{first2, n},\n\t\t\t\t\tdefault_sentinel, match_predicate, __stl2::ref(proj2));\n\t\t\t\tif (c2 == 0) return false;\n\n\t\t\t\t// Count number of e in [i, default_sentinel)\n\t\t\t\tconst auto c1 = count_if(i, default_sentinel,\n\t\t\t\t\tmatch_predicate, __stl2::ref(proj1));\n\n\t\t\t\t// If the number of e in [first2, n) is not equal to\n\t\t\t\t// the number of e in [first1, n), we don't have a permutation.\n\t\t\t\tif (c1 + 1 != c2) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate<forward_iterator I1, forward_iterator I2,\n\t\t\tclass Pred, class Proj1, class Proj2>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tstatic bool __is_permutation_trim(I1 first1, I2 first2, iter_difference_t<I1> n,\n\t\t\tPred& pred, Proj1& proj1, Proj2& proj2)\n\t\t{\n\t\t\t// trim equal prefixes\n\t\t\tauto [counted, mid2] = mismatch(\n\t\t\t\tcounted_iterator{std::move(first1), n}, default_sentinel,\n\t\t\t\tstd::move(first2), unreachable_sentinel,\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\n\t\t\t// TODO: trim equal suffixes from bidirectional sequences?\n\n\t\t\treturn __is_permutation_tail(counted.base(), std::move(mid2),\n\t\t\t\tcounted.count(), pred, proj1, proj2);\n\t\t}\n\t};\n\n\tinline constexpr __is_permutation_fn is_permutation{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/is_sorted.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_IS_SORTED_HPP\n#define STL2_DETAIL_ALGORITHM_IS_SORTED_HPP\n\n#include <stl2/detail/algorithm/is_sorted_until.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// is_sorted [is.sorted]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __is_sorted_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\tconstexpr bool\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn last == is_sorted_until(std::move(first), last,\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\tconstexpr bool operator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn end(r) == is_sorted_until(begin(r), end(r),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __is_sorted_fn is_sorted{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/is_sorted_until.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_IS_SORTED_UNTIL_HPP\n#define STL2_DETAIL_ALGORITHM_IS_SORTED_UNTIL_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// is_sorted_until [is.sorted]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __is_sorted_until_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif (first != last) {\n\t\t\t\twhile (true) {\n\t\t\t\t\tauto prev = first;\n\t\t\t\t\tif (++first == last || __stl2::invoke(comp,\n\t\t\t\t\t\t\t__stl2::invoke(proj, *first),\n\t\t\t\t\t\t\t__stl2::invoke(proj, *prev))) {\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\treturn first;\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __is_sorted_until_fn is_sorted_until{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/lexicographical_compare.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP\n#define STL2_DETAIL_ALGORITHM_LEXICOGRAPHICAL_COMPARE_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// lexicographical_compare [alg.lex.comparison]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __lexicographical_compare_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_strict_weak_order<projected<I1, Proj1>,\n\t\t\t\tprojected<I2, Proj2>> Comp = less>\n\t\tconstexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (true) {\n\t\t\t\tconst bool at_end2 = first2 == last2;\n\n\t\t\t\tif (first1 == last1) return !at_end2;\n\t\t\t\tif (at_end2) return false;\n\n\t\t\t\tif (__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2))) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2),\n\t\t\t\t\t\t__stl2::invoke(proj1, *first1))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t++first1;\n\t\t\t\t++first2;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<input_range Rng1, input_range Rng2,\n\t\t\tclass Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<Rng1>, Proj1>,\n\t\t\t\tprojected<iterator_t<Rng2>, Proj2>> Comp = less>\n\t\tconstexpr bool operator()(Rng1&& rng1, Rng2&& rng2,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(rng1), end(rng1), begin(rng2), end(rng2),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __lexicographical_compare_fn lexicographical_compare{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/lower_bound.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_LOWER_BOUND_HPP\n#define STL2_DETAIL_ALGORITHM_LOWER_BOUND_HPP\n\n#include <stl2/detail/algorithm/partition_point.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// lower_bound [lower.bound]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\tstruct __lower_bound_n_fn {\n\t\t\ttemplate<class I, class T, class Comp = less, class Proj = identity>\n\t\t\trequires forward_iterator<__f<I>> &&\n\t\t\t\tindirect_strict_weak_order<Comp, const T*, projected<__f<I>, Proj>>\n\t\t\tconstexpr __f<I> operator()(I&& first, iter_difference_t<__f<I>> n,\n\t\t\t\tconst T& value, Comp comp = {}, Proj proj = {}) const\n\t\t\t{\n\t\t\t\tauto pred = [&](auto&& i) -> bool {\n\t\t\t\t\treturn __stl2::invoke(comp, i, value);\n\t\t\t\t};\n\t\t\t\treturn __stl2::ext::partition_point_n(std::forward<I>(first), n,\n\t\t\t\t\tstd::move(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __lower_bound_n_fn lower_bound_n{};\n\t}\n\n\tstruct __lower_bound_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<const T*, projected<I, Proj>> Comp = less>\n\t\tconstexpr I operator()(I first, S last, const T& value, Comp comp = {},\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\tauto n = distance(first, std::move(last));\n\t\t\t\treturn ext::lower_bound_n(std::move(first), n, value,\n\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\tauto pred = [&](auto&& i) -> bool {\n\t\t\t\t\treturn __stl2::invoke(comp, i, value);\n\t\t\t\t};\n\t\t\t\treturn partition_point(std::move(first), std::move(last),\n\t\t\t\t\tstd::move(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range Rng, class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<const T*,\n\t\t\t\tprojected<iterator_t<Rng>, Proj>> Comp = less>\n\t\tconstexpr safe_iterator_t<Rng> operator()(Rng&& rng, const T& value,\n\t\t\tComp comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\tif constexpr (sized_range<Rng>) {\n\t\t\t\treturn ext::lower_bound_n(begin(rng), distance(rng), value,\n\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\treturn (*this)(begin(rng), end(rng), value,\n\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __lower_bound_fn lower_bound{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/make_heap.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_MAKE_HEAP_HPP\n#define STL2_DETAIL_ALGORITHM_MAKE_HEAP_HPP\n\n#include <stl2/detail/algorithm/heap_sift.hpp>\n#include <stl2/detail/range/dangling.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// make_heap [make.heap]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __make_heap_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(first, std::move(last));\n\t\t\tmake_heap_n(first, n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn first + n;\n\t\t}\n\n\t\ttemplate<random_access_range Rng, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<Rng>, Comp, Proj>\n\t\tconstexpr safe_iterator_t<Rng>\n\t\toperator()(Rng&& rng, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(rng);\n\t\t\tmake_heap_n(begin(rng), n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn begin(rng) + n;\n\t\t}\n\tprivate:\n\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\trequires sortable<I, Comp, Proj>\n\t\tstatic void make_heap_n(I first, iter_difference_t<I> n, Comp comp, Proj proj) {\n\t\t\tif (n > 1) {\n\t\t\t\t// start from the first parent, there is no need to consider children\n\t\t\t\tfor (auto start = (n - 2) / 2; start >= 0; --start) {\n\t\t\t\t\tdetail::sift_down_n(first, n, first + start,\n\t\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __make_heap_fn make_heap{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/max.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MAX_HPP\n#define STL2_DETAIL_ALGORITHM_MAX_HPP\n\n#include <initializer_list>\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// max [alg.min.max]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __max_fn : private __niebloid {\n\t\ttemplate<class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<const T*, Proj>> Comp = less>\n\t\tconstexpr const T&\n\t\toperator()(const T& a, const T& b, Comp comp = {}, Proj proj = {}) const {\n\t\t\tconst bool test = __stl2::invoke(comp,\n\t\t\t\t__stl2::invoke(proj, a), __stl2::invoke(proj, b));\n\t\t\treturn !test ? a : b;\n\t\t}\n\n\t\ttemplate<copyable T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<const T*, Proj>> Comp = less>\n\t\tconstexpr T operator()(std::initializer_list<T> r, Comp comp = {},\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\treturn impl(r, __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\trequires\n\t\t\tindirectly_copyable_storable<iterator_t<R>, iter_value_t<iterator_t<R>>*>\n\t\tconstexpr iter_value_t<iterator_t<R>>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn impl(r, __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\tprivate:\n\t\ttemplate<input_range R, class Proj,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp>\n\t\trequires\n\t\t\tindirectly_copyable_storable<iterator_t<R>, iter_value_t<iterator_t<R>>*>\n\t\tstatic constexpr iter_value_t<iterator_t<R>>\n\t\timpl(R&& r, Comp comp, Proj proj) {\n\t\t\tauto first = begin(r);\n\t\t\tauto last = end(r);\n\t\t\tSTL2_EXPECT(first != last);\n\t\t\titer_value_t<iterator_t<R>> result = *first;\n\t\t\twhile (++first != last) {\n\t\t\t\tauto&& tmp = *first;\n\t\t\t\tif (__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj, result),\n\t\t\t\t\t\t__stl2::invoke(proj, tmp))) {\n\t\t\t\t\tresult = static_cast<decltype(tmp)>(tmp);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tinline constexpr __max_fn max{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/max_element.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MAX_ELEMENT_HPP\n#define STL2_DETAIL_ALGORITHM_MAX_ELEMENT_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// max_element [alg.min.max]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __max_element_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif (first != last) {\n\t\t\t\tfor (auto i = next(first); i != last; ++i) {\n\t\t\t\t\tif (!__stl2::invoke(comp,\n\t\t\t\t\t\t\t__stl2::invoke(proj, *i),\n\t\t\t\t\t\t\t__stl2::invoke(proj, *first))) {\n\t\t\t\t\t\tfirst = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __max_element_fn max_element{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/merge.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MERGE_HPP\n#define STL2_DETAIL_ALGORITHM_MERGE_HPP\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// merge [alg.merge]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2, class O>\n\tusing merge_result = __in_in_out_result<I1, I2, O>;\n\n\tstruct __merge_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,\n\t\t\tweakly_incrementable O, class Comp = less, class Proj1 = identity,\n\t\t\tclass Proj2 = identity>\n\t\trequires mergeable<I1, I2, O, Comp, Proj1, Proj2>\n\t\tconstexpr merge_result<I1, I2, O>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2, O result,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (true) {\n\t\t\t\tif (first1 == last1) {\n\t\t\t\t\tauto cresult = copy(std::move(first2), std::move(last2), std::move(result));\n\t\t\t\t\tfirst2 = std::move(cresult.in);\n\t\t\t\t\tresult = std::move(cresult.out);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (first2 == last2) {\n\t\t\t\t\tauto cresult = copy(std::move(first1), std::move(last1), std::move(result));\n\t\t\t\t\tfirst1 = std::move(cresult.in);\n\t\t\t\t\tresult = std::move(cresult.out);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\titer_reference_t<I1>&& v1 = *first1;\n\t\t\t\titer_reference_t<I2>&& v2 = *first2;\n\t\t\t\tif (__stl2::invoke(comp, __stl2::invoke(proj1, v1), __stl2::invoke(proj2, v2))) {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I1>>(v1);\n\t\t\t\t\t++first1;\n\t\t\t\t} else {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I2>>(v2);\n\t\t\t\t\t++first2;\n\t\t\t\t}\n\t\t\t\t++result;\n\t\t\t}\n\t\t\treturn {std::move(first1), std::move(first2), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, weakly_incrementable O, class Comp = less,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>\n\t\tconstexpr merge_result<safe_iterator_t<R1>, safe_iterator_t<R2>, O>\n\t\toperator()(R1&& r1, R2&& r2, O result, Comp comp = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\tstd::move(result), __stl2::ref(comp), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __merge_fn merge{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/min.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MIN_HPP\n#define STL2_DETAIL_ALGORITHM_MIN_HPP\n\n#include <initializer_list>\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// min [alg.min.max]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __min_fn : private __niebloid {\n\t\ttemplate<class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<const T*, Proj>> Comp = less>\n\t\tconstexpr const T&\n\t\toperator()(const T& a, const T& b, Comp comp = {}, Proj proj = {}) const {\n\t\t\tconst bool test = __stl2::invoke(comp,\n\t\t\t\t__stl2::invoke(proj, b), __stl2::invoke(proj, a));\n\t\t\treturn test ? b : a;\n\t\t}\n\n\t\ttemplate<copyable T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<const T*, Proj>> Comp = less>\n\t\tconstexpr T\n\t\toperator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn impl(r, __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\trequires indirectly_copyable_storable<iterator_t<R>, iter_value_t<iterator_t<R>>*>\n\t\tconstexpr iter_value_t<iterator_t<R>>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn impl(r, __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\tprivate:\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\trequires\n\t\t\tindirectly_copyable_storable<iterator_t<R>, iter_value_t<iterator_t<R>>*>\n\t\tstatic constexpr iter_value_t<iterator_t<R>>\n\t\timpl(R&& r, Comp comp = {}, Proj proj = {}) {\n\t\t\tauto first = begin(r);\n\t\t\tauto last = end(r);\n\t\t\tSTL2_EXPECT(first != last);\n\t\t\titer_value_t<iterator_t<R>> result = *first;\n\t\t\twhile (++first != last) {\n\t\t\t\tauto&& tmp = *first;\n\t\t\t\tif (__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj, tmp),\n\t\t\t\t\t\t__stl2::invoke(proj, result))) {\n\t\t\t\t\tresult = static_cast<decltype(tmp)>(tmp);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tinline constexpr __min_fn min{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/min_element.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MIN_ELEMENT_HPP\n#define STL2_DETAIL_ALGORITHM_MIN_ELEMENT_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// min_element [alg.min.max]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __min_element_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif (first != last) {\n\t\t\t\tfor (auto i = next(first); i != last; ++i) {\n\t\t\t\t\tif (__stl2::invoke(comp,\n\t\t\t\t\t\t\t__stl2::invoke(proj, *i),\n\t\t\t\t\t\t\t__stl2::invoke(proj, *first))) {\n\t\t\t\t\t\tfirst = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __min_element_fn min_element{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/minmax.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MINMAX_HPP\n#define STL2_DETAIL_ALGORITHM_MINMAX_HPP\n\n#include <initializer_list>\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// minmax [alg.min.max]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __minmax_fn : private __niebloid {\n\t\ttemplate<class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<const T*, Proj>> Comp = less>\n\t\tconstexpr minmax_result<const T&>\n\t\toperator()(const T& a, const T& b, Comp comp = {}, Proj proj = {}) const {\n\t\t\tconst bool test = __stl2::invoke(comp,\n\t\t\t\t__stl2::invoke(proj, b), __stl2::invoke(proj, a));\n\t\t\tif (test)\n\t\t\t\treturn {b, a};\n\t\t\telse\n\t\t\t\treturn {a, b};\n\t\t}\n\n\t\ttemplate<copyable T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<const T*, Proj>> Comp = less>\n\t\tconstexpr minmax_result<T>\n\t\toperator()(std::initializer_list<T>&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn impl(r, __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\trequires copyable<iter_value_t<iterator_t<R>>>\n\t\tconstexpr minmax_result<iter_value_t<iterator_t<R>>>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn impl(r, __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\tprivate:\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\trequires indirectly_copyable_storable<iterator_t<R>, iter_value_t<iterator_t<R>>*>\n\t\tstatic constexpr minmax_result<iter_value_t<iterator_t<R>>>\n\t\timpl(R&& r, Comp comp = {}, Proj proj = {}) {\n\t\t\tusing V = iter_value_t<iterator_t<R>>;\n\t\t\tauto first = begin(r);\n\t\t\tauto last = end(r);\n\t\t\tSTL2_EXPECT(first != last);\n\t\t\tminmax_result<V> result{*first, *first};\n\t\t\tif (++first == last) return result;\n\n\t\t\tauto pred = [&](auto& lhs, auto& rhs) -> bool {\n\t\t\t\treturn __stl2::invoke(comp, __stl2::invoke(proj, lhs),\n\t\t\t\t\t__stl2::invoke(proj, rhs));\n\t\t\t};\n\n\t\t\t{\n\t\t\t\tauto&& tmp = *first;\n\t\t\t\tif (pred(tmp, result.min)) {\n\t\t\t\t\tresult.min = static_cast<decltype(tmp)>(tmp);\n\t\t\t\t} else {\n\t\t\t\t\tresult.max = static_cast<decltype(tmp)>(tmp);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhile (true) {\n\t\t\t\tif (++first == last) return result;\n\n\t\t\t\tauto tmp1 = V{*first};\n\t\t\t\tif (++first == last) {\n\t\t\t\t\tif (pred(tmp1, result.min)) result.min = std::move(tmp1);\n\t\t\t\t\telse if (!pred(tmp1, result.max)) result.max = std::move(tmp1);\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tauto&& tmp2 = *first;\n\t\t\t\tif (pred(tmp2, tmp1)) {\n\t\t\t\t\tif (pred(tmp2, result.min)) {\n\t\t\t\t\t\tresult.min = static_cast<decltype(tmp2)>(tmp2);\n\t\t\t\t\t}\n\t\t\t\t\tif (!pred(tmp1, result.max)) {\n\t\t\t\t\t\tresult.max = std::move(tmp1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (pred(tmp1, result.min)) {\n\t\t\t\t\t\tresult.min = std::move(tmp1);\n\t\t\t\t\t}\n\t\t\t\t\tif (!pred(tmp2, result.max)) {\n\t\t\t\t\t\tresult.max = static_cast<decltype(tmp2)>(tmp2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __minmax_fn minmax{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/minmax_element.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n// Implementation based on the code in libc++\n//   http://http://libcxx.llvm.org/\n//\n#ifndef STL2_DETAIL_ALGORITHM_MINMAX_ELEMENT_HPP\n#define STL2_DETAIL_ALGORITHM_MINMAX_ELEMENT_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// minmax_element [alg.min.max]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __minmax_element_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<I, Proj>> Comp = less>\n\t\tconstexpr minmax_result<I>\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\tminmax_result<I> result{first, first};\n\t\t\tif (first == last || ++first == last) return result;\n\n\t\t\tauto pred = [&](auto&& lhs, auto&& rhs) -> bool {\n\t\t\t\treturn __stl2::invoke(comp,\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(lhs)>(lhs)),\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(rhs)>(rhs)));\n\t\t\t};\n\t\t\tif (pred(*first, *result.max)) result.min = first;\n\t\t\telse result.max = first;\n\n\t\t\twhile (true) {\n\t\t\t\tif (++first == last) return result;\n\n\t\t\t\tI tmp = first;\n\t\t\t\tif (++first == last) {\n\t\t\t\t\tif (pred(*tmp, *result.min)) result.min = tmp;\n\t\t\t\t\telse if (!pred(*tmp, *result.max)) result.max = tmp;\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (pred(*first, *tmp)) {\n\t\t\t\t\tif (pred(*first, *result.min)) result.min = first;\n\t\t\t\t\tif (!pred(*tmp, *result.max)) result.max = tmp;\n\t\t\t\t} else {\n\t\t\t\t\tif (pred(*tmp, *result.min)) result.min = tmp;\n\t\t\t\t\tif (!pred(*first, *result.max)) result.max = first;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = less>\n\t\tconstexpr minmax_result<safe_iterator_t<R>>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __minmax_element_fn minmax_element{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/mismatch.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MISMATCH_HPP\n#define STL2_DETAIL_ALGORITHM_MISMATCH_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// mismatch [mismatch]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2>\n\tusing mismatch_result = __in_in_result<I1, I2>;\n\n\tstruct __mismatch_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_relation<projected<I1, Proj1>,\n\t\t\t\tprojected<I2, Proj2>> Pred = equal_to>\n\t\tconstexpr mismatch_result<I1, I2>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (true) {\n\t\t\t\tif (first1 == last1) break;\n\t\t\t\tif (first2 == last2) break;\n\t\t\t\tif (!__stl2::invoke(pred,\n\t\t\t\t\t\t__stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2))) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t++first1;\n\t\t\t\t++first2;\n\t\t\t}\n\t\t\treturn {std::move(first1), std::move(first2)};\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2,\n\t\t\tclass Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_relation<projected<iterator_t<R1>, Proj1>,\n\t\t\t\tprojected<iterator_t<R2>, Proj2>> Pred = equal_to>\n\t\tconstexpr mismatch_result<safe_iterator_t<R1>, safe_iterator_t<R2>>\n\t\toperator()(R1&& r1, R2&& r2, Pred pred = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __mismatch_fn mismatch{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/move.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MOVE_HPP\n#define STL2_DETAIL_ALGORITHM_MOVE_HPP\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// move [alg.move]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing move_result = __in_out_result<I, O>;\n\n\tstruct __move_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O>\n\t\trequires indirectly_movable<I, O>\n\t\tconstexpr move_result<I, O>\n\t\toperator()(I first, S last, O result) const {\n\t\t\tfor (; first != last; (void) ++first, (void) ++result) {\n\t\t\t\t*result = iter_move(first);\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O>\n\t\trequires indirectly_movable<iterator_t<R>, O>\n\t\tconstexpr move_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(result));\n\t\t}\n\t};\n\n\tinline constexpr __move_fn move{};\n\n\tnamespace ext {\n\t\tstruct __move_fn : private __niebloid {\n\t\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O>\n\t\t\trequires indirectly_movable<I, O>\n\t\t\tconstexpr move_result<I, O>\n\t\t\toperator()(I first, S last, O result) const {\n\t\t\t\tfor (; first != last; (void) ++first, (void) ++result) {\n\t\t\t\t\t*result = iter_move(first);\n\t\t\t\t}\n\t\t\t\treturn {std::move(first), std::move(result)};\n\t\t\t}\n\n\t\t\ttemplate<input_range R, class O>\n\t\t\trequires (!range<O> && weakly_incrementable<__f<O>>\n\t\t\t\t&& indirectly_movable<iterator_t<R>, __f<O>>)\n\t\t\tconstexpr move_result<safe_iterator_t<R>, __f<O>>\n\t\t\toperator()(R&& r, O&& result_) const {\n\t\t\t\tauto result = std::forward<O>(result_);\n\t\t\t\treturn (*this)(begin(r), end(r), std::move(result));\n\t\t\t}\n\n\t\t\t// Extension\n\t\t\ttemplate<input_iterator I1, sentinel_for<I1> S1,\n\t\t\t\tinput_or_output_iterator I2, sentinel_for<I2> S2>\n\t\t\trequires indirectly_movable<I1, I2>\n\t\t\tconstexpr move_result<I1, I2>\n\t\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2) const {\n\t\t\t\twhile (true) {\n\t\t\t\t\tif (first1 == last1) break;\n\t\t\t\t\tif (first2 == last2) break;\n\t\t\t\t\t*first2 = iter_move(first1);\n\t\t\t\t\t++first1;\n\t\t\t\t\t++first2;\n\t\t\t\t}\n\t\t\t\treturn {std::move(first1), std::move(first2)};\n\t\t\t}\n\n\t\t\t// Extension\n\t\t\ttemplate<input_range R1, range R2>\n\t\t\trequires indirectly_movable<iterator_t<R1>, iterator_t<R2>>\n\t\t\tconstexpr move_result<safe_iterator_t<R1>, safe_iterator_t<R2>>\n\t\t\toperator()(R1&& r1, R2&& r2) const {\n\t\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2));\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __move_fn move{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/move_backward.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_MOVE_BACKWARD_HPP\n#define STL2_DETAIL_ALGORITHM_MOVE_BACKWARD_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// move_backward [alg.move]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2>\n\tusing move_backward_result = __in_out_result<I1, I2>;\n\n\tstruct __move_backward_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I1, sentinel_for<I1> S1,\n\t\t\tbidirectional_iterator I2>\n\t\trequires indirectly_movable<I1, I2>\n\t\tconstexpr move_backward_result<I1, I2>\n\t\toperator()(I1 first, S1 s, I2 result) const {\n\t\t\tauto last = next(first, std::move(s));\n\t\t\tauto i = last;\n\t\t\twhile (i != first) {\n\t\t\t\t*--result = iter_move(--i);\n\t\t\t}\n\t\t\treturn {std::move(last), std::move(result)};\n\t\t}\n\n\t\ttemplate<bidirectional_range Rng, bidirectional_iterator I>\n\t\trequires indirectly_movable<iterator_t<Rng>, I>\n\t\tconstexpr move_backward_result<safe_iterator_t<Rng>, I>\n\t\toperator()(Rng&& rng, I result) const {\n\t\t\treturn (*this)(begin(rng), end(rng), std::move(result));\n\t\t}\n\t};\n\n\tinline constexpr __move_backward_fn move_backward{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/next_permutation.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===-------------------------- algorithm ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_NEXT_PERMUTATION_HPP\n#define STL2_DETAIL_ALGORITHM_NEXT_PERMUTATION_HPP\n\n#include <stl2/detail/algorithm/reverse.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// next_permutation [alg.permutation.generators]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __next_permutation_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I, sentinel_for<I> S,\n\t\t\tclass Comp = less, class Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr bool\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif (first == last) return false;\n\n\t\t\tI end = next(first, std::move(last));\n\t\t\tI i = end;\n\t\t\tif (first == --i) return false;\n\n\t\t\tauto pred = [&](auto&& lhs, auto&& rhs) -> bool {\n\t\t\t\treturn __stl2::invoke(comp,\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(lhs)>(lhs)),\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(rhs)>(rhs)));\n\t\t\t};\n\n\t\t\twhile (true) {\n\t\t\t\tI ip1 = i;\n\t\t\t\tif (pred(*--i, *ip1)) {\n\t\t\t\t\tI j = end;\n\t\t\t\t\twhile (!pred(*i, *--j)) {\n\t\t\t\t\t\t;\n\t\t\t\t\t}\n\t\t\t\t\titer_swap(i, j);\n\t\t\t\t\treverse(ip1, end);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (i == first) {\n\t\t\t\t\treverse(first, end);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<bidirectional_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tconstexpr bool\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __next_permutation_fn next_permutation{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/none_of.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_NONE_OF_HPP\n#define STL2_DETAIL_ALGORITHM_NONE_OF_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\n////////////////////////////////////////////////////////////////////////////////\n// none_of [alg.none_of]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __none_of_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr bool\n\t\toperator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *first))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\ttemplate<input_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\tconstexpr bool operator()(R&& r, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __none_of_fn none_of{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/nth_element.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_NTH_ELEMENT_HPP\n#define STL2_DETAIL_ALGORITHM_NTH_ELEMENT_HPP\n\n#include <stl2/detail/algorithm/min_element.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// nth_element [alg.nth.element]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __nth_element_fn : private __niebloid {\n\t\t// TODO: refactor this monstrosity.\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr I operator()(I first, I nth, S last, Comp comp = {},\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\tconstexpr iter_difference_t<I> limit = 7;\n\t\t\tstatic_assert(limit >= 3);\n\n\t\t\tauto pred = [&](auto&& lhs, auto&& rhs) -> bool {\n\t\t\t\treturn __stl2::invoke(comp,\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(lhs)>(lhs)),\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(rhs)>(rhs)));\n\t\t\t};\n\n\t\t\tI end_orig = next(nth, last);\n\t\t\tI end = end_orig;\n\t\t\twhile (true) {\n\t\t\t\tif (nth == end) return end_orig;\n\n\t\t\t\titer_difference_t<I> len = end - first;\n\t\t\t\tSTL2_EXPECT(len >= 0);\n\t\t\t\tswitch (len) {\n\t\t\t\tcase 0:\n\t\t\t\tcase 1:\n\t\t\t\t\treturn end_orig;\n\t\t\t\tcase 2:\n\t\t\t\t\tif (pred(*--end, *first)) iter_swap(first, end);\n\t\t\t\t\treturn end_orig;\n\t\t\t\tcase 3:\n\t\t\t\t\t{\n\t\t\t\t\t\tI m = first;\n\t\t\t\t\t\tsort3(first, ++m, --end, comp, proj);\n\t\t\t\t\t\treturn end_orig;\n\t\t\t\t\t}\n\t\t\t\tdefault: break;\n\t\t\t\t}\n\t\t\t\tif (len <= limit) {\n\t\t\t\t\tselection_sort(first, end, comp, proj);\n\t\t\t\t\treturn end_orig;\n\t\t\t\t}\n\t\t\t\t// Post: len > limit\n\n\t\t\t\tI m = first + len / 2;\n\t\t\t\tI lm1 = end;\n\t\t\t\tunsigned n_swaps = sort3(first, m, --lm1, comp, proj);\n\t\t\t\t// Post: *m is median\n\n\t\t\t\t// partition [first, m) < *m and *m <= [m, end)\n\t\t\t\t//(this inhibits tossing elements equivalent to m around unnecessarily)\n\t\t\t\tI i = first;\n\t\t\t\tI j = lm1;\n\t\t\t\t// j points beyond range to be tested, *lm1 is known to be <= *m\n\t\t\t\t// The search going up is known to be guarded but the search coming down isn't.\n\t\t\t\t// Prime the downward search with a guard.\n\t\t\t\tif (!pred(*i, *m)) {  // if *first == *m\n\t\t\t\t\t// *first == *m, *first doesn't go in first part\n\t\t\t\t\t// manually guard downward moving j against i\n\t\t\t\t\tbool restart = false;\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tif (i == --j) {\n\t\t\t\t\t\t\t// *first == *m, *m <= all other elements\n\t\t\t\t\t\t\t// Parition instead into [first, i) == *first and *first < [i, end)\n\t\t\t\t\t\t\t++i;  // first + 1\n\t\t\t\t\t\t\tj = end;\n\t\t\t\t\t\t\tif (!pred(*first, *--j)) {  // we need a guard if *first == *(end-1)\n\t\t\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\t\t\tif (i == j) {\n\t\t\t\t\t\t\t\t\t\treturn end_orig;  // [first, end) all equivalent elements\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (pred(*first, *i)) {\n\t\t\t\t\t\t\t\t\t\titer_swap(i, j);\n\t\t\t\t\t\t\t\t\t\t++n_swaps;\n\t\t\t\t\t\t\t\t\t\t++i;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t++i;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// [first, i) == *first and *first < [j, end) and j == end - 1\n\t\t\t\t\t\t\tif (i == j) return end_orig;\n\n\t\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\t\twhile (!pred(*first, *i)) { ++i; }\n\t\t\t\t\t\t\t\twhile (pred(*first, *--j)) {}\n\t\t\t\t\t\t\t\tif (i >= j) break;\n\t\t\t\t\t\t\t\titer_swap(i, j);\n\t\t\t\t\t\t\t\t++n_swaps;\n\t\t\t\t\t\t\t\t++i;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// [first, i) == *first and *first < [i, end)\n\t\t\t\t\t\t\t// The first part is sorted,\n\t\t\t\t\t\t\tif (nth < i) return end_orig;\n\n\t\t\t\t\t\t\t// nth_element the second part\n\t\t\t\t\t\t\t// nth_element<C>(i, nth, end, comp);\n\t\t\t\t\t\t\trestart = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (pred(*j, *m)) {\n\t\t\t\t\t\t\titer_swap(i, j);\n\t\t\t\t\t\t\t++n_swaps;\n\t\t\t\t\t\t\tbreak;  // found guard for downward moving j, now use unguarded partition\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (restart) {\n\t\t\t\t\t\tfirst = i;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t++i;\n\t\t\t\t// j points beyond range to be tested, *lm1 is known to be <= *m\n\t\t\t\t// if not yet partitioned...\n\t\t\t\tif (i < j) {\n\t\t\t\t\t// known that *(i - 1) < *m\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t// m still guards upward moving i\n\t\t\t\t\t\twhile (pred(*i, *m)) { ++i; }\n\t\t\t\t\t\t// It is now known that a guard exists for downward moving j\n\t\t\t\t\t\twhile (!pred(*--j, *m)) {}\n\t\t\t\t\t\tif (i >= j) break;\n\t\t\t\t\t\titer_swap(i, j);\n\t\t\t\t\t\t++n_swaps;\n\t\t\t\t\t\t// It is known that m != j\n\t\t\t\t\t\t// If m just moved, follow it\n\t\t\t\t\t\tif (m == i) m = j;\n\t\t\t\t\t\t++i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// [first, i) < *m and *m <= [i, end)\n\t\t\t\tif (i != m && pred(*m, *i)) {\n\t\t\t\t\titer_swap(i, m);\n\t\t\t\t\t++n_swaps;\n\t\t\t\t}\n\t\t\t\t// [first, i) < *i and *i <= [i+1, end)\n\t\t\t\tif (nth == i) return end_orig;\n\n\t\t\t\tif (n_swaps == 0) {\n\t\t\t\t\t// We were given a perfectly partitioned sequence.  Coincidence?\n\t\t\t\t\tif (nth < i) {\n\t\t\t\t\t\t// Check for [first, i) already sorted\n\t\t\t\t\t\tj = m = first;\n\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\tif (++j == i) {\n\t\t\t\t\t\t\t\t// [first, i) sorted\n\t\t\t\t\t\t\t\treturn end_orig;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (pred(*j, *m)) {\n\t\t\t\t\t\t\t\t// not yet sorted, so sort\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tm = j;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Check for [i, end) already sorted\n\t\t\t\t\t\tj = m = i;\n\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\tif (++j == end) {\n\t\t\t\t\t\t\t\t// [i, end) sorted\n\t\t\t\t\t\t\t\treturn end_orig;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (pred(*j, *m)) {\n\t\t\t\t\t\t\t\t// not yet sorted, so sort\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tm = j;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// nth_element on range containing nth\n\t\t\t\tif (nth < i) {\n\t\t\t\t\t// nth_element<C>(first, nth, i, comp);\n\t\t\t\t\tend = i;\n\t\t\t\t} else {\n\t\t\t\t\t// nth_element<C>(i+1, nth, end, comp);\n\t\t\t\t\tfirst = ++i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn end_orig;\n\t\t}\n\n\t\ttemplate<random_access_range Rng, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<Rng>, Comp, Proj>\n\t\tconstexpr safe_iterator_t<Rng> operator()(Rng&& rng, iterator_t<Rng> nth,\n\t\t\tComp comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(rng), std::move(nth), end(rng),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\tprivate:\n\t\t// stable, 2-3 compares, 0-2 swaps\n\t\ttemplate<class I, class C, class P>\n\t\trequires sortable<I, C, P>\n\t\tstatic constexpr unsigned sort3(I x, I y, I z, C& comp, P& proj) {\n\t\t\tauto pred = [&](auto&& lhs, auto&& rhs) -> bool {\n\t\t\t\treturn __stl2::invoke(comp,\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(lhs)>(lhs)),\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(rhs)>(rhs)));\n\t\t\t};\n\n\t\t\tif (!pred(*y, *x)) {      // if x <= y\n\t\t\t\tif (!pred(*z, *y)) {  // if y <= z\n\t\t\t\t\treturn 0;         // x <= y && y <= z\n\t\t\t\t}\n\t\t\t\t                      // x <= y && y > z\n\t\t\t\titer_swap(y, z);      // x <= z && y < z\n\t\t\t\tif (pred(*y, *x)) {   // if x > y\n\t\t\t\t\titer_swap(x, y);  // x < y && y <= z\n\t\t\t\t\treturn 2;\n\t\t\t\t}\n\t\t\t\treturn 1;             // x <= y && y < z\n\t\t\t}\n\t\t\tif (pred(*z, *y)) {       // x > y, if y > z\n\t\t\t\titer_swap(x, z);      // x < y && y < z\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\titer_swap(x, y);          // x > y && y <= z\n\t\t\t                          // x < y && x <= z\n\t\t\tif (pred(*z, *y)) {       // if y > z\n\t\t\t\titer_swap(y, z);      // x <= y && y < z\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\treturn 1;\n\t\t}\n\n\t\ttemplate<bidirectional_iterator I, class C, class P>\n\t\trequires sortable<I, C, P>\n\t\tstatic constexpr void selection_sort(I begin, I end, C &comp, P &proj) {\n\t\t\tSTL2_EXPECT(begin != end);\n\t\t\tfor (I lm1 = prev(end); begin != lm1; ++begin) {\n\t\t\t\tI i = min_element(begin, end, __stl2::ref(comp),\n\t\t\t\t\t__stl2::ref(proj));\n\t\t\t\tif (i != begin) {\n\t\t\t\t\titer_swap(begin, i);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __nth_element_fn nth_element{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/partial_sort.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_PARTIAL_SORT_HPP\n#define STL2_DETAIL_ALGORITHM_PARTIAL_SORT_HPP\n\n#include <stl2/detail/algorithm/heap_sift.hpp>\n#include <stl2/detail/algorithm/make_heap.hpp>\n#include <stl2/detail/algorithm/sort_heap.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// partial_sort [partial.sort]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __partial_sort_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr I operator()(I first, I middle, S last, Comp comp = {},\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\tmake_heap(first, middle, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\tconst auto len = distance(first, middle);\n\t\t\tI i = middle;\n\t\t\tfor(; i != last; ++i) {\n\t\t\t\tif(__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj, *i),\n\t\t\t\t\t\t__stl2::invoke(proj, *first))) {\n\t\t\t\t\titer_swap(i, first);\n\t\t\t\t\tdetail::sift_down_n(first, len, first, __stl2::ref(comp),\n\t\t\t\t\t\t__stl2::ref(proj));\n\t\t\t\t}\n\t\t\t}\n\t\t\tsort_heap(first, middle, __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t\treturn i;\n\t\t}\n\n\t\ttemplate<random_access_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tconstexpr safe_iterator_t<R> operator()(R&& r, iterator_t<R> middle,\n\t\t\tComp comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r), std::move(middle), end(r),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __partial_sort_fn partial_sort{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/partial_sort_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_PARTIAL_SORT_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_PARTIAL_SORT_COPY_HPP\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/heap_sift.hpp>\n#include <stl2/detail/algorithm/make_heap.hpp>\n#include <stl2/detail/algorithm/sort_heap.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// partial_sort_copy [partial.sort.copy]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __partial_sort_copy_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, random_access_iterator I2,\n\t\t\tsentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity,\n\t\t\tindirect_strict_weak_order<projected<I1, Proj1>,\n\t\t\t\tprojected<I2, Proj2>> Comp = less>\n\t\trequires indirectly_copyable<I1, I2> && sortable<I2, Comp, Proj2>\n\t\tconstexpr I2\n\t\toperator()(I1 first, S1 last, I2 result_first, S2 result_last,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tauto r = result_first;\n\t\t\tif(r != result_last) {\n\t\t\t\tauto cresult = ext::copy(std::move(first), last, std::move(r),\n\t\t\t\t\tresult_last);\n\t\t\t\tfirst = std::move(cresult.in);\n\t\t\t\tr = std::move(cresult.out);\n\n\t\t\t\tmake_heap(result_first, r, __stl2::ref(comp), __stl2::ref(proj2));\n\t\t\t\tconst auto len = distance(result_first, r);\n\t\t\t\tfor(; first != last; ++first) {\n\t\t\t\t\titer_reference_t<I1>&& x = *first;\n\t\t\t\t\tif(__stl2::invoke(comp,\n\t\t\t\t\t\t\t__stl2::invoke(proj1, x),\n\t\t\t\t\t\t\t__stl2::invoke(proj2, *result_first))) {\n\t\t\t\t\t\t*result_first = std::forward<iter_reference_t<I1>>(x);\n\t\t\t\t\t\tdetail::sift_down_n(result_first, len, result_first,\n\t\t\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsort_heap(result_first, r, __stl2::ref(comp),\n\t\t\t\t\t__stl2::ref(proj2));\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\n\t\ttemplate<input_range R1, random_access_range R2, class Proj1 = identity,\n\t\t\tclass Proj2 = identity,\n\t\t\tindirect_strict_weak_order<projected<iterator_t<R1>, Proj1>,\n\t\t\t\tprojected<iterator_t<R2>, Proj2>> Comp = less>\n\t\trequires indirectly_copyable<iterator_t<R1>, iterator_t<R2>> &&\n\t\t\tsortable<iterator_t<R2>, Comp, Proj2>\n\t\tconstexpr safe_iterator_t<R2> operator()(R1&& r, R2&& result_r,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r), end(r), begin(result_r), end(result_r),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __partial_sort_copy_fn partial_sort_copy{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/partition.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===-------------------------- algorithm ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_PARTITION_HPP\n#define STL2_DETAIL_ALGORITHM_PARTITION_HPP\n\n#include <stl2/detail/algorithm/find_if_not.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// partition [alg.partitions]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __partition_fn : private __niebloid {\n\t\ttemplate<permutable I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr I operator()(I first, S last_, Pred pred, Proj proj = {}) const {\n\t\t\tif constexpr (bidirectional_iterator<I>) {\n\t\t\t\tauto last = next(first, std::move(last_));\n\n\t\t\t\tfor (; first != last; ++first) {\n\t\t\t\t\tif (!__stl2::invoke(pred, __stl2::invoke(proj, *first))) {\n\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\tif (--last == first) {\n\t\t\t\t\t\t\t\treturn first;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *last))) {\n\t\t\t\t\t\t\t\titer_swap(first, last);\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}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfirst = find_if_not(std::move(first), last_, __stl2::ref(pred),\n\t\t\t\t\t__stl2::ref(proj));\n\t\t\t\tif (first != last_) {\n\t\t\t\t\tfor (auto m = first; ++m != last_;) {\n\t\t\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *m))) {\n\t\t\t\t\t\t\titer_swap(first, m);\n\t\t\t\t\t\t\t++first;\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\treturn first;\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\trequires permutable<iterator_t<R>>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __partition_fn partition{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/partition_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_PARTITION_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_PARTITION_COPY_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// partition_copy [alg.partitions]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O1, class O2>\n\tusing partition_copy_result = __in_out_out_result<I, O1, O2>;\n\n\tstruct __partition_copy_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O1,\n\t\t\tweakly_incrementable O2, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\trequires indirectly_copyable<I, O1> && indirectly_copyable<I, O2>\n\t\tconstexpr partition_copy_result<I, O1, O2>\n\t\toperator()(I first, S last, O1 out_true, O2 out_false, Pred pred,\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, v))) {\n\t\t\t\t\t*out_true  = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t\t++out_true;\n\t\t\t\t} else {\n\t\t\t\t\t*out_false = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t\t++out_false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(out_true), std::move(out_false)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O1, weakly_incrementable O2,\n\t\t\tclass Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\trequires indirectly_copyable<iterator_t<R>, O1> &&\n\t\t\tindirectly_copyable<iterator_t<R>, O2>\n\t\tconstexpr partition_copy_result<safe_iterator_t<R>, O1, O2>\n\t\toperator()(R&& r, O1 out_true, O2 out_false, Pred pred,\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r), end(r),\n\t\t\t\tstd::move(out_true), std::move(out_false),\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __partition_copy_fn partition_copy{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/partition_point.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===-------------------------- algorithm ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_PARTITION_POINT_HPP\n#define STL2_DETAIL_ALGORITHM_PARTITION_POINT_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// partition_point [alg.partitions]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\tstruct __partition_point_n_fn {\n\t\t\ttemplate<forward_iterator I, class Proj = identity,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\tconstexpr I operator()(I first, iter_difference_t<I> n, Pred pred,\n\t\t\t\tProj proj = {}) const\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(0 <= n);\n\t\t\t\twhile (n != 0) {\n\t\t\t\t\tauto const half = n / 2;\n\t\t\t\t\tauto middle = next(ext::uncounted(first), half);\n\t\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *middle))) {\n\t\t\t\t\t\tfirst = ext::recounted(first, std::move(++middle), half + 1);\n\t\t\t\t\t\tn -= half + 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tn = half;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn first;\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __partition_point_n_fn partition_point_n{};\n\t}\n\n\tstruct __partition_point_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr I operator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\tauto n = distance(first, std::move(last));\n\t\t\t\treturn ext::partition_point_n(std::move(first), n,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\t// Probe exponentially for either end-of-range or an iterator\n\t\t\t\t// that is past the partition point (i.e., does not satisfy pred).\n\t\t\t\tauto n = iter_difference_t<I>{1};\n\t\t\t\twhile (true) {\n\t\t\t\t\tauto m = first;\n\t\t\t\t\tauto d = advance(m, n, last);\n\t\t\t\t\tif (m == last || !__stl2::invoke(pred, __stl2::invoke(proj, *m))) {\n\t\t\t\t\t\tn -= d;\n\t\t\t\t\t\treturn ext::partition_point_n(std::move(first), n,\n\t\t\t\t\t\t\tstd::move(pred), std::move(proj));\n\t\t\t\t\t}\n\t\t\t\t\tfirst = std::move(m);\n\t\t\t\t\tn *= 2;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Pred pred, Proj proj = {}) const {\n\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\treturn ext::partition_point_n(begin(r), distance(r),\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(pred),\n\t\t\t\t\t__stl2::ref(proj));\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __partition_point_fn partition_point{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/pop_heap.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_POP_HEAP_HPP\n#define STL2_DETAIL_ALGORITHM_POP_HEAP_HPP\n\n#include <stl2/detail/algorithm/heap_sift.hpp>\n#include <stl2/detail/range/dangling.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// pop_heap [pop.heap]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct __pop_heap_n_fn {\n\t\t\ttemplate<random_access_iterator I, class Proj, class Comp>\n\t\t\trequires sortable<I, Comp, Proj>\n\t\t\tconstexpr void\n\t\t\toperator()(I first, iter_difference_t<I> n, Comp comp, Proj proj) const {\n\t\t\t\tif (n > 1) {\n\t\t\t\t\titer_swap(first, first + (n - 1));\n\t\t\t\t\tsift_down_n(first, n - 1, first, __stl2::ref(comp),\n\t\t\t\t\t\t__stl2::ref(proj));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __pop_heap_n_fn pop_heap_n{};\n\t}\n\n\tstruct __pop_heap_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(first, std::move(last));\n\t\t\tdetail::pop_heap_n(first, n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn first + n;\n\t\t}\n\n\t\ttemplate<random_access_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(r);\n\t\t\tdetail::pop_heap_n(begin(r), n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn begin(r) + n;\n\t\t}\n\t};\n\n\tinline constexpr __pop_heap_fn pop_heap{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/prev_permutation.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===-------------------------- algorithm ---------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_PREV_PERMUTATION_HPP\n#define STL2_DETAIL_ALGORITHM_PREV_PERMUTATION_HPP\n\n#include <stl2/detail/algorithm/reverse.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// prev_permutation [alg.permutation.generators]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __prev_permutation_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr bool\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif (first == last) return false;\n\n\t\t\tI end = next(first, std::move(last));\n\t\t\tI i = end;\n\t\t\tif (first == --i) return false;\n\n\t\t\tauto pred = [&](auto&& lhs, auto&& rhs) -> bool {\n\t\t\t\treturn __stl2::invoke(comp,\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(lhs)>(lhs)),\n\t\t\t\t\t__stl2::invoke(proj, static_cast<decltype(rhs)>(rhs)));\n\t\t\t};\n\n\t\t\twhile (true) {\n\t\t\t\tI ip1 = i;\n\t\t\t\tif (pred(*ip1, *--i)) {\n\t\t\t\t\tI j = end;\n\t\t\t\t\twhile (!pred(*--j, *i)) {\n\t\t\t\t\t\t;\n\t\t\t\t\t}\n\t\t\t\t\titer_swap(i, j);\n\t\t\t\t\treverse(ip1, end);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (i == first) {\n\t\t\t\t\treverse(first, end);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<bidirectional_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tconstexpr bool\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __prev_permutation_fn prev_permutation{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/push_heap.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_PUSH_HEAP_HPP\n#define STL2_DETAIL_ALGORITHM_PUSH_HEAP_HPP\n\n#include <stl2/detail/algorithm/heap_sift.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// push_heap [push.heap]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __push_heap_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(first, std::move(last));\n\t\t\tdetail::sift_up_n(first, n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn first + n;\n\t\t}\n\n\t\ttemplate<random_access_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(r);\n\t\t\tdetail::sift_up_n(begin(r), n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn begin(r) + n;\n\t\t}\n\t};\n\n\tinline constexpr __push_heap_fn push_heap{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/remove.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REMOVE_HPP\n#define STL2_DETAIL_ALGORITHM_REMOVE_HPP\n\n#include <stl2/detail/algorithm/find.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// remove [alg.remove]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __remove_fn : private __niebloid {\n\t\ttemplate<permutable I, sentinel_for<I> S, class T, class Proj = identity>\n\t\trequires indirect_relation<equal_to, projected<I, Proj>, const T*>\n\t\tconstexpr I\n\t\toperator()(I first, S last, const T& value, Proj proj = {}) const {\n\t\t\tfirst = find(std::move(first), last, value, __stl2::ref(proj));\n\t\t\tif (first != last) {\n\t\t\t\tfor (auto m = next(first); m != last; ++m) {\n\t\t\t\t\tif (__stl2::invoke(proj, *m) != value) {\n\t\t\t\t\t\t*first = iter_move(m);\n\t\t\t\t\t\t++first;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<forward_range Rng, class T, class Proj = identity>\n\t\trequires permutable<iterator_t<Rng>> &&\n\t\t\tindirect_relation<equal_to, projected<iterator_t<Rng>, Proj>, const T*>\n\t\tconstexpr safe_iterator_t<Rng>\n\t\toperator()(Rng&& rng, const T& value, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(rng), end(rng), value, __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __remove_fn remove{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/remove_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REMOVE_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_REMOVE_COPY_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// remove_copy [alg.remove]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing remove_copy_result = __in_out_result<I, O>;\n\n\tstruct __remove_copy_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class T,\n\t\t\tclass Proj = identity>\n\t\trequires indirectly_copyable<I, O> &&\n\t\t\tindirect_relation<equal_to, projected<I, Proj>, const T*>\n\t\tconstexpr remove_copy_result<I, O>\n\t\toperator()(I first, S last, O result, const T& value, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\tif (__stl2::invoke(proj, v) != value) {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t\t++result;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O, class T, class Proj = identity>\n\t\trequires indirectly_copyable<iterator_t<R>, O> &&\n\t\t\tindirect_relation<equal_to, projected<iterator_t<R>, Proj>, const T*>\n\t\tconstexpr remove_copy_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result, const T& value, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(result), value, __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __remove_copy_fn remove_copy{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/remove_copy_if.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REMOVE_COPY_IF_HPP\n#define STL2_DETAIL_ALGORITHM_REMOVE_COPY_IF_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// remove_copy_if [alg.remove]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing remove_copy_if_result = __in_out_result<I, O>;\n\n\tstruct __remove_copy_if_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O,\n\t\t\tclass Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>\n\t\trequires indirectly_copyable<I, O>\n\t\tconstexpr remove_copy_if_result<I, O>\n\t\toperator()(I first, S last, O result, Pred pred, Proj proj = {}) const {\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\tif (!__stl2::invoke(pred, __stl2::invoke(proj, v))) {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t\t++result;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\trequires indirectly_copyable<iterator_t<R>, O>\n\t\tconstexpr remove_copy_if_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(result),\n\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __remove_copy_if_fn remove_copy_if{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/remove_if.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REMOVE_IF_HPP\n#define STL2_DETAIL_ALGORITHM_REMOVE_IF_HPP\n\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// remove_if [alg.remove]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __remove_if_fn : private __niebloid {\n\t\ttemplate<permutable I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tfirst = find_if(std::move(first), last, __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj));\n\t\t\tif (first != last) {\n\t\t\t\tfor (auto m = next(first); m != last; ++m) {\n\t\t\t\t\tif (!__stl2::invoke(pred, __stl2::invoke(proj, *m))) {\n\t\t\t\t\t\t*first = iter_move(m);\n\t\t\t\t\t\t++first;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<forward_range Rng, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<Rng>, Proj>> Pred>\n\t\trequires permutable<iterator_t<Rng>>\n\t\tconstexpr safe_iterator_t<Rng>\n\t\toperator()(Rng&& rng, Pred pred, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(rng), end(rng), __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __remove_if_fn remove_if{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/replace.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REPLACE_HPP\n#define STL2_DETAIL_ALGORITHM_REPLACE_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// replace [alg.replace]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __replace_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class T1, class T2,\n\t\t\tclass Proj = identity>\n\t\trequires writable<I, const T2&> &&\n\t\t\tindirect_relation<equal_to, projected<I, Proj>, const T1*>\n\t\tconstexpr I operator()(I first, S last, const T1& old_value,\n\t\t\tconst T2& new_value, Proj proj = {}) const\n\t\t{\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(proj, *first) == old_value) {\n\t\t\t\t\t*first = new_value;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<input_range R, class T1, class T2, class Proj = identity>\n\t\trequires writable<iterator_t<R>, const T2&> &&\n\t\t\tindirect_relation<equal_to, projected<iterator_t<R>, Proj>, const T1*>\n\t\tconstexpr safe_iterator_t<R> operator()(R&& r, const T1& old_value,\n\t\t\tconst T2& new_value, Proj proj = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r), end(r), old_value, new_value,\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __replace_fn replace{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/replace_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REPLACE_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_REPLACE_COPY_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// replace_copy [alg.replace]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing replace_copy_result = __in_out_result<I, O>;\n\n\tstruct __replace_copy_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class T1, class T2,\n\t\t\toutput_iterator<const T2&> O, class Proj = identity>\n\t\trequires indirectly_copyable<I, O> &&\n\t\t\tindirect_relation<equal_to, projected<I, Proj>, const T1*>\n\t\tconstexpr replace_copy_result<I, O>\n\t\toperator()(I first, S last, O result, const T1& old_value,\n\t\t\tconst T2& new_value, Proj proj = {}) const\n\t\t{\n\t\t\tfor (; first != last; (void) ++first, (void) ++result) {\n\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\tif (__stl2::invoke(proj, v) == old_value) {\n\t\t\t\t\t*result = new_value;\n\t\t\t\t} else {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, class T1, class T2, output_iterator<const T2&> O,\n\t\t\tclass Proj = identity>\n\t\trequires indirectly_copyable<iterator_t<R>, O> &&\n\t\t\tindirect_relation<equal_to, projected<iterator_t<R>, Proj>, const T1*>\n\t\tconstexpr replace_copy_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result, const T1& old_value, const T2& new_value,\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r), end(r), std::move(result),\n\t\t\t\told_value, new_value, __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __replace_copy_fn replace_copy{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/replace_copy_if.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REPLACE_COPY_IF_HPP\n#define STL2_DETAIL_ALGORITHM_REPLACE_COPY_IF_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// replace_copy_if [alg.replace]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing replace_copy_if_result = __in_out_result<I, O>;\n\n\tstruct __replace_copy_if_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class T,\n\t\t\toutput_iterator<const T&> O, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\trequires indirectly_copyable<I, O>\n\t\tconstexpr replace_copy_if_result<I, O>\n\t\toperator()(I first, S last, O result, Pred pred,\n\t\t\tconst T& new_value, Proj proj = {}) const\n\t\t{\n\t\t\tfor (; first != last; (void) ++first, (void) ++result) {\n\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, v))) {\n\t\t\t\t\t*result = new_value;\n\t\t\t\t} else {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, class T, output_iterator<const T&> O,\n\t\t\tclass Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\trequires indirectly_copyable<iterator_t<R>, O>\n\t\tconstexpr replace_copy_if_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result, Pred pred, const T& new_value,\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r), end(r), std::move(result),\n\t\t\t\t__stl2::ref(pred), new_value, __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __replace_copy_if_fn replace_copy_if{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/replace_if.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REPLACE_IF_HPP\n#define STL2_DETAIL_ALGORITHM_REPLACE_IF_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// replace_if [alg.replace]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __replace_if_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, class T, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\trequires writable<I, const T&>\n\t\tconstexpr I operator()(I first, S last, Pred pred, const T& new_value,\n\t\t\tProj proj = {}) const\n\t\t{\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *first))) {\n\t\t\t\t\t*first = new_value;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<input_range R, class T, class Proj = identity,\n\t\t\tindirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>\n\t\trequires writable<iterator_t<R>, const T&>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Pred pred, const T& new_value, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(pred), new_value,\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __replace_if_fn replace_if{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/results.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_RESULTS_HPP\n#define STL2_DETAIL_ALGORITHM_RESULTS_HPP\n\n#include <utility>\n#include <stl2/detail/concepts/core.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tstruct __in_out_result {\n\t\tSTL2_NO_UNIQUE_ADDRESS I in;\n\t\tSTL2_NO_UNIQUE_ADDRESS O out;\n\n\t\t// Extension: the dangling story actually works.\n\t\ttemplate<class I2, class O2>\n\t\trequires convertible_to<const I&, I2> && convertible_to<const O&, O2>\n\t\toperator __in_out_result<I2, O2>() const& {\n\t\t\treturn {in, out};\n\t\t}\n\t\ttemplate<class I2, class O2>\n\t\trequires convertible_to<I, I2> && convertible_to<O, O2>\n\t\toperator __in_out_result<I2, O2>() && {\n\t\t\treturn {std::move(in), std::move(out)};\n\t\t}\n\t};\n\n\ttemplate<class I1, class I2>\n\tstruct __in_in_result {\n\t\tSTL2_NO_UNIQUE_ADDRESS I1 in1;\n\t\tSTL2_NO_UNIQUE_ADDRESS I2 in2;\n\n\t\t// Extension: the dangling story actually works.\n\t\ttemplate<class II1, class II2>\n\t\trequires convertible_to<const I1&, II1> && convertible_to<const I2&, II2>\n\t\toperator __in_in_result<II1, II2>() const& {\n\t\t\treturn {in1, in2};\n\t\t}\n\t\ttemplate<class II1, class II2>\n\t\trequires convertible_to<I1, II1> && convertible_to<I2, II2>\n\t\toperator __in_in_result<II1, II2>() && {\n\t\t\treturn {std::move(in1), std::move(in2)};\n\t\t}\n\t};\n\n\ttemplate<class I1, class I2, class O>\n\tstruct __in_in_out_result {\n\t\tSTL2_NO_UNIQUE_ADDRESS I1 in1;\n\t\tSTL2_NO_UNIQUE_ADDRESS I2 in2;\n\t\tSTL2_NO_UNIQUE_ADDRESS O out;\n\n\t\t// Extension: the dangling story actually works.\n\t\ttemplate<class II1, class II2, class OO>\n\t\trequires convertible_to<const I1&, II1> &&\n\t\t\tconvertible_to<const I2&, II2> && convertible_to<const O&, OO>\n\t\toperator __in_in_out_result<II1, II2, OO>() const& {\n\t\t\treturn {in1, in2, out};\n\t\t}\n\t\ttemplate<class II1, class II2, class OO>\n\t\trequires convertible_to<I1, II1> &&\n\t\t\tconvertible_to<I2, II2> && convertible_to<O, OO>\n\t\toperator __in_in_out_result<II1, II2, OO>() && {\n\t\t\treturn {std::move(in1), std::move(in2), std::move(out)};\n\t\t}\n\t};\n\n\ttemplate<class I, class O1, class O2>\n\tstruct __in_out_out_result {\n\t\tSTL2_NO_UNIQUE_ADDRESS I in;\n\t\tSTL2_NO_UNIQUE_ADDRESS O1 out1;\n\t\tSTL2_NO_UNIQUE_ADDRESS O2 out2;\n\n\t\t// Extension: the dangling story actually works.\n\t\ttemplate<class II, class OO1, class OO2>\n\t\trequires convertible_to<const I&, II> &&\n\t\t\tconvertible_to<const O1&, OO1> && convertible_to<const O2&, OO2>\n\t\toperator __in_out_out_result<II, OO1, OO2>() const& {\n\t\t\treturn {in, out1, out2};\n\t\t}\n\t\ttemplate<class II, class OO1, class OO2>\n\t\trequires convertible_to<I, II> &&\n\t\t\tconvertible_to<O1, OO1> && convertible_to<O2, OO2>\n\t\toperator __in_out_out_result<II, OO1, OO2>() && {\n\t\t\treturn {std::move(in), std::move(out1), std::move(out2)};\n\t\t}\n\t};\n\n\ttemplate<class I, class F>\n\tstruct __in_fun_result {\n\t\tSTL2_NO_UNIQUE_ADDRESS I in;\n\t\tSTL2_NO_UNIQUE_ADDRESS F fun;\n\n\t\t// Extension: the dangling story actually works.\n\t\ttemplate<class I2, class F2>\n\t\trequires convertible_to<const I&, I2> && convertible_to<const F&, F2>\n\t\toperator __in_fun_result<I2, F2>() const& {\n\t\t\treturn {in, fun};\n\t\t}\n\t\ttemplate<class I2, class F2>\n\t\trequires convertible_to<I, I2> && convertible_to<F, F2>\n\t\toperator __in_fun_result<I2, F2>() && {\n\t\t\treturn {std::move(in), std::move(fun)};\n\t\t}\n\t};\n\n\ttemplate<class T>\n\tstruct minmax_result {\n\t\tSTL2_NO_UNIQUE_ADDRESS T min;\n\t\tSTL2_NO_UNIQUE_ADDRESS T max;\n\n\t\t// Extension: the dangling story actually works.\n\t\ttemplate<class T2>\n\t\trequires convertible_to<const T&, T2>\n\t\toperator minmax_result<T2>() const& {\n\t\t\treturn {min, max};\n\t\t}\n\t\ttemplate<class T2>\n\t\trequires convertible_to<T, T2>\n\t\toperator minmax_result<T2>() && {\n\t\t\treturn {std::move(min), std::move(max)};\n\t\t}\n\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/reverse.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REVERSE_HPP\n#define STL2_DETAIL_ALGORITHM_REVERSE_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// reverse [alg.reverse]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __reverse_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I, sentinel_for<I> S>\n\t\trequires permutable<I>\n\t\tconstexpr I operator()(I first, S last) const {\n\t\t\tauto bound = next(first, static_cast<S&&>(last));\n\t\t\tif constexpr (random_access_iterator<I>) {\n\t\t\t\tif (first != bound) {\n\t\t\t\t\tfor (auto m = bound; first < --m; ++first) {\n\t\t\t\t\t\titer_swap(first, m);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (auto m = bound; bool(first != m) && bool(first != --m); ++first) {\n\t\t\t\t\titer_swap(first, m);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn bound;\n\t\t}\n\n\t\ttemplate<bidirectional_range R>\n\t\trequires permutable<iterator_t<R>>\n\t\tconstexpr safe_iterator_t<R> operator()(R&& r) const {\n\t\t\treturn (*this)(begin(r), end(r));\n\t\t}\n\t};\n\n\tinline constexpr __reverse_fn reverse{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/reverse_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_REVERSE_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_REVERSE_COPY_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// reverse_copy [alg.reverse]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing reverse_copy_result = __in_out_result<I, O>;\n\n\tstruct __reverse_copy_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I, sentinel_for<I> S, weakly_incrementable O>\n\t\trequires indirectly_copyable<I, O>\n\t\tconstexpr reverse_copy_result<I, O>\n\t\toperator()(I first, S last, O result) const {\n\t\t\tauto bound = next(first, std::move(last));\n\t\t\tfor (auto m = bound; m != first; ++result) {\n\t\t\t\t*result = *--m;\n\t\t\t}\n\t\t\treturn {std::move(bound), std::move(result)};\n\t\t}\n\n\t\ttemplate<bidirectional_range R, weakly_incrementable O>\n\t\trequires indirectly_copyable<iterator_t<R>, O>\n\t\tconstexpr reverse_copy_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(result));\n\t\t}\n\t};\n\n\tinline constexpr __reverse_copy_fn reverse_copy{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/rotate.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_ROTATE_HPP\n#define STL2_DETAIL_ALGORITHM_ROTATE_HPP\n\n#include <stl2/detail/algorithm/move.hpp>\n#include <stl2/detail/algorithm/move_backward.hpp>\n#include <stl2/detail/algorithm/swap_ranges.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/view/subrange.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// rotate [alg.rotate]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __sean_parent_fn : private __niebloid {\n\t\ttemplate<permutable I, sentinel_for<I> S>\n\t\tconstexpr subrange<I> operator()(I first, I middle, S last) const {\n\t\t\tif (first == middle) {\n\t\t\t\tfirst = next(std::move(first), std::move(last));\n\t\t\t\treturn {first, std::move(first)};\n\t\t\t}\n\t\t\tif (middle == last) {\n\t\t\t\treturn {std::move(first), std::move(middle)};\n\t\t\t}\n\t\t\tif constexpr (std::is_trivially_move_assignable_v<iter_value_t<I>>) {\n\t\t\t\tif (next(first) == middle) {\n\t\t\t\t\treturn __rotate_left(std::move(first), std::move(last));\n\t\t\t\t}\n\t\t\t\tif constexpr (same_as<I, S>) {\n\t\t\t\t\tif constexpr (bidirectional_iterator<I>) {\n\t\t\t\t\t\tif (next(middle) == last) {\n\t\t\t\t\t\t\treturn __rotate_right(std::move(first), std\n\t\t\t\t\t\t\t\t::move(last));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif constexpr (random_access_iterator<I>) {\n\t\t\t\t\t\treturn __rotate_gcd(std::move(first), std::move(middle),\n\t\t\t\t\t\t\tstd::move(last));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn __rotate_forward(std::move(first), std::move(middle),\n\t\t\t\tstd::move(last));\n\t\t}\n\n\t\ttemplate<forward_range R>\n\t\trequires permutable<iterator_t<R>>\n\t\tconstexpr safe_subrange_t<R>\n\t\toperator()(R&& r, iterator_t<R> middle) const {\n\t\t\treturn (*this)(begin(r), std::move(middle), end(r));\n\t\t}\n\tprivate:\n\t\ttemplate<permutable I, sentinel_for<I> S>\n\t\tstatic constexpr subrange<I> __rotate_left(I first, S sent) {\n\t\t\tSTL2_EXPECT(first != sent);\n\t\t\titer_value_t<I> tmp = iter_move(first);\n\t\t\tauto [last, last_but_one] = move(next(first), sent, first);\n\t\t\t*last_but_one = std::move(tmp);\n\t\t\treturn {std::move(last_but_one), std::move(last)};\n\t\t}\n\n\t\ttemplate<permutable I>\n\t\trequires bidirectional_iterator<I>\n\t\tstatic constexpr subrange<I> __rotate_right(I first, I last) {\n\t\t\tSTL2_EXPECT(first != last);\n\t\t\tI last_but_one = prev(last);\n\t\t\titer_value_t<I> tmp = iter_move(last_but_one);\n\t\t\tI fp1 = move_backward(first, std::move(last_but_one), last).out;\n\t\t\t*first = std::move(tmp);\n\t\t\treturn {std::move(fp1), std::move(last)};\n\t\t}\n\n\t\ttemplate<permutable I, sentinel_for<I> S>\n\t\tstatic constexpr subrange<I> __rotate_forward(I first, I middle, S last) {\n\t\t\tSTL2_EXPECT(first != middle);\n\t\t\tSTL2_EXPECT(middle != last);\n\t\t\tI i = middle;\n\t\t\twhile (true) {\n\t\t\t\titer_swap(first, i);\n\t\t\t\t++first;\n\t\t\t\tif (++i == last) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (first == middle) {\n\t\t\t\t\tmiddle = i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tI r = first;\n\t\t\tif (first != middle) {\n\t\t\t\tI j = middle;\n\t\t\t\twhile (true) {\n\t\t\t\t\titer_swap(first, j);\n\t\t\t\t\t++first;\n\t\t\t\t\tif (++j == last) {\n\t\t\t\t\t\tif (first == middle) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tj = middle;\n\t\t\t\t\t} else if(first == middle) {\n\t\t\t\t\t\tmiddle = j;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {std::move(r), std::move(i)};\n\t\t}\n\n\t\ttemplate<integral I>\n\t\tstatic constexpr I __gcd(I x, I y) {\n\t\t\tdo {\n\t\t\t\tauto t = x % y;\n\t\t\t\tx = y;\n\t\t\t\ty = t;\n\t\t\t} while(y);\n\t\t\treturn x;\n\t\t}\n\n\t\ttemplate<permutable I>\n\t\trequires random_access_iterator<I>\n\t\tstatic constexpr subrange<I> __rotate_gcd(I first, I middle, I last) {\n\t\t\tusing D = iter_difference_t<I>;\n\t\t\tD const m1 = middle - first;\n\t\t\tD const m2 = last - middle;\n\t\t\tif (m1 == m2) {\n\t\t\t\t__swap_ranges3(first, middle, middle);\n\t\t\t\treturn {std::move(middle), std::move(last)};\n\t\t\t}\n\t\t\tauto const g = __gcd(m1, m2);\n\t\t\tfor (I p = first + g; p != first;) {\n\t\t\t\titer_value_t<I> t = iter_move(--p);\n\t\t\t\tI p1 = p;\n\t\t\t\tI p2 = p1 + m1;\n\t\t\t\tdo {\n\t\t\t\t\t*p1 = iter_move(p2);\n\t\t\t\t\tp1 = p2;\n\t\t\t\t\tD const d = last - p2;\n\t\t\t\t\tif (m1 < d) {\n\t\t\t\t\t\tp2 += m1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp2 = first + D{m1 - d};\n\t\t\t\t\t}\n\t\t\t\t} while(p2 != p);\n\t\t\t\t*p1 = std::move(t);\n\t\t\t}\n\t\t\tfirst += m2;\n\t\t\treturn {std::move(first), std::move(last)};\n\t\t}\n\t};\n\n\tinline constexpr __sean_parent_fn rotate{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/rotate_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_ROTATE_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_ROTATE_COPY_HPP\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// rotate_copy [alg.rotate]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing rotate_copy_result = __in_out_result<I, O>;\n\n\tstruct __rotate_copy_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, weakly_incrementable O>\n\t\trequires indirectly_copyable<I, O>\n\t\tconstexpr rotate_copy_result<I, O>\n\t\toperator()(I first, I middle, S last, O result) const {\n\t\t\tauto res = copy(middle, std::move(last), std::move(result));\n\t\t\tres.out = copy(std::move(first), std::move(middle),\n\t\t\t\tstd::move(res.out)).out;\n\t\t\treturn res;\n\t\t}\n\n\t\ttemplate<forward_range R, weakly_incrementable O>\n\t\trequires indirectly_copyable<iterator_t<R>, O>\n\t\tconstexpr rotate_copy_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, iterator_t<R> middle, O result) const {\n\t\t\treturn (*this)(begin(r), std::move(middle), end(r),\n\t\t\t\tstd::move(result));\n\t\t}\n\t};\n\n\tinline constexpr __rotate_copy_fn rotate_copy{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/sample.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef RANGES_V3_ALGORITHM_SAMPLE_HPP\n#define RANGES_V3_ALGORITHM_SAMPLE_HPP\n\n#include <stl2/random.hpp>\n#include <stl2/detail/randutils.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n////////////////////////////////////////////////////////////////////////////////\n// sample [Extension]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<class I, class O>\n\t\tusing sample_result = __in_out_result<I, O>;\n\n\t\ttemplate<class I, class S, class O, class Gen>\n\t\tMETA_CONCEPT __sample_constraint =\n\t\t\tinput_iterator<I> && sentinel_for<S, I> && weakly_incrementable<O> &&\n\t\t\tindirectly_copyable<I, O> &&\n\t\t\tuniform_random_bit_generator<std::remove_reference_t<Gen>>;\n\n\t\tstruct __sample_fn : private __niebloid {\n\t\t\ttemplate<class I, class S, class O,\n\t\t\t\tclass Gen = detail::default_random_engine&>\n\t\t\trequires __sample_constraint<I, S, O, Gen> &&\n\t\t\t\t(forward_iterator<I> || sized_sentinel_for<S, I> ||\n\t\t\t\t random_access_iterator<O>)\n\t\t\tconstexpr sample_result<I, O>\n\t\t\toperator()(I first, S last, O o, iter_difference_t<I> n,\n\t\t\t\tGen&& gen = detail::get_random_engine()) const\n\t\t\t{\n\t\t\t\tif constexpr (forward_iterator<I> || sized_sentinel_for<S, I>) {\n\t\t\t\t\tconst auto k = distance(first, last);\n\t\t\t\t\treturn sized_impl(std::move(first), std::move(last),\n\t\t\t\t\t\tk, std::move(o), n, gen);\n\t\t\t\t} else {\n\t\t\t\t\tif (n > 0) {\n\t\t\t\t\t\tfor (iter_difference_t<I> i = 0;\n\t\t\t\t\t\t     i < n && bool(first != last);\n\t\t\t\t\t\t     (void) ++i, (void) ++first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\to[i] = *first;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (first != last) {\n\t\t\t\t\t\t\tstd::uniform_int_distribution<iter_difference_t<I>> dist;\n\t\t\t\t\t\t\tusing param_t = typename decltype(dist)::param_type;\n\t\t\t\t\t\t\tfor (auto pop_size = n; first != last;\n\t\t\t\t\t\t\t     (void) ++first, ++pop_size)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tconst auto i = dist(gen, param_t{0, pop_size});\n\t\t\t\t\t\t\t\tif (i < n) o[i] = *first;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\to += n;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn {std::move(first), std::move(o)};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<class I, class S, class OR,\n\t\t\t\tclass Gen = detail::default_random_engine&>\n\t\t\trequires __sample_constraint<I, S, iterator_t<OR>, Gen> &&\n\t\t\t\t(forward_iterator<I> || sized_sentinel_for<S, I> ||\n\t\t\t\t random_access_range<OR>) &&\n\t\t\t\t(forward_range<OR> || sized_range<OR>)\n\t\t\tconstexpr sample_result<I, safe_iterator_t<OR>>\n\t\t\toperator()(I first, S last, OR&& o,\n\t\t\t\tGen&& gen = detail::get_random_engine()) const\n\t\t\t{\n\t\t\t\tif constexpr (forward_iterator<I> || sized_sentinel_for<S, I>) {\n\t\t\t\t\tauto k = distance(first, last);\n\t\t\t\t\treturn sized_impl(std::move(first), std::move(last),\n\t\t\t\t\t\tk, begin(o), distance(o), gen);\n\t\t\t\t} else { // random_access_range<OR>\n\t\t\t\t\treturn (*this)(std::move(first), std::move(last),\n\t\t\t\t\t\tbegin(o), distance(o), std::forward<Gen>(gen));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<range R, class O, class Gen = detail::default_random_engine&>\n\t\t\trequires __sample_constraint<iterator_t<R>, sentinel_t<R>, O, Gen> &&\n\t\t\t\t(forward_range<R> || sized_range<R> || random_access_iterator<O>)\n\t\t\tconstexpr sample_result<safe_iterator_t<R>, O>\n\t\t\toperator()(R&& r, O o, iter_difference_t<iterator_t<R>> n,\n\t\t\t\tGen&& gen = detail::get_random_engine()) const\n\t\t\t{\n\t\t\t\tif constexpr (forward_range<R> || sized_range<R>) {\n\t\t\t\t\treturn sized_impl(begin(r), end(r), distance(r), std::move(o),\n\t\t\t\t\t\tn, std::forward<Gen>(gen));\n\t\t\t\t} else { // random_access_iterator<O>\n\t\t\t\t\treturn (*this)(begin(r), end(r), std::move(o), n,\n\t\t\t\t\t\tstd::forward<Gen>(gen));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<range IR, range OR,\n\t\t\t\tclass Gen = detail::default_random_engine&>\n\t\t\trequires\n\t\t\t\t__sample_constraint<iterator_t<IR>, sentinel_t<IR>,\n\t\t\t\t\titerator_t<OR>, Gen> &&\n\t\t\t\t(forward_range<IR> || sized_range<IR> || random_access_range<OR>) &&\n\t\t\t\t(forward_range<OR> || sized_range<OR>)\n\t\t\tconstexpr sample_result<safe_iterator_t<IR>, safe_iterator_t<OR>>\n\t\t\toperator()(IR&& r, OR&& o,\n\t\t\t\tGen&& gen = detail::get_random_engine()) const\n\t\t\t{\n\t\t\t\tif constexpr (forward_range<IR> || sized_range<IR>) {\n\t\t\t\t\treturn sized_impl(begin(r), end(r), distance(r), begin(o),\n\t\t\t\t\t\tdistance(o), std::forward<Gen>(gen));\n\t\t\t\t} else { // random_access_range<OR>\n\t\t\t\t\treturn (*this)(begin(r), end(r),\n\t\t\t\t\t\tbegin(o), distance(o), std::forward<Gen>(gen));\n\t\t\t\t}\n\t\t\t}\n\t\tprivate:\n\t\t\ttemplate<class I, class S, class O, class Gen>\n\t\t\trequires __sample_constraint<I, S, O, Gen>\n\t\t\tstatic constexpr sample_result<I, O>\n\t\t\tsized_impl(I first, S last, iter_difference_t<I> pop_size,\n\t\t\t\tO o, iter_difference_t<I> n, Gen& gen)\n\t\t\t{\n\t\t\t\tstd::uniform_int_distribution<iter_difference_t<I>> dist;\n\t\t\t\tusing param_t = typename decltype(dist)::param_type;\n\t\t\t\tif (n > pop_size) {\n\t\t\t\t\tn = pop_size;\n\t\t\t\t}\n\t\t\t\tfor (; n > 0 && first != last; ++first) {\n\t\t\t\t\tif (dist(gen, param_t{0, --pop_size}) < n) {\n\t\t\t\t\t\t--n;\n\t\t\t\t\t\t*o = *first;\n\t\t\t\t\t\t++o;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn {std::move(first), std::move(o)};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __sample_fn sample{};\n\t} // namespace ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/search.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_SEARCH_HPP\n#define STL2_DETAIL_ALGORITHM_SEARCH_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/view/subrange.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// search [alg.search]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __search_fn : private __niebloid {\n\t\ttemplate<forward_iterator I1, sentinel_for<I1> S1,\n\t\t\tforward_iterator I2, sentinel_for<I2> S2, class Pred = equal_to,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires indirectly_comparable< I1, I2, Pred, Proj1, Proj2>\n\t\tconstexpr subrange<I1> operator()(I1 first1, S1 last1, I2 first2,\n\t\t\tS2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S1, I1> && sized_sentinel_for<S2, I2>) {\n\t\t\t\treturn sized(first1, last1, last1 - first1,\n\t\t\t\t\tfirst2, last2, last2 - first2,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t\t} else {\n\t\t\t\treturn unsized(first1, last1, first2, last2,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range R1, forward_range R2, class Pred = equal_to,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires indirectly_comparable<iterator_t<R1>, iterator_t<R2>,\n\t\t\tPred, Proj1, Proj2>\n\t\tconstexpr safe_subrange_t<R1> operator()(R1&& r1, R2&& r2,\n\t\t\tPred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tif constexpr (sized_range<R1> && sized_range<R2>) {\n\t\t\t\treturn sized(begin(r1), end(r1), distance(r1),\n\t\t\t\t\tbegin(r2), end(r2), distance(r2), __stl2::ref(pred),\n\t\t\t\t\t__stl2::ref(proj1), __stl2::ref(proj2));\n\t\t\t} else {\n\t\t\t\treturn unsized(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t\t}\n\t\t}\n\tprivate:\n\t\ttemplate<forward_iterator I1, sentinel_for<I1> S1,\n\t\t\tforward_iterator I2, sentinel_for<I2> S2, class Pred = equal_to,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tstatic constexpr subrange<I1> unsized(I1 first1, S1 last1, I2 first2,\n\t\t\tS2 last2, Pred pred, Proj1 proj1, Proj2 proj2)\n\t\t{\n\t\t\tif (first2 == last2) {\n\t\t\t\treturn {first1, first1};\n\t\t\t}\n\n\t\t\tfor (; first1 != last1; ++first1) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2)))\n\t\t\t\t{\n\t\t\t\t\t// *first1 matches *first2, now match elements after here\n\t\t\t\t\tauto m1 = first1;\n\t\t\t\t\tauto m2 = first2;\n\t\t\t\t\tdo {\n\t\t\t\t\t\t++m1;\n\t\t\t\t\t\t// If pattern exhausted, first1 is the answer (works for 1 element pattern)\n\t\t\t\t\t\tif (++m2 == last2) {\n\t\t\t\t\t\t\treturn {first1, m1};\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Otherwise if source exhausted, pattern not found\n\t\t\t\t\t\tif (m1 == last1) {\n\t\t\t\t\t\t\treturn {m1, m1};\n\t\t\t\t\t\t}\n\t\t\t\t\t} while (__stl2::invoke(pred, __stl2::invoke(proj1, *m1), __stl2::invoke(proj2, *m2)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {first1, first1};\n\t\t}\n\n\t\ttemplate<forward_iterator I1, sentinel_for<I1> S1,\n\t\t\tforward_iterator I2, sentinel_for<I2> S2,\n\t\t\tclass Pred, class Proj1, class Proj2>\n\t\trequires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>\n\t\tstatic constexpr subrange<I1> sized(const I1 first1_, S1 last1,\n\t\t\tconst iter_difference_t<I1> d1_, I2 first2, S2 last2,\n\t\t\tconst iter_difference_t<I2> d2, Pred pred, Proj1 proj1, Proj2 proj2)\n\t\t{\n\t\t\tif (d2 == 0) {\n\t\t\t\treturn {first1_, first1_};\n\t\t\t}\n\n\t\t\tauto d1 = d1_;\n\t\t\tauto first1 = ext::uncounted(first1_);\n\t\t\tfor(; d1 >= d2; ++first1, --d1) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj1, *first1),\n\t\t\t\t\t\t__stl2::invoke(proj2, *first2)))\n\t\t\t\t{\n\t\t\t\t\tauto m1 = first1;\n\t\t\t\t\tauto m2 = first2;\n\t\t\t\t\tdo {\n\t\t\t\t\t\t++m1;\n\t\t\t\t\t\tif (++m2 == last2) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\text::recounted(first1_, first1, d1_ - d1),\n\t\t\t\t\t\t\t\text::recounted(first1_, m1, d1_ - d1 + d2)\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} while (__stl2::invoke(pred, __stl2::invoke(proj1, *m1), __stl2::invoke(proj2, *m2)));\n\t\t\t\t}\n\t\t\t}\n\t\t\tauto end = next(ext::recounted(first1_, first1, d1_ - d1), last1);\n\t\t\treturn {end, end};\n\t\t}\n\t};\n\n\tinline constexpr __search_fn search{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/search_n.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_SEARCH_N_HPP\n#define STL2_DETAIL_ALGORITHM_SEARCH_N_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// search_n [alg.search]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __search_n_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class T,\n\t\t\tclass Pred = equal_to, class Proj = identity>\n\t\trequires indirectly_comparable<I, const T*, Pred, Proj>\n\t\tconstexpr I operator()(I first, S last, iter_difference_t<I> count,\n\t\t\tconst T& value, Pred pred = {}, Proj proj = {}) const\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\tauto n = static_cast<iter_difference_t<I>>(last - first);\n\t\t\t\treturn sized(std::move(first), std::move(last),\n\t\t\t\t\tn, count, value, __stl2::ref(pred), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\treturn unsized(std::move(first), std::move(last),\n\t\t\t\t\tcount, value, __stl2::ref(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range R, class T, class Pred = equal_to,\n\t\t\tclass Proj = identity>\n\t\trequires indirectly_comparable<iterator_t<R>, const T*, Pred, Proj>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, iter_difference_t<iterator_t<R>> count,\n\t\t\tconst T& value, Pred pred = {}, Proj proj = {}) const\n\t\t{\n\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\treturn sized(begin(r), end(r), distance(r), count, value,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\treturn unsized(begin(r), end(r), count, value,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\tprivate:\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class T, class Pred,\n\t\t\tclass Proj>\n\t\trequires indirectly_comparable<I, const T*, Pred, Proj>\n\t\tstatic constexpr I unsized(I first, S last, iter_difference_t<I> count,\n\t\t\tconst T& value, Pred pred, Proj proj)\n\t\t{\n\t\t\tif (count <= 0) {\n\t\t\t\treturn first;\n\t\t\t}\n\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *first), value)) {\n\t\t\t\t\tauto saved = first;\n\t\t\t\t\titer_difference_t<I> n = 0;\n\t\t\t\t\tdo {\n\t\t\t\t\t\tif (++n == count) {\n\t\t\t\t\t\t\treturn saved;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (++first == last) {\n\t\t\t\t\t\t\treturn first;\n\t\t\t\t\t\t}\n\t\t\t\t\t} while(__stl2::invoke(pred, __stl2::invoke(proj, *first), value));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class T, class Pred, class Proj>\n\t\trequires indirectly_comparable<I, const T*, Pred, Proj>\n\t\tstatic constexpr I sized(I first_, S last, iter_difference_t<I> d_,\n\t\t\titer_difference_t<I> count, const T& value, Pred pred, Proj proj)\n\t\t{\n\t\t\tif (count <= 0) {\n\t\t\t\treturn first_;\n\t\t\t}\n\n\t\t\tauto d = d_;\n\t\t\tauto first = ext::uncounted(first_);\n\n\t\t\tfor (; d >= count; ++first, --d) {\n\t\t\t\tif (__stl2::invoke(pred, __stl2::invoke(proj, *first), value)) {\n\t\t\t\t\t// *first matches val, now match elements after here\n\t\t\t\t\tauto saved = first;\n\t\t\t\t\titer_difference_t<I> n = 0;\n\t\t\t\t\tdo {\n\t\t\t\t\t\tif (++n == count) {\n\t\t\t\t\t\t\t// Pattern exhausted, saved is the answer\n\t\t\t\t\t\t\t// (works for 1 element pattern)\n\t\t\t\t\t\t\treturn ext::recounted(first_, std::move(saved), d_ - d);\n\t\t\t\t\t\t}\n\t\t\t\t\t} while (__stl2::invoke(pred, __stl2::invoke(proj, *++first), value));\n\t\t\t\t\td -= n;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn next(ext::recounted(first_, std::move(first), d_ - d),\n\t\t\t\tstd::move(last));\n\t\t}\n\t};\n\n\tinline constexpr __search_n_fn search_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/set_difference.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_SET_DIFFERENCE_HPP\n#define STL2_DETAIL_ALGORITHM_SET_DIFFERENCE_HPP\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// set_difference [set.difference]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing set_difference_result = __in_out_result<I, O>;\n\n\tstruct __set_difference_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, weakly_incrementable O, class Comp = less,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<I1, I2, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_difference_result<I1, O>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2, O result,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (bool(first1 != last1) && bool(first2 != last2)) {\n\t\t\t\titer_reference_t<I1>&& v1 = *first1;\n\t\t\t\titer_reference_t<I2>&& v2 = *first2;\n\t\t\t\tauto&& p1 = __stl2::invoke(proj1, v1);\n\t\t\t\tauto&& p2 = __stl2::invoke(proj2, v2);\n\t\t\t\tif (__stl2::invoke(comp, p1, p2)) {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I1>>(v1);\n\t\t\t\t\t++result;\n\t\t\t\t\t++first1;\n\t\t\t\t} else {\n\t\t\t\t\tif (!__stl2::invoke(comp, p2, p1)) {\n\t\t\t\t\t\t++first1;\n\t\t\t\t\t}\n\t\t\t\t\t++first2;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn copy(std::move(first1), std::move(last1), std::move(result));\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, weakly_incrementable O,\n\t\t\tclass Comp = less, class Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_difference_result<safe_iterator_t<R1>, O>\n\t\toperator()(R1&& r1, R2&& r2, O result,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\tstd::move(result), __stl2::ref(comp), __stl2::ref(proj1),\n\t\t\t\t__stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __set_difference_fn set_difference{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/set_intersection.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_SET_INTERSECTION_HPP\n#define STL2_DETAIL_ALGORITHM_SET_INTERSECTION_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// set_intersection [set.intersection]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2, class O>\n\tusing set_intersection_result = __in_in_out_result<I1, I2, O>;\n\n\tstruct __set_intersection_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, weakly_incrementable O, class Comp = less,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<I1, I2, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_intersection_result<I1, I2, O>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2, O result,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (bool(first1 != last1) && bool(first2 != last2)) {\n\t\t\t\titer_reference_t<I1>&& v1 = *first1;\n\t\t\t\titer_reference_t<I2>&& v2 = *first2;\n\t\t\t\tauto&& p1 = __stl2::invoke(proj1, v1);\n\t\t\t\tauto&& p2 = __stl2::invoke(proj2, v2);\n\t\t\t\tif (__stl2::invoke(comp, p1, p2)) {\n\t\t\t\t\t++first1;\n\t\t\t\t} else if (__stl2::invoke(comp, p2, p1)) {\n\t\t\t\t\t++first2;\n\t\t\t\t} else {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I1>>(v1);\n\t\t\t\t\t++result;\n\t\t\t\t\t++first1;\n\t\t\t\t\t++first2;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {std::move(first1), std::move(first2), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, weakly_incrementable O,\n\t\t\tclass Comp = less, class Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_intersection_result<\n\t\t\tsafe_iterator_t<R1>, safe_iterator_t<R2>, O>\n\t\toperator()(R1&& r1, R2&& r2, O result, Comp comp = {}, Proj1 proj1 = {},\n\t\t\tProj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\tstd::move(result), __stl2::ref(comp), __stl2::ref(proj1),\n\t\t\t\t__stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __set_intersection_fn set_intersection{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/set_symmetric_difference.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_SET_SYMMETRIC_DIFFERENCE_HPP\n#define STL2_DETAIL_ALGORITHM_SET_SYMMETRIC_DIFFERENCE_HPP\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// set_symmetric_difference [set.symmetric.difference]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2, class O>\n\tusing set_symmetric_difference_result = __in_in_out_result<I1, I2, O>;\n\n\tstruct __set_symmetric_difference_fn : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, weakly_incrementable O, class Comp = less,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<I1, I2, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_symmetric_difference_result<I1, I2, O>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2, O result,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (true) {\n\t\t\t\tif (first1 == last1) {\n\t\t\t\t\tauto cresult = copy(std::move(first2), std::move(last2),\n\t\t\t\t\t\tstd::move(result));\n\t\t\t\t\tfirst2 = std::move(cresult.in);\n\t\t\t\t\tresult = std::move(cresult.out);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (first2 == last2) {\n\t\t\t\t\tauto cresult = copy(std::move(first1), std::move(last1),\n\t\t\t\t\t\tstd::move(result));\n\t\t\t\t\tfirst1 = std::move(cresult.in);\n\t\t\t\t\tresult = std::move(cresult.out);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\titer_reference_t<I1>&& v1 = *first1;\n\t\t\t\titer_reference_t<I2>&& v2 = *first2;\n\t\t\t\tauto&& p1 = __stl2::invoke(proj1, v1);\n\t\t\t\tauto&& p2 = __stl2::invoke(proj2, v2);\n\t\t\t\tif (__stl2::invoke(comp, p1, p2)) {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I1>>(v1);\n\t\t\t\t\t++result;\n\t\t\t\t\t++first1;\n\t\t\t\t} else {\n\t\t\t\t\tif (__stl2::invoke(comp, p2, p1)) {\n\t\t\t\t\t\t*result = std::forward<iter_reference_t<I2>>(v2);\n\t\t\t\t\t\t++result;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t++first1;\n\t\t\t\t\t}\n\t\t\t\t\t++first2;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstd::move(first1), std::move(first2), std::move(result)\n\t\t\t};\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, weakly_incrementable O,\n\t\t\tclass Comp = less, class Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_symmetric_difference_result<\n\t\t\tsafe_iterator_t<R1>, safe_iterator_t<R2>, O>\n\t\toperator()(R1&& r1, R2&& r2, O result, Comp comp = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\tstd::move(result), __stl2::ref(comp), __stl2::ref(proj1),\n\t\t\t\t__stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __set_symmetric_difference_fn set_symmetric_difference{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/set_union.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_SET_UNION_HPP\n#define STL2_DETAIL_ALGORITHM_SET_UNION_HPP\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// set_union [set.union]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2, class O>\n\tusing set_union_result = __in_in_out_result<I1, I2, O>;\n\n\tstruct __set_union : private __niebloid {\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1, input_iterator I2,\n\t\t\tsentinel_for<I2> S2, weakly_incrementable O, class Comp = less,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<I1, I2, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_union_result<I1, I2, O>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2, O result,\n\t\t\tComp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\twhile (true) {\n\t\t\t\tif (first1 == last1) {\n\t\t\t\t\tauto res = copy(std::move(first2), std::move(last2),\n\t\t\t\t\t\tstd::move(result));\n\t\t\t\t\treturn {std::move(first1), std::move(res.in),\n\t\t\t\t\t\tstd::move(res.out)};\n\t\t\t\t}\n\t\t\t\tif (first2 == last2) {\n\t\t\t\t\tauto res = copy(std::move(first1), std::move(last1),\n\t\t\t\t\t\tstd::move(result));\n\t\t\t\t\treturn {std::move(res.in), std::move(first2),\n\t\t\t\t\t\tstd::move(res.out)};\n\t\t\t\t}\n\t\t\t\titer_reference_t<I1>&& v1 = *first1;\n\t\t\t\titer_reference_t<I2>&& v2 = *first2;\n\t\t\t\tauto&& p1 = __stl2::invoke(proj1, v1);\n\t\t\t\tauto&& p2 = __stl2::invoke(proj2, v2);\n\t\t\t\tif (__stl2::invoke(comp, p1, p2)) {\n\t\t\t\t\t*result = std::forward<iter_reference_t<I1>>(v1);\n\t\t\t\t\t++first1;\n\t\t\t\t} else {\n\t\t\t\t\tif (!__stl2::invoke(comp, p2, p1)) {\n\t\t\t\t\t\t++first1;\n\t\t\t\t\t}\n\t\t\t\t\t*result = std::forward<iter_reference_t<I2>>(v2);\n\t\t\t\t\t++first2;\n\t\t\t\t}\n\t\t\t\t++result;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, weakly_incrementable O,\n\t\t\tclass Comp = less, class Proj1 = identity, class Proj2 = identity>\n\t\trequires mergeable<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>\n\t\tconstexpr set_union_result<safe_iterator_t<R1>, safe_iterator_t<R2>, O>\n\t\toperator()(R1&& r1, R2&& r2, O result, Comp comp = {},\n\t\t\tProj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2),\n\t\t\t\tstd::move(result), __stl2::ref(comp), __stl2::ref(proj1),\n\t\t\t\t__stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __set_union set_union{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/shuffle.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_SHUFFLE_HPP\n#define STL2_DETAIL_ALGORITHM_SHUFFLE_HPP\n\n#include <stl2/random.hpp>\n#include <stl2/detail/randutils.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// shuffle [alg.random.shuffle]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __shuffle_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S,\n\t\t\tclass Gen = detail::default_random_engine&>\n\t\trequires permutable<I> &&\n\t\t\tuniform_random_bit_generator<std::remove_reference_t<Gen>>\n\t\tconstexpr I operator()(I const first, S const last,\n\t\t\tGen&& g = detail::get_random_engine()) const\n\t\t{\n\t\t\tauto mid = first;\n\t\t\tif (mid == last) return mid;\n\t\t\tusing D = iter_difference_t<I>;\n\t\t\tauto dist = std::uniform_int_distribution<D>{};\n\t\t\tusing param_t =\n\t\t\t\ttypename std::uniform_int_distribution<D>::param_type;\n\t\t\twhile (++mid != last) {\n\t\t\t\tif (auto const i = dist(g, param_t{0, mid - first})) {\n\t\t\t\t\titer_swap(mid - i, mid);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn mid;\n\t\t}\n\n\t\ttemplate<random_access_range Rng,\n\t\t\tclass Gen = detail::default_random_engine&>\n\t\trequires permutable<iterator_t<Rng>> &&\n\t\t\tuniform_random_bit_generator<std::remove_reference_t<Gen>>\n\t\tconstexpr safe_iterator_t<Rng>\n\t\toperator()(Rng&& rng, Gen&& g = detail::get_random_engine()) const {\n\t\t\treturn (*this)(begin(rng), end(rng), std::forward<Gen>(g));\n\t\t}\n\t};\n\n\tinline constexpr __shuffle_fn shuffle{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/sort.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//  Copyright (c) 1994\n//  Hewlett-Packard Company\n//\n//  Permission to use, copy, modify, distribute and sell this software\n//  and its documentation for any purpose is hereby granted without fee,\n//  provided that the above copyright notice appear in all copies and\n//  that both that copyright notice and this permission notice appear\n//  in supporting documentation.  Hewlett-Packard Company makes no\n//  representations about the suitability of this software for any\n//  purpose.  It is provided \"as is\" without express or implied warranty.\n//\n//  Copyright (c) 1996\n//  Silicon Graphics Computer Systems, Inc.\n//\n//  Permission to use, copy, modify, distribute and sell this software\n//  and its documentation for any purpose is hereby granted without fee,\n//  provided that the above copyright notice appear in all copies and\n//  that both that copyright notice and this permission notice appear\n//  in supporting documentation.  Silicon Graphics makes no\n//  representations about the suitability of this software for any\n//  purpose.  It is provided \"as is\" without express or implied warranty.\n//\n#ifndef STL2_DETAIL_ALGORITHM_SORT_HPP\n#define STL2_DETAIL_ALGORITHM_SORT_HPP\n\n#include <stl2/detail/algorithm/move_backward.hpp>\n#include <stl2/detail/algorithm/partial_sort.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// sort [sort]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct rsort {\n\t\t\ttemplate<bidirectional_iterator I, class Comp, class Proj>\n\t\t\trequires sortable<I, Comp, Proj>\n\t\t\tstatic constexpr void\n\t\t\tunguarded_linear_insert(I last, iter_value_t<I> val, Comp& comp, Proj& proj)\n\t\t\t{\n\t\t\t\tI next = prev(last);\n\t\t\t\twhile (__stl2::invoke(comp, __stl2::invoke(proj, val), __stl2::invoke(proj, *next))) {\n\t\t\t\t\t*last = iter_move(next);\n\t\t\t\t\tlast = next;\n\t\t\t\t\t--next;\n\t\t\t\t}\n\t\t\t\t*last = std::move(val);\n\t\t\t}\n\t\t\ttemplate<bidirectional_iterator I, class Comp, class Proj>\n\t\t\trequires sortable<I, Comp, Proj>\n\t\t\tstatic constexpr void insertion_sort(I first, I last, Comp& comp, Proj& proj)\n\t\t\t{\n\t\t\t\tif (first != last) {\n\t\t\t\t\tfor (I i = next(first); i != last; ++i) {\n\t\t\t\t\t\tlinear_insert(first, i, comp, proj);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tprivate:\n\t\t\ttemplate<bidirectional_iterator I, class Comp, class Proj>\n\t\t\trequires sortable<I, Comp, Proj>\n\t\t\tstatic constexpr void linear_insert(I first, I last, Comp& comp, Proj& proj)\n\t\t\t{\n\t\t\t\titer_value_t<I> val = iter_move(last);\n\t\t\t\tif (__stl2::invoke(comp, __stl2::invoke(proj, val), __stl2::invoke(proj, *first))) {\n\t\t\t\t\tmove_backward(first, last, last + 1);\n\t\t\t\t\t*first = std::move(val);\n\t\t\t\t} else {\n\t\t\t\t\tunguarded_linear_insert(last, std::move(val), comp, proj);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tstruct __sort_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr I\n\t\toperator()(I first, S sent, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif (first == sent) return first;\n\t\t\tauto last = next(first, static_cast<S&&>(sent));\n\t\t\tauto n = distance(first, last);\n\t\t\tintrosort_loop(first, last, log2(n) * 2, comp, proj);\n\t\t\tfinal_insertion_sort(first, last, comp, proj);\n\t\t\treturn last;\n\t\t}\n\n\t\ttemplate<random_access_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), static_cast<Comp&&>(comp),\n\t\t\t\tstatic_cast<Proj&&>(proj));\n\t\t}\n\tprivate:\n\t\tstatic constexpr std::ptrdiff_t introsort_threshold = 16;\n\n\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\trequires sortable<I, Comp, Proj>\n\t\tstatic constexpr I\n\t\tchoose_pivot(I first, I last, Comp& comp, Proj& proj) {\n\t\t\tSTL2_EXPECT(first != last);\n\t\t\tI mid = first + iter_difference_t<I>(last - first) / 2;\n\t\t\t--last;\n\t\t\t// Find the median:\n\t\t\treturn [&](auto&& a, auto&& b, auto&& c) {\n\t\t\t\treturn __stl2::invoke(comp, a, b)\n\t\t\t\t\t? (__stl2::invoke(comp, b, c) ? mid   : (__stl2::invoke(comp, a, c) ? last : first))\n\t\t\t\t\t: (__stl2::invoke(comp, a, c) ? first : (__stl2::invoke(comp, b, c) ? last : mid  ));\n\t\t\t}(__stl2::invoke(proj, *first), __stl2::invoke(proj, *mid), __stl2::invoke(proj, *last));\n\t\t}\n\n\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\trequires sortable<I, Comp, Proj>\n\t\tstatic constexpr I\n\t\tunguarded_partition(I first, I last, Comp& comp, Proj& proj) {\n\t\t\tI pivot_pnt = choose_pivot(first, last, comp, proj);\n\n\t\t\t// Do the partition:\n\t\t\twhile (true) {\n\t\t\t\tauto&& v = *pivot_pnt;\n\t\t\t\tauto&& pivot = __stl2::invoke(proj, std::forward<decltype(v)>(v));\n\t\t\t\twhile (__stl2::invoke(comp, __stl2::invoke(proj, *first), pivot)) {\n\t\t\t\t\t++first;\n\t\t\t\t}\n\t\t\t\twhile (__stl2::invoke(comp, pivot, __stl2::invoke(proj, *--last))) {\n\t\t\t\t\t; // do nothing\n\t\t\t\t}\n\t\t\t\tif (!(first < last)) {\n\t\t\t\t\treturn first;\n\t\t\t\t}\n\t\t\t\titer_swap(first, last);\n\t\t\t\tpivot_pnt = pivot_pnt == first ? last : (pivot_pnt == last ? first : pivot_pnt);\n\t\t\t\t++first;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\trequires sortable<I, Comp, Proj>\n\t\tstatic constexpr void\n\t\tintrosort_loop(I first, I last, iter_difference_t<I> depth_limit, Comp& comp, Proj& proj)\n\t\t{\n\t\t\twhile (distance(first, last) > introsort_threshold) {\n\t\t\t\tif (depth_limit == 0) {\n\t\t\t\t\tpartial_sort(first, last, last, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tI cut = unguarded_partition(first, last, comp, proj);\n\t\t\t\tintrosort_loop(cut, last, --depth_limit, comp, proj);\n\t\t\t\tlast = cut;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<bidirectional_iterator I, class Comp, class Proj>\n\t\trequires sortable<I, Comp, Proj>\n\t\tstatic constexpr void\n\t\tunguarded_insertion_sort(I first, I last, Comp& comp, Proj& proj) {\n\t\t\tfor (I i = first; i != last; ++i) {\n\t\t\t\tdetail::rsort::unguarded_linear_insert(i, iter_move(i), comp, proj);\n\t\t\t}\n\t\t}\n\n\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\trequires sortable<I, Comp, Proj>\n\t\tstatic constexpr void\n\t\tfinal_insertion_sort(I first, I last, Comp &comp, Proj &proj) {\n\t\t\tif (distance(first, last) > introsort_threshold) {\n\t\t\t\tdetail::rsort::insertion_sort(first, first + introsort_threshold, comp, proj);\n\t\t\t\tunguarded_insertion_sort(first + introsort_threshold, last, comp, proj);\n\t\t\t} else {\n\t\t\t\tdetail::rsort::insertion_sort(first, last, comp, proj);\n\t\t\t}\n\t\t}\n\n\t\ttemplate<integral I>\n\t\tstatic constexpr auto log2(I n) {\n\t\t\tSTL2_EXPECT(n > 0);\n\t\t\tI k = 0;\n\t\t\tfor (; n != 1; n /= 2) {\n\t\t\t\t++k;\n\t\t\t}\n\t\t\treturn k;\n\t\t}\n\t};\n\n\tinline constexpr __sort_fn sort{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/sort_heap.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n//\n#ifndef STL2_DETAIL_ALGORITHM_SORT_HEAP_HPP\n#define STL2_DETAIL_ALGORITHM_SORT_HEAP_HPP\n\n#include <stl2/detail/algorithm/pop_heap.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// sort_heap [sort.heap]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\tstruct __sort_heap_n_fn {\n\t\t\ttemplate<random_access_iterator I, class Comp, class Proj>\n\t\t\trequires sortable<I, Comp, Proj>\n\t\t\tconstexpr void operator()(I first, iter_difference_t<I> n,\n\t\t\t\tComp comp, Proj proj) const\n\t\t\t{\n\t\t\t\tfor (; n > 1; --n) {\n\t\t\t\t\tdetail::pop_heap_n(first, n, __stl2::ref(comp),\n\t\t\t\t\t\t__stl2::ref(proj));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __sort_heap_n_fn sort_heap_n{};\n\t} // namespace ext\n\n\tstruct __sort_heap_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, sentinel_for<I> S, class Comp = less,\n\t\t\tclass Proj = identity>\n\t\trequires sortable<I, Comp, Proj>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(first, std::move(last));\n\t\t\text::sort_heap_n(first, n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn first + n;\n\t\t}\n\n\t\ttemplate<random_access_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto n = distance(r);\n\t\t\text::sort_heap_n(begin(r), n, __stl2::ref(comp), __stl2::ref(proj));\n\t\t\treturn begin(r) + n;\n\t\t}\n\t};\n\n\tinline constexpr __sort_heap_fn sort_heap{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/stable_partition.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_STABLE_PARTITION_HPP\n#define STL2_DETAIL_ALGORITHM_STABLE_PARTITION_HPP\n\n#include <stl2/detail/temporary_vector.hpp>\n#include <stl2/detail/algorithm/find_if_not.hpp>\n#include <stl2/detail/algorithm/move.hpp>\n#include <stl2/detail/algorithm/rotate.hpp>\n#include <stl2/detail/algorithm/partition_copy.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <stl2/detail/iterator/move_iterator.hpp>\n#include <stl2/view/subrange.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// stable_partition [alg.partitions]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\tstruct __stable_partition_n_fn : private __niebloid {\n\t\t\ttemplate<forward_iterator I, class Pred, class Proj = identity>\n\t\t\trequires permutable<I> &&\n\t\t\t\tindirect_unary_predicate<Pred, projected<I, Proj>>\n\t\t\tI operator()(I first, iter_difference_t<I> n, Pred pred,\n\t\t\t\tProj proj = {}) const\n\t\t\t{\n\t\t\t\tif constexpr (bidirectional_iterator<I>) {\n\t\t\t\t\tauto bound = next(first, n);\n\t\t\t\t\treturn (*this)(std::move(first), std::move(bound), n,\n\t\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t\t} else {\n\t\t\t\t\t// Either prove all true or find first false\n\t\t\t\t\tskip_true(first, n, pred, proj);\n\t\t\t\t\tif (n < iter_difference_t<I>(2)) return first;\n\t\t\t\t\t// We now have a reduced range [first, first + n)\n\t\t\t\t\t// *first is known to be false\n\n\t\t\t\t\t// PERF: might want to make this a function of trivial assignment\n\t\t\t\t\tconstexpr iter_difference_t<I> alloc_threshold = 4;\n\t\t\t\t\tusing buf_t = buf_t<I>;\n\t\t\t\t\tauto buf = n >= alloc_threshold ? buf_t{n} : buf_t{};\n\t\t\t\t\treturn forward(first, n, buf, pred, proj).begin();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<bidirectional_iterator I, class Pred, class Proj = identity>\n\t\t\trequires permutable<I> &&\n\t\t\t\tindirect_unary_predicate<Pred, projected<I, Proj>>\n\t\t\tI operator()(I first, I last, iter_difference_t<I> n, Pred pred,\n\t\t\t\tProj proj = {}) const\n\t\t\t{\n\t\t\t\tSTL2_ASSERT(n == distance(first, last));\n\n\t\t\t\t// Either prove all true or find first false\n\t\t\t\tskip_true(first, n, pred, proj);\n\t\t\t\tif (n == iter_difference_t<I>(0)) return first;\n\n\t\t\t\t// Either prove (first, last) is all false or find last true\n\t\t\t\tskip_false(last, n, pred, proj);\n\t\t\t\tif (n == iter_difference_t<I>(0)) return first;\n\t\t\t\t// We now have a reduced range [first, last]\n\t\t\t\t// *first is known to be false\n\t\t\t\t// *last is known to be true\n\n\t\t\t\t// might want to make this a function of trivial assignment\n\t\t\t\tconstexpr iter_difference_t<I> alloc_threshold = 4;\n\t\t\t\tusing buf_t = buf_t<I>;\n\t\t\t\tbuf_t buf = n >= alloc_threshold ? buf_t{n} : buf_t{};\n\t\t\t\treturn bidirectional(first, last, n, buf, pred, proj);\n\t\t\t}\n\t\tprivate:\n\t\t\ttemplate<readable I>\n\t\t\tusing buf_t = detail::temporary_buffer<iter_value_t<I>>;\n\n\t\t\ttemplate<forward_iterator I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\tstatic constexpr void\n\t\t\tskip_true(I& first, iter_difference_t<I>& n, Pred& pred, Proj& proj) {\n\t\t\t\t// advance \"first\" past values that satisfy the predicate.\n\t\t\t\t// Ensures: n == 0 || !__stl2::invoke(pred, __stl2::invoke(proj, *first))\n\t\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\t\twhile (n != 0 && __stl2::invoke(pred, __stl2::invoke(proj, *first))) {\n\t\t\t\t\t++first;\n\t\t\t\t\t--n;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<permutable I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\tstatic subrange<I> forward_buffer(I first, I next,\n\t\t\t\titer_difference_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj)\n\t\t\t{\n\t\t\t\t// Precondition: !__stl2::invoke(pred, __stl2::invoke(proj, *first)))\n\t\t\t\t// Precondition: next(first) == next\n\t\t\t\tSTL2_EXPECT(n >= 2);\n\t\t\t\tSTL2_EXPECT(n <= buf.size());\n\n\t\t\t\tauto&& vec = detail::make_temporary_vector(buf);\n\t\t\t\tvec.push_back(iter_move(first));\n\t\t\t\tauto counted = counted_iterator{ext::uncounted(next), n - 1};\n\t\t\t\tauto pp = partition_copy(\n\t\t\t\t\t\t__stl2::make_move_iterator(std::move(counted)),\n\t\t\t\t\t\tmove_sentinel<default_sentinel_t>{},\n\t\t\t\t\t\tstd::move(first), __stl2::back_inserter(vec),\n\t\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj)).out1;\n\t\t\t\tauto last = move(vec, pp).out;\n\t\t\t\treturn {std::move(pp), std::move(last)};\n\t\t\t}\n\n\t\t\ttemplate<permutable I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\tstatic subrange<I> forward(I first, iter_difference_t<I> n,\n\t\t\t\tbuf_t<I>& buf, Pred& pred, Proj& proj)\n\t\t\t{\n\t\t\t\t// Precondition: !__stl2::invoke(pred, __stl2::invoke(proj, *first)))\n\t\t\t\tSTL2_EXPECT(n > 0);\n\n\t\t\t\tauto middle = next(first);\n\t\t\t\tif (n == iter_difference_t<I>(1)) {\n\t\t\t\t\treturn {std::move(first), std::move(middle)};\n\t\t\t\t}\n\t\t\t\t// Post: n >= 2\n\n\t\t\t\tif (n <= buf.size()) {\n\t\t\t\t\treturn forward_buffer(\n\t\t\t\t\t\tstd::move(first), std::move(middle),\n\t\t\t\t\t\tn, buf, pred, proj);\n\t\t\t\t}\n\n\t\t\t\tconst auto half_n = n / 2;\n\t\t\t\tauto res1 = forward(std::move(first), half_n, buf, pred, proj);\n\t\t\t\tauto res2 = forward_reduce(res1.end(), n - half_n, buf, pred, proj);\n\t\t\t\tauto pp = rotate(std::move(res1.begin()),\n\t\t\t\t\tstd::move(res1.end()), std::move(res2.begin())).begin();\n\t\t\t\treturn {std::move(pp), std::move(res2.end())};\n\t\t\t}\n\n\t\t\ttemplate<permutable I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\tstatic subrange<I> forward_reduce(I first, iter_difference_t<I> n,\n\t\t\t\tbuf_t<I>& buf, Pred& pred, Proj& proj)\n\t\t\t{\n\t\t\t\t// Establish preconditions of forward by reducing the\n\t\t\t\t// input range.\n\t\t\t\tskip_true(first, n, pred, proj);\n\t\t\t\tif (n < iter_difference_t<I>(2)) {\n\t\t\t\t\tauto last = next(first, n);\n\t\t\t\t\treturn {std::move(first), std::move(last)};\n\t\t\t\t}\n\t\t\t\treturn forward(std::move(first), n, buf, pred, proj);\n\t\t\t}\n\n\t\t\ttemplate<bidirectional_iterator I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\tstatic constexpr void\n\t\t\tskip_false(I& last, iter_difference_t<I>& n, Pred& pred, Proj& proj) {\n\t\t\t\t// Move last backward past values that do not satisfy pred.\n\t\t\t\t// Pre: __stl2::invoke(pred, __stl2::invoke(proj, *(last - n)))\n\t\t\t\tSTL2_EXPECT(n > 0);\n\t\t\t\t// Post: n == 0 || __stl2::invoke(pred, __stl2::invoke(proj, *last))\n\n\t\t\t\tdo {\n\t\t\t\t\t--last;\n\t\t\t\t} while (--n != 0 && !__stl2::invoke(pred, __stl2::invoke(proj, *last)));\n\t\t\t}\n\n\t\t\ttemplate<bidirectional_iterator I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\trequires permutable<I>\n\t\t\tstatic I bidirectional_buffer(I first, I last, iter_difference_t<I> n,\n\t\t\t\tbuf_t<I>& buf, Pred& pred, Proj& proj)\n\t\t\t{\n\t\t\t\t// Pre: !__stl2::invoke(pred, __stl2::invoke(proj, *first))\n\t\t\t\t// Pre: __stl2::invoke(pred, __stl2::invoke(proj, *last))\n\t\t\t\t// Pre: n == distance(first, last)\n\t\t\t\tSTL2_EXPECT(n >= 2);\n\t\t\t\tSTL2_EXPECT(n <= buf.size());\n\n\t\t\t\t// Move the false values into the temporary buffer\n\t\t\t\t// and the true values to the front of the sequence.\n\t\t\t\tauto&& vec = detail::make_temporary_vector(buf);\n\t\t\t\tvec.push_back(iter_move(first));\n\t\t\t\tauto middle = next(first);\n\t\t\t\tmiddle = partition_copy(\n\t\t\t\t\t__stl2::make_move_iterator(std::move(middle)),\n\t\t\t\t\t__stl2::make_move_iterator(last),\n\t\t\t\t\tstd::move(first),\n\t\t\t\t\t__stl2::back_inserter(vec),\n\t\t\t\t\t__stl2::ref(pred),\n\t\t\t\t\t__stl2::ref(proj)).out1;\n\t\t\t\t*middle = iter_move(last);\n\t\t\t\t++middle;\n\t\t\t\tmove(vec, middle);\n\t\t\t\treturn middle;\n\t\t\t}\n\n\t\t\ttemplate<bidirectional_iterator I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\trequires permutable<I>\n\t\t\tstatic I bidirectional(I first, I last, iter_difference_t<I> n,\n\t\t\t\tbuf_t<I>& buf, Pred& pred, Proj& proj)\n\t\t\t{\n\t\t\t\t// Pre: !__stl2::invoke(pred, __stl2::invoke(proj, *first))\n\t\t\t\t// Pre: __stl2::invoke(pred, __stl2::invoke(proj, *last))\n\t\t\t\t// Pre: n == distance(first, last)\n\t\t\t\tSTL2_EXPECT(n >= iter_difference_t<I>(1));\n\n\t\t\t\tif (n == iter_difference_t<I>(1)) {\n\t\t\t\t\titer_swap(first, last);\n\t\t\t\t\treturn last;\n\t\t\t\t}\n\t\t\t\t// Post: n >= 2\n\t\t\t\tif (n <= buf.size()) {\n\t\t\t\t\treturn bidirectional_buffer(\n\t\t\t\t\t\tstd::move(first), std::move(last),\n\t\t\t\t\t\tn, buf, pred, proj);\n\t\t\t\t}\n\n\t\t\t\tconst auto half_n = n / 2;\n\t\t\t\tauto middle = next(first, half_n);\n\t\t\t\tauto pp1 = bidirectional_reduce_back(\n\t\t\t\t\tstd::move(first), middle, half_n, buf, pred, proj);\n\t\t\t\tauto pp2 = bidirectional_reduce_front(\n\t\t\t\t\tmiddle, std::move(last), n - half_n, buf, pred, proj);\n\n\t\t\t\treturn rotate(std::move(pp1), std::move(middle),\n\t\t\t\t\tstd::move(pp2)).begin();\n\t\t\t}\n\n\t\t\ttemplate<bidirectional_iterator I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\trequires permutable<I>\n\t\t\tstatic I bidirectional_reduce_front(I first, I last,\n\t\t\t\titer_difference_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj)\n\t\t\t{\n\t\t\t\t// Pre: __stl2::invoke(pred, __stl2::invoke(proj, *last))\n\t\t\t\t// Pre: n == distance(first, last)\n\t\t\t\tSTL2_EXPECT(n >= iter_difference_t<I>(0));\n\n\t\t\t\tskip_true(first, n, pred, proj);\n\t\t\t\tif (n == iter_difference_t<I>(0)) {\n\t\t\t\t\treturn std::move(++last);\n\t\t\t\t}\n\t\t\t\treturn bidirectional(first, last, n, buf, pred, proj);\n\t\t\t}\n\n\t\t\ttemplate<bidirectional_iterator I, class Proj,\n\t\t\t\tindirect_unary_predicate<projected<I, Proj>> Pred>\n\t\t\trequires permutable<I>\n\t\t\tstatic I bidirectional_reduce_back(I first, I last,\n\t\t\t\titer_difference_t<I> n, buf_t<I>& buf, Pred& pred, Proj& proj) {\n\t\t\t\t// Pre: !__stl2::invoke(pred, __stl2::invoke(proj, *first))\n\t\t\t\t// Pre: n == distance(first, last)\n\t\t\t\tSTL2_EXPECT(n >= iter_difference_t<I>(1));\n\n\t\t\t\tskip_false(last, n, pred, proj);\n\t\t\t\tif (n == iter_difference_t<I>(0)) {\n\t\t\t\t\treturn first;\n\t\t\t\t}\n\t\t\t\treturn bidirectional(first, last, n, buf, pred, proj);\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __stable_partition_n_fn stable_partition_n{};\n\t} // namespace ext\n\n\tstruct __stable_partition_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class Pred, class Proj = identity>\n\t\trequires permutable<I> && indirect_unary_predicate<Pred, projected<I, Proj>>\n\t\tI operator()(I first, S last, Pred pred, Proj proj = {}) const {\n\t\t\tif constexpr (bidirectional_iterator<I>) {\n\t\t\t\tauto [bound, n] = ext::enumerate(first, std::move(last));\n\t\t\t\treturn ext::stable_partition_n(\n\t\t\t\t\tstd::move(first), std::move(bound), n,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\tauto n = distance(first, std::move(last));\n\t\t\t\treturn ext::stable_partition_n(\n\t\t\t\t\tstd::move(first), n,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range Rng, class Pred, class Proj = identity>\n\t\trequires permutable<iterator_t<Rng>> &&\n\t\t\tindirect_unary_predicate<Pred, projected<iterator_t<Rng>, Proj>>\n\t\tsafe_iterator_t<Rng>\n\t\toperator()(Rng&& rng, Pred pred, Proj proj = {}) const {\n\t\t\tif constexpr (bidirectional_range<Rng>) {\n\t\t\t\tauto [bound, n] = ext::enumerate(rng);\n\t\t\t\treturn ext::stable_partition_n(\n\t\t\t\t\tbegin(rng), std::move(bound), n,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\treturn ext::stable_partition_n(\n\t\t\t\t\tbegin(rng), distance(rng),\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __stable_partition_fn stable_partition{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/stable_sort.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//  Copyright (c) 1994\n//  Hewlett-Packard Company\n//\n//  Permission to use, copy, modify, distribute and sell this software\n//  and its documentation for any purpose is hereby granted without fee,\n//  provided that the above copyright notice appear in all copies and\n//  that both that copyright notice and this permission notice appear\n//  in supporting documentation.  Hewlett-Packard Company makes no\n//  representations about the suitability of this software for any\n//  purpose.  It is provided \"as is\" without express or implied warranty.\n//\n//  Copyright (c) 1996\n//  Silicon Graphics Computer Systems, Inc.\n//\n//  Permission to use, copy, modify, distribute and sell this software\n//  and its documentation for any purpose is hereby granted without fee,\n//  provided that the above copyright notice appear in all copies and\n//  that both that copyright notice and this permission notice appear\n//  in supporting documentation.  Silicon Graphics makes no\n//  representations about the suitability of this software for any\n//  purpose.  It is provided \"as is\" without express or implied warranty.\n//\n#ifndef STL2_DETAIL_ALGORITHM_STABLE_SORT_HPP\n#define STL2_DETAIL_ALGORITHM_STABLE_SORT_HPP\n\n#include <stl2/detail/algorithm/inplace_merge.hpp>\n#include <stl2/detail/algorithm/merge.hpp>\n#include <stl2/detail/algorithm/min.hpp>\n#include <stl2/detail/algorithm/sort.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <stl2/detail/iterator/move_iterator.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// stable_sort [stable.sort]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __stable_sort_fn : private __niebloid {\n\t\ttemplate<random_access_iterator I, class S, class Comp = less, class Proj = identity>\n\t\trequires sentinel_for<__f<S>, I> && sortable<I, Comp, Proj>\n\t\tI operator()(I first, S&& last_, Comp comp = {}, Proj proj = {}) const {\n\t\t\tauto last = next(first, static_cast<S&&>(last_));\n\t\t\tauto len = iter_difference_t<I>(last - first);\n\t\t\tauto buf = len > 256 ? buf_t<I>{len} : buf_t<I>{};\n\t\t\tif (!buf.size()) {\n\t\t\t\tinplace_stable_sort(first, last, comp, proj);\n\t\t\t} else {\n\t\t\t\tstable_sort_adaptive(first, last, buf, comp, proj);\n\t\t\t}\n\t\t\treturn last;\n\t\t}\n\n\t\ttemplate<random_access_range R, class Comp = less, class Proj = identity>\n\t\trequires sortable<iterator_t<R>, Comp, Proj>\n\t\tsafe_iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), static_cast<Comp&&>(comp), static_cast<Proj&&>(proj));\n\t\t}\n\tprivate:\n\t\ttemplate<class I>\n\t\tusing buf_t = detail::temporary_buffer<iter_value_t<I>>;\n\n\t\tstatic constexpr int merge_sort_chunk_size = 7;\n\n\t\ttemplate<random_access_iterator I, class C, class P>\n\t\trequires sortable<I, C, P>\n\t\tstatic void inplace_stable_sort(I first, I last, C &pred, P &proj) {\n\t\t\tif (last - first < 15) {\n\t\t\t\tdetail::rsort::insertion_sort(first, last, pred, proj);\n\t\t\t} else {\n\t\t\t\tI middle = first + iter_difference_t<I>(last - first) / 2;\n\t\t\t\tinplace_stable_sort(first, middle, pred, proj);\n\t\t\t\tinplace_stable_sort(middle, last, pred, proj);\n\t\t\t\tdetail::inplace_merge_no_buffer(first, middle, last,\n\t\t\t\t\tmiddle - first, last - middle,\n\t\t\t\t\t__stl2::ref(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<random_access_iterator I, weakly_incrementable O, class C, class P>\n\t\trequires sortable<I, C, P>\n\t\tstatic void merge_sort_loop(I first, I last, O result,\n\t\t\titer_difference_t<I> step_size, C &pred, P &proj) {\n\t\t\tauto two_step = iter_difference_t<I>(2 * step_size);\n\t\t\twhile (last - first >= two_step) {\n\t\t\t\tresult = merge(\n\t\t\t\t\t__stl2::make_move_iterator(first),\n\t\t\t\t\t__stl2::make_move_iterator(first + step_size),\n\t\t\t\t\t__stl2::make_move_iterator(first + step_size),\n\t\t\t\t\t__stl2::make_move_iterator(first + two_step),\n\t\t\t\t\tresult, __stl2::ref(pred),\n\t\t\t\t\t__stl2::ref(proj), __stl2::ref(proj)).out;\n\t\t\t\tfirst += two_step;\n\t\t\t}\n\t\t\tstep_size = min(iter_difference_t<I>(last - first), step_size);\n\t\t\tmerge(\n\t\t\t\t__stl2::make_move_iterator(first),\n\t\t\t\t__stl2::make_move_iterator(first + step_size),\n\t\t\t\t__stl2::make_move_iterator(first + step_size),\n\t\t\t\t__stl2::make_move_iterator(last),\n\t\t\t\tresult, __stl2::ref(pred),\n\t\t\t\t__stl2::ref(proj), __stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<random_access_iterator I, class C, class P>\n\t\trequires sortable<I, C, P>\n\t\tstatic void chunk_insertion_sort(I first, I last,\n\t\t\titer_difference_t<I> chunk_size, C &comp, P &proj) {\n\t\t\twhile (last - first >= chunk_size) {\n\t\t\t\tdetail::rsort::insertion_sort(first, first + chunk_size, comp, proj);\n\t\t\t\tfirst += chunk_size;\n\t\t\t}\n\t\t\tdetail::rsort::insertion_sort(first, last, comp, proj);\n\t\t}\n\n\t\ttemplate<random_access_iterator I, class C, class P>\n\t\trequires sortable<I, C, P>\n\t\tstatic void merge_sort_with_buffer(I first, I last, buf_t<I>& buf, C &comp, P &proj) {\n\t\t\tauto len = iter_difference_t<I>(last - first);\n\t\t\tauto step_size = iter_difference_t<I>(merge_sort_chunk_size);\n\t\t\tchunk_insertion_sort(first, last, step_size, comp, proj);\n\t\t\tif (step_size >= len) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdetail::temporary_vector<iter_value_t<I>> vec{buf};\n\t\t\tmerge_sort_loop(first, last, __stl2::back_inserter(vec), step_size, comp, proj);\n\t\t\tstep_size *= 2;\n\t\t\twhile (true) {\n\t\t\t\tmerge_sort_loop(vec.begin(), vec.end(), first, step_size, comp, proj);\n\t\t\t\tstep_size *= 2;\n\t\t\t\tif (step_size >= len) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmerge_sort_loop(first, last, vec.begin(), step_size, comp, proj);\n\t\t\t\tstep_size *= 2;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<random_access_iterator I, class C, class P>\n\t\trequires sortable<I, C, P>\n\t\tstatic void stable_sort_adaptive(I first, I last, buf_t<I>& buf, C &comp, P &proj) {\n\t\t\tauto len = iter_difference_t<I>((last - first + 1) / 2);\n\t\t\tauto middle = first + len;\n\t\t\tif (len > buf.size()) {\n\t\t\t\tstable_sort_adaptive(first, middle, buf, comp, proj);\n\t\t\t\tstable_sort_adaptive(middle, last, buf, comp, proj);\n\t\t\t} else {\n\t\t\t\tmerge_sort_with_buffer(first, middle, buf, comp, proj);\n\t\t\t\tmerge_sort_with_buffer(middle, last, buf, comp, proj);\n\t\t\t}\n\t\t\tdetail::merge_adaptive(first, middle, last,\n\t\t\t\tmiddle - first, last - middle, buf,\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __stable_sort_fn stable_sort{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/swap_ranges.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_SWAP_RANGES_HPP\n#define STL2_DETAIL_ALGORITHM_SWAP_RANGES_HPP\n\n#include <stl2/detail/swap.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// swap_ranges [alg.swap]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2>\n\tusing swap_ranges_result = __in_in_result<I1, I2>;\n\n\tstruct __swap_ranges3_fn {\n\t\ttemplate<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2>\n\t\trequires indirectly_swappable<I1, I2>\n\t\tconstexpr swap_ranges_result<I1, I2>\n\t\toperator()(I1 first1, S1 last1, I2 first2) const {\n\t\t\tfor (; first1 != last1; (void) ++first1, (void) ++first2) {\n\t\t\t\titer_swap(first1, first2);\n\t\t\t}\n\t\t\treturn {std::move(first1), std::move(first2)};\n\t\t}\n\t};\n\n\tinline constexpr __swap_ranges3_fn __swap_ranges3{};\n\n\tstruct __swap_ranges_fn : private __niebloid {\n\t\ttemplate<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,\n\t\t\tsentinel_for<I2> S2>\n\t\trequires indirectly_swappable<I1, I2>\n\t\tconstexpr swap_ranges_result<I1, I2>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2) const {\n\t\t\tfor (; bool(first1 != last1) && bool(first2 != last2);\n\t\t\t     (void) ++first1, (void) ++first2)\n\t\t\t{\n\t\t\t\titer_swap(first1, first2);\n\t\t\t}\n\t\t\treturn {std::move(first1), std::move(first2)};\n\t\t}\n\n\t\ttemplate<forward_range R1, forward_range R2>\n\t\trequires indirectly_swappable<iterator_t<R1>, iterator_t<R2>>\n\t\tconstexpr swap_ranges_result<safe_iterator_t<R1>, safe_iterator_t<R2>>\n\t\toperator()(R1&& r1, R2&& r2) const {\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2));\n\t\t}\n\t};\n\n\tinline constexpr __swap_ranges_fn swap_ranges{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/transform.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_TRANSFORM_HPP\n#define STL2_DETAIL_ALGORITHM_TRANSFORM_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n////////////////////////////////////////////////////////////////////////////////\n// transform [alg.transform]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing unary_transform_result = __in_out_result<I, O>;\n\n\ttemplate<class I1, class I2, class O>\n\tusing binary_transform_result = __in_in_out_result<I1, I2, O>;\n\n\tstruct __transform_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O,\n\t\t\tcopy_constructible F, class Proj = identity>\n\t\trequires writable<O, indirect_result_t<F&, projected<I, Proj>>>\n\t\tconstexpr unary_transform_result<I, O>\n\t\toperator()(I first, S last, O result, F op, Proj proj = {}) const {\n\t\t\tfor (; first != last; (void) ++first, (void) ++result) {\n\t\t\t\t*result = __stl2::invoke(op, __stl2::invoke(proj, *first));\n\t\t\t}\n\t\t\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O, copy_constructible F,\n\t\t\tclass Proj = identity>\n\t\trequires writable<O, indirect_result_t<F&, projected<iterator_t<R>, Proj>>>\n\t\tconstexpr unary_transform_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result, F op, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(result), __stl2::ref(op),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\n\t\ttemplate<input_iterator I1, sentinel_for<I1> S1,\n\t\t\tinput_iterator I2, sentinel_for<I2> S2,\n\t\t\tweakly_incrementable O, copy_constructible F,\n\t\t\tclass Proj1 = identity, class Proj2 = identity>\n\t\trequires writable<O, indirect_result_t<F&,\n\t\t\tprojected<I1, Proj1>, projected<I2, Proj2>>>\n\t\tconstexpr binary_transform_result<I1, I2, O>\n\t\toperator()(I1 first1, S1 last1, I2 first2, S2 last2, O result,\n\t\t\tF op, Proj1 proj1 = {}, Proj2 proj2 = {}) const\n\t\t{\n\t\t\tfor (; bool(first1 != last1) && bool(first2 != last2);\n\t\t\t     (void) ++first1, (void) ++first2, (void) ++result)\n\t\t\t{\n\t\t\t\t*result = __stl2::invoke(op, __stl2::invoke(proj1, *first1),\n\t\t\t\t\t__stl2::invoke(proj2, *first2));\n\t\t\t}\n\t\t\treturn {std::move(first1), std::move(first2), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R1, input_range R2, weakly_incrementable O,\n\t\t\tcopy_constructible F, class Proj1 = identity, class Proj2 = identity>\n\t\trequires writable<O, indirect_result_t<F&,\n\t\t\tprojected<iterator_t<R1>, Proj1>, projected<iterator_t<R2>, Proj2>>>\n\t\tconstexpr binary_transform_result<safe_iterator_t<R1>, safe_iterator_t<R2>, O>\n\t\toperator()(R1&& r1, R2&& r2, O result, F op, Proj1 proj1 = {},\n\t\t\tProj2 proj2 = {}) const\n\t\t{\n\t\t\treturn (*this)(begin(r1), end(r1), begin(r2), end(r2), std::move(result),\n\t\t\t\t__stl2::ref(op), __stl2::ref(proj1), __stl2::ref(proj2));\n\t\t}\n\t};\n\n\tinline constexpr __transform_fn transform{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/unique.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_UNIQUE_HPP\n#define STL2_DETAIL_ALGORITHM_UNIQUE_HPP\n\n#include <stl2/detail/algorithm/adjacent_find.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// unique [alg.unique]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct __unique_fn : private __niebloid {\n\t\ttemplate<permutable I, sentinel_for<I> S, class Proj = identity,\n\t\t\tindirect_relation<projected<I, Proj>> Comp = equal_to>\n\t\tconstexpr I\n\t\toperator()(I first, S last, Comp comp = {}, Proj proj = {}) const {\n\t\t\tfirst = adjacent_find(std::move(first), last, __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t\tif (first != last) {\n\t\t\t\tfor (auto m = next(first, 2); m != last; ++m) {\n\t\t\t\t\tif (!__stl2::invoke(comp, __stl2::invoke(proj, *first),\n\t\t\t\t\t\t\t__stl2::invoke(proj, *m)))\n\t\t\t\t\t{\n\t\t\t\t\t\t*++first = iter_move(m);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t++first;\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<forward_range R, class Proj = identity,\n\t\t\tindirect_relation<projected<iterator_t<R>, Proj>> Comp = equal_to>\n\t\trequires permutable<iterator_t<R>>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, Comp comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), __stl2::ref(comp),\n\t\t\t\t__stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __unique_fn unique{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/unique_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-present\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_UNIQUE_COPY_HPP\n#define STL2_DETAIL_ALGORITHM_UNIQUE_COPY_HPP\n\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// unique_copy [alg.unique]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I, class O>\n\tusing unique_copy_result = __in_out_result<I, O>;\n\n\ttemplate<class I, class O>\n\tMETA_CONCEPT __unique_copy_helper = input_iterator<I> &&  input_iterator<O> &&\n\t\tsame_as<iter_value_t<I>, iter_value_t<O>>;\n\n\tstruct __unique_copy_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S, weakly_incrementable O,\n\t\t\tclass Proj = identity,\n\t\t\tindirect_relation<projected<I, Proj>> C = equal_to>\n\t\trequires indirectly_copyable<I, O> &&\n\t\t\t(forward_iterator<I> || __unique_copy_helper<I, O> ||\n\t\t\t indirectly_copyable_storable<I, O>)\n\t\tconstexpr unique_copy_result<I, O> operator()(I first, const S last,\n\t\t\tO result, C comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\tif (first != last) {\n\t\t\t\tauto pred = [&comp, &proj](auto&& lhs, auto&& rhs) {\n\t\t\t\t\treturn !bool(__stl2::invoke(comp,\n\t\t\t\t\t\t__stl2::invoke(proj, std::forward<decltype(lhs)>(lhs)),\n\t\t\t\t\t\t__stl2::invoke(proj, std::forward<decltype(rhs)>(rhs))));\n\t\t\t\t};\n\t\t\t\tif constexpr (forward_iterator<I>) {\n\t\t\t\t\t*result = *first;\n\t\t\t\t\t++result;\n\t\t\t\t\tauto m = first;\n\t\t\t\t\twhile (++first != last) {\n\t\t\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\t\t\tif (pred(std::forward<iter_reference_t<I>>(v), *m)) {\n\t\t\t\t\t\t\t*result = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t\t\t\t++result;\n\t\t\t\t\t\t\tm = first;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if constexpr (__unique_copy_helper<I, O>) {\n\t\t\t\t\t*result = *first;\n\t\t\t\t\twhile (++first != last) {\n\t\t\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\t\t\tif (pred(std::forward<iter_reference_t<I>>(v), *result)) {\n\t\t\t\t\t\t\t*++result = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t++result;\n\t\t\t\t} else { // indirectly_copyable_storable<I, O>\n\t\t\t\t\titer_value_t<I> saved = *first;\n\t\t\t\t\t*result = saved;\n\t\t\t\t\t++result;\n\t\t\t\t\twhile (++first != last) {\n\t\t\t\t\t\titer_reference_t<I>&& v = *first;\n\t\t\t\t\t\tif (pred(std::forward<iter_reference_t<I>>(v), saved)) {\n\t\t\t\t\t\t\tsaved = std::forward<iter_reference_t<I>>(v);\n\t\t\t\t\t\t\t*result = saved;\n\t\t\t\t\t\t\t++result;\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\treturn {std::move(first), std::move(result)};\n\t\t}\n\n\t\ttemplate<input_range R, weakly_incrementable O, class Proj = identity,\n\t\t\tindirect_relation<projected<iterator_t<R>, Proj>> C = equal_to>\n\t\trequires indirectly_copyable<iterator_t<R>, O> &&\n\t\t\t(forward_range<R> || __unique_copy_helper<iterator_t<R>, O> ||\n\t\t\t indirectly_copyable_storable<iterator_t<R>, O>)\n\t\tconstexpr unique_copy_result<safe_iterator_t<R>, O>\n\t\toperator()(R&& r, O result, C comp = {}, Proj proj = {}) const {\n\t\t\treturn (*this)(begin(r), end(r), std::move(result),\n\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t}\n\t};\n\n\tinline constexpr __unique_copy_fn unique_copy{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/algorithm/upper_bound.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ALGORITHM_UPPER_BOUND_HPP\n#define STL2_DETAIL_ALGORITHM_UPPER_BOUND_HPP\n\n#include <stl2/detail/algorithm/partition_point.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// upper_bound [upper.bound]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\tstruct __upper_bound_n_fn {\n\t\t\ttemplate<class I, class T, class Comp = less, class Proj = identity>\n\t\t\trequires forward_iterator<__f<I>> &&\n\t\t\t\tindirect_strict_weak_order<Comp, const T*, projected<__f<I>, Proj>>\n\t\t\tconstexpr __f<I> operator()(I&& first_, iter_difference_t<__f<I>> n,\n\t\t\t\tconst T& value, Comp comp = {}, Proj proj = {}) const\n\t\t\t{\n\t\t\t\tauto pred = [&](auto&& i) {\n\t\t\t\t\treturn !__stl2::invoke(comp, value, i);\n\t\t\t\t};\n\t\t\t\treturn ext::partition_point_n(std::forward<I>(first_), n,\n\t\t\t\t\tstd::move(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __upper_bound_n_fn upper_bound_n{};\n\t}\n\n\tstruct __upper_bound_fn : private __niebloid {\n\t\ttemplate<forward_iterator I, sentinel_for<I> S, class T,\n\t\t\tclass Proj = identity,\n\t\t\tindirect_strict_weak_order<const T*, projected<I, Proj>> Comp = less>\n\t\tconstexpr I operator()(I first, S last, const T& value,\n\t\t\tComp comp = {}, Proj proj = {}) const\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\tauto n = distance(first, std::move(last));\n\t\t\t\treturn ext::upper_bound_n(std::move(first), n, value,\n\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\tauto pred = [&](auto&& i) {\n\t\t\t\t\treturn !__stl2::invoke(comp, value, i);\n\t\t\t\t};\n\t\t\t\treturn partition_point(std::move(first), std::move(last),\n\t\t\t\t\tstd::move(pred), __stl2::ref(proj));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<forward_range R, class T, class Proj = identity,\n\t\t\tindirect_strict_weak_order<const T*,\n\t\t\t\tprojected<iterator_t<R>, Proj>> Comp = less>\n\t\tconstexpr safe_iterator_t<R>\n\t\toperator()(R&& r, const T& value, Comp comp = {}, Proj proj = {}) const {\n\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\treturn ext::upper_bound_n(begin(r), distance(r), value,\n\t\t\t\t\t__stl2::ref(comp), __stl2::ref(proj));\n\t\t\t} else {\n\t\t\t\treturn (*this)(begin(r), end(r), value, __stl2::ref(comp),\n\t\t\t\t\t__stl2::ref(proj));\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __upper_bound_fn upper_bound{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/cached_position.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\r\n//\r\n//  Copyright Casey Carter 2018\r\n//\r\n//  Use, modification and distribution is subject to the\r\n//  Boost Software License, Version 1.0. (See accompanying\r\n//  file LICENSE_1_0.txt or copy at\r\n//  http://www.boost.org/LICENSE_1_0.txt)\r\n//\r\n// Project home: https://github.com/caseycarter/cmcstl2\r\n//\r\n\r\n#ifndef STL2_DETAIL_CACHED_POSITION_HPP\r\n#define STL2_DETAIL_CACHED_POSITION_HPP\r\n\r\n#include <stl2/detail/fwd.hpp>\r\n#include <stl2/detail/swap.hpp>\r\n#include <stl2/detail/non_propagating_cache.hpp>\r\n#include <stl2/detail/iterator/operations.hpp>\r\n#include <stl2/detail/range/concepts.hpp>\r\n\r\nSTL2_OPEN_NAMESPACE {\r\n\tnamespace detail {\r\n\t\t/// \\addtogroup group-utility\r\n\t\t/// @{\r\n\r\n\t\t/// \\brief Caches a position in a range.\r\n\t\ttemplate<range R, class Tag = void, bool Enable = true>\r\n\t\tstruct cached_position {\r\n\t\t\t/// \\brief Returns `true` if and only if a position is cached.\r\n\t\t\tconstexpr explicit operator bool() const noexcept {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t\t/// \\brief Retrieves an `iterator_t<R>` denoting the cached position.\r\n\t\t\t///\r\n\t\t\t/// \\pre `*this` caches a position within the \\c range `r`.\r\n\t\t\t[[noreturn]] iterator_t<R> get(R& r) const {\r\n\t\t\t\t(void) r;\r\n\t\t\t\tSTL2_EXPECT(false);\r\n\t\t\t}\r\n\t\t\t/// \\brief Caches the position of the `iterator_t<R>` argument.\r\n\t\t\t///\r\n\t\t\t/// \\pre The \\c input_or_output_iterator `it` denotes a position in \\c range r.\r\n\t\t\tconstexpr void set(R& r, const iterator_t<R>& it) {\r\n\t\t\t\t(void) r;\r\n\t\t\t\t(void) it;\r\n\t\t\t}\r\n\t\t};\r\n\t\t/// @}\r\n\r\n\t\t/// \\cond\r\n\t\ttemplate<range R, class Tag>\r\n\t\tstruct cached_position<R, Tag, true> {\r\n\t\t\tconstexpr explicit operator bool() const noexcept {\r\n\t\t\t\treturn static_cast<bool>(cache_);\r\n\t\t\t}\r\n\t\t\tconstexpr iterator_t<R> get(R&) const {\r\n\t\t\t\tSTL2_EXPECT(*this);\r\n\t\t\t\treturn *cache_;\r\n\t\t\t}\r\n\t\t\tconstexpr void set(R&, const iterator_t<R>& it) {\r\n\t\t\t\tcache_ = it;\r\n\t\t\t}\r\n\t\tprivate:\r\n\t\t\tmeta::if_c<_ForwardingRange<R>,\r\n\t\t\t\tstd::optional<iterator_t<R>>,\r\n\t\t\t\tnon_propagating_cache<iterator_t<R>>> cache_;\r\n\t\t};\r\n\t\ttemplate<random_access_range R, class Tag>\r\n\t\tstruct cached_position<R, Tag, true> {\r\n\t\t\tcached_position() = default;\r\n\t\t\tcached_position(const cached_position&) = default;\r\n\t\t\tcached_position(cached_position&& that)\r\n\t\t\t: offset_{__stl2::exchange(that.offset_, -1)} {}\r\n\t\t\tcached_position& operator=(const cached_position&) = default;\r\n\t\t\tcached_position& operator=(cached_position&& that) {\r\n\t\t\t\toffset_ = __stl2::exchange(that.offset_, -1);\r\n\t\t\t\treturn *this;\r\n\t\t\t}\r\n\r\n\t\t\tconstexpr explicit operator bool() const noexcept {\r\n\t\t\t\treturn offset_ >= 0;\r\n\t\t\t}\r\n\t\t\tconstexpr iterator_t<R> get(R& r) const {\r\n\t\t\t\tSTL2_EXPECT(*this);\r\n\t\t\t\treturn begin(r) + offset_;\r\n\t\t\t}\r\n\t\t\tconstexpr void set(R& r, const iterator_t<R>& it) {\r\n\t\t\t\toffset_ = it - begin(r);\r\n\t\t\t}\r\n\t\tprivate:\r\n\t\t\titer_difference_t<iterator_t<R>> offset_ = -1;\r\n\t\t};\r\n\t\t/// \\endcond\r\n\t}\r\n} STL2_CLOSE_NAMESPACE\r\n\r\n#endif\r\n"
  },
  {
    "path": "include/stl2/detail/cheap_storage.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CHEAP_STORAGE_HPP\n#define STL2_DETAIL_CHEAP_STORAGE_HPP\n\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tconstexpr std::size_t cheap_copy_size = 32;\n\n\t\ttemplate<class>\n\t\tconstexpr bool cheaply_copyable = false;\n\t\ttemplate<class T>\n\t\trequires\n\t\t\tcopy_constructible<T> &&\n\t\t\tstd::is_trivially_copyable<T>::value &&\n\t\t\t((std::is_empty_v<T> && !std::is_final_v<T>) ||\n\t\t\t\tsizeof(T) <= cheap_copy_size)\n\t\tconstexpr bool cheaply_copyable<T> = true;\n\n\t\ttemplate<ext::object T, class Tag = void>\n\t\tclass ref_box {\n\t\tpublic:\n\t\t\tref_box() = default;\n\t\t\tconstexpr ref_box(T& t) noexcept\n\t\t\t: ptr_{&t} {}\n\t\t\tref_box(T&&) = delete;\n\n\t\t\tconstexpr T& get() const noexcept {\n\t\t\t\treturn *ptr_;\n\t\t\t}\n\n\t\tprivate:\n\t\t\traw_ptr<T> ptr_;\n\t\t};\n\n\t\t// Note: promotes to copy_constructible\n\t\ttemplate<ext::object T, class Tag = void>\n\t\tusing cheap_reference_box_t = meta::if_c<\n\t\t\tcheaply_copyable<remove_cv_t<T>>,\n\t\t\tebo_box<remove_cv_t<T>, Tag>,\n\t\t\tref_box<T, Tag>>;\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/callable.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_CALLABLE_HPP\n#define STL2_DETAIL_CONCEPTS_CALLABLE_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/function.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/functional/invoke.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t////////////////////////////////////////////////////////////////////////////\n\t// Indirect callables [indirectcallable.indirectinvocable]\n\t//\n\ttemplate<class... T>\n\tstruct __common_reference\n\t: meta::bool_<sizeof...(T) == 1> {};\n\n\ttemplate<class T, class U, class... Rest>\n\trequires common_reference_with<T, U>\n\tstruct __common_reference<T, U, Rest...>\n\t: __common_reference<common_reference_t<T, U>, Rest...> {};\n\n\ttemplate<readable... Is>\n\tusing __iter_args_lists_ =\n\t\tmeta::push_back<\n\t\t\tmeta::cartesian_product<\n\t\t\t\tmeta::list<meta::list<iter_value_t<Is>&, iter_reference_t<Is>>...>>,\n\t\t\tmeta::list<iter_common_reference_t<Is>...>>;\n\ttemplate<class... Is>\n\tusing __iter_args_lists = __iter_args_lists_<Is...>;\n\n\ttemplate<typename MapFn, typename ReduceFn>\n\tusing __iter_map_reduce_fn =\n\t\tmeta::compose<\n\t\t\tmeta::uncurry<meta::on<ReduceFn, meta::uncurry<MapFn>>>,\n\t\t\tmeta::quote<__iter_args_lists>>;\n\n\ttemplate<class F, class... Args>\n\trequires invocable<F, Args...>\n\tusing __callable_result_t = invoke_result_t<F, Args...>;\n\n\tnamespace ext {\n\t\ttemplate<class F, class... Is>\n\t\tMETA_CONCEPT indirect_invocable =\n\t\t\t(readable<Is> && ... && true) &&\n\t\t\tcopy_constructible<F> &&\n\t\t\t// The following 3 are checked redundantly, but are called out\n\t\t\t// specifically for better error messages on concept check failure.\n\t\t\tinvocable<F&, iter_value_t<Is>&...> &&\n\t\t\tinvocable<F&, iter_reference_t<Is>...> &&\n\t\t\tinvocable<F&, iter_common_reference_t<Is>...> &&\n\t\t\t// redundantly checks the above 3 requirements\n\t\t\tmeta::_v<meta::invoke<\n\t\t\t\t__iter_map_reduce_fn<\n\t\t\t\t\tmeta::bind_front<meta::quote<__callable_result_t>, F&>,\n\t\t\t\t\tmeta::quote<__common_reference>>,\n\t\t\t\tIs...>>;\n\t}\n\n\ttemplate<class F, class I>\n\tMETA_CONCEPT indirect_unary_invocable =\n\t\text::indirect_invocable<F, I>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// indirect_result_t\n\t//\n\ttemplate<class F, class... Is>\n\trequires (readable<Is> && ...) && invocable<F, iter_reference_t<Is>...>\n\tusing indirect_result_t = invoke_result_t<F, iter_reference_t<Is>&&...>;\n\n\tnamespace ext {\n\t\ttemplate<class F, class... Is>\n\t\tMETA_CONCEPT indirect_regular_invocable =\n\t\t\tindirect_invocable<F, Is...>;\n\t}\n\n\ttemplate<class F, class I>\n\tMETA_CONCEPT indirect_regular_unary_invocable =\n\t\text::indirect_regular_invocable<F, I>;\n\n\ttemplate<class, class...> struct __predicate : std::false_type {};\n\ttemplate<class F, class... Args>\n\trequires predicate<F, Args...>\n\tstruct __predicate<F, Args...> : std::true_type {};\n\n\tnamespace ext {\n\t\ttemplate<class F, class... Is>\n\t\tMETA_CONCEPT indirect_predicate =\n\t\t\t(readable<Is> && ... && true) &&\n\t\t\tcopy_constructible<F> &&\n\t\t\t// The following 3 are checked redundantly, but are called out\n\t\t\t// specifically for better error messages on concept check failure.\n\t\t\tpredicate<F&, iter_value_t<Is>&...> &&\n\t\t\tpredicate<F&, iter_reference_t<Is>...> &&\n\t\t\tpredicate<F&, iter_common_reference_t<Is>...> &&\n\t\t\t// redundantly checks the above 3 requirements\n\t\t\tmeta::_v<meta::invoke<\n\t\t\t\t__iter_map_reduce_fn<\n\t\t\t\t\tmeta::bind_front<meta::quote<__predicate>, F&>,\n\t\t\t\t\tmeta::quote<meta::strict_and>>,\n\t\t\t\tIs...>>;\n\t}\n\n\ttemplate<class F, class I>\n\tMETA_CONCEPT indirect_unary_predicate =\n\t\text::indirect_predicate<F, I>;\n\n\ttemplate<class F, class I1, class I2 = I1>\n\tMETA_CONCEPT indirect_relation =\n\t\treadable<I1> &&\n\t\treadable<I2> &&\n\t\tcopy_constructible<F> &&\n\t\trelation<F&, iter_value_t<I1>&, iter_value_t<I2>&> &&\n\t\trelation<F&, iter_value_t<I1>&, iter_reference_t<I2>> &&\n\t\trelation<F&, iter_reference_t<I1>, iter_value_t<I2>&> &&\n\t\trelation<F&, iter_reference_t<I1>, iter_reference_t<I2>> &&\n\t\trelation<F&, iter_common_reference_t<I1>, iter_common_reference_t<I2>>;\n\n\ttemplate<class F, class I1, class I2 = I1>\n\tMETA_CONCEPT indirect_strict_weak_order =\n\t\treadable<I1> &&\n\t\treadable<I2> &&\n\t\tcopy_constructible<F> &&\n\t\tstrict_weak_order<F&, iter_value_t<I1>&, iter_value_t<I2>&> &&\n\t\tstrict_weak_order<F&, iter_value_t<I1>&, iter_reference_t<I2>> &&\n\t\tstrict_weak_order<F&, iter_reference_t<I1>, iter_value_t<I2>&> &&\n\t\tstrict_weak_order<F&, iter_reference_t<I1>, iter_reference_t<I2>> &&\n\t\tstrict_weak_order<F&, iter_common_reference_t<I1>, iter_common_reference_t<I2>>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// projected [projected.indirectcallables]\n\t//\n\ttemplate<readable I, indirect_regular_unary_invocable<I> Proj>\n\tstruct projected {\n\t\tusing value_type = __uncvref<indirect_result_t<Proj&, I>>;\n\t\tindirect_result_t<Proj&, I> operator*() const;\n\t};\n\n\ttemplate<weakly_incrementable I, class Proj>\n\tstruct incrementable_traits<projected<I, Proj>> {\n\t\tusing type = iter_difference_t<I>;\n\t};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// indirectly_comparable [alg.req.ind.cmp]\n\t//\n\ttemplate<class I1, class I2, class R = equal_to, class P1 = identity,\n\t\tclass P2 = identity>\n\tMETA_CONCEPT indirectly_comparable =\n\t\tindirect_relation<R, projected<I1, P1>, projected<I2, P2>>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// permutable [alg.req.permutable]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT permutable = forward_iterator<I> &&\n\t\tindirectly_movable_storable<I, I> && indirectly_swappable<I, I>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// mergeable [alg.req.mergeable]\n\t//\n\ttemplate<class I1, class I2, class Out, class R = less,\n\t\tclass P1 = identity, class P2 = identity>\n\tMETA_CONCEPT mergeable = input_iterator<I1> && input_iterator<I2> &&\n\t\tweakly_incrementable<Out> &&\n\t\tindirectly_copyable<I1, Out> && indirectly_copyable<I2, Out> &&\n\t\tindirect_strict_weak_order<R, projected<I1, P1>, projected<I2, P2>>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// sortable [alg.req.sortable]\n\t//\n\ttemplate<class I, class R = less, class P = identity>\n\tMETA_CONCEPT sortable = permutable<I> &&\n\t\tindirect_strict_weak_order<R, projected<I, P>>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/compare.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_COMPARE_HPP\n#define STL2_DETAIL_CONCEPTS_COMPARE_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object/movable.hpp>\n\n/////////////////////////////////////////////\n// Comparison Concepts [concepts.lib.compare]\n//\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// boolean [concepts.lib.compare.boolean]\n\t//\n\ttemplate<class B>\n\tMETA_CONCEPT boolean =\n\t\tmovable<std::decay_t<B>> &&\n\t\trequires(const std::remove_reference_t<B>& b1,\n\t\t\t     const std::remove_reference_t<B>& b2, const bool a) {\n#ifdef META_HAS_P1084\n\t\t\t// Requirements common to both boolean and BooleanTestable.\n\t\t\t{  b1      } -> convertible_to<bool>;\n\t\t\t{ !b1      } -> convertible_to<bool>;\n\t\t\t{  b1 && a } -> same_as<bool>;\n\t\t\t{  b1 || a } -> same_as<bool>;\n\n\t\t\t// Requirements of boolean that are also be valid for\n\t\t\t// BooleanTestable, but for which BooleanTestable does not\n\t\t\t// require validation.\n\t\t\t{ b1 && b2 } -> same_as<bool>;\n\t\t\t{  a && b2 } -> same_as<bool>;\n\t\t\t{ b1 || b2 } -> same_as<bool>;\n\t\t\t{  a || b2 } -> same_as<bool>;\n\n\t\t\t// Requirements of boolean that are not required by\n\t\t\t// BooleanTestable.\n\t\t\t{ b1 == b2 } -> convertible_to<bool>;\n\t\t\t{ b1 == a  } -> convertible_to<bool>;\n\t\t\t{  a == b2 } -> convertible_to<bool>;\n\t\t\t{ b1 != b2 } -> convertible_to<bool>;\n\t\t\t{ b1 != a  } -> convertible_to<bool>;\n\t\t\t{  a != b2 } -> convertible_to<bool>;\n#else\n\t\t\t// Requirements common to both boolean and BooleanTestable.\n\t\t\t b1     ; requires convertible_to<decltype(( b1)), bool>;\n\t\t\t!b1     ; requires convertible_to<decltype((!b1)), bool>;\n\t\t\t b1 && a; requires same_as<decltype((b1 && a)), bool>;\n\t\t\t b1 || a; requires same_as<decltype((b1 || a)), bool>;\n\n\t\t\t// Requirements of boolean that are also be valid for\n\t\t\t// BooleanTestable, but for which BooleanTestable does not\n\t\t\t// require validation.\n\t\t\tb1 && b2; requires same_as<decltype((b1 && b2)), bool>;\n\t\t\t a && b2; requires same_as<decltype(( a && b2)), bool>;\n\t\t\tb1 || b2; requires same_as<decltype((b1 || b2)), bool>;\n\t\t\t a || b2; requires same_as<decltype(( a || b2)), bool>;\n\n\t\t\t// Requirements of boolean that are not required by\n\t\t\t// BooleanTestable.\n\t\t\tb1 == b2; requires convertible_to<decltype((b1 == b2)), bool>;\n\t\t\tb1 == a ; requires convertible_to<decltype((b1 == a )), bool>;\n\t\t\t a == b2; requires convertible_to<decltype(( a == b2)), bool>;\n\t\t\tb1 != b2; requires convertible_to<decltype((b1 != b2)), bool>;\n\t\t\tb1 != a ; requires convertible_to<decltype((b1 != a )), bool>;\n\t\t\t a != b2; requires convertible_to<decltype(( a != b2)), bool>;\n#endif // META_HAS_P1084\n\t\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// WeaklyEqualityComparable [concepts.lib.compare.equalitycomparable]\n\t// Relaxation of equality_comparable<T, U> that doesn't require\n\t// equality_comparable<T>, equality_comparable<U>, common_with<T, U>, or\n\t// equality_comparable<common_type_t<T, U>>. I.e., provides exactly the\n\t// requirements for sentinel_for's operator ==.\n\t//\n\ttemplate<class T, class U>\n\tMETA_CONCEPT WeaklyEqualityComparable =\n\t\trequires(const std::remove_reference_t<T>& t,\n\t\t\t\t const std::remove_reference_t<U>& u) {\n#ifdef META_HAS_P1084\n\t\t\t{ t == u } -> boolean;\n\t\t\t{ t != u } -> boolean;\n\t\t\t{ u == t } -> boolean;\n\t\t\t{ u != t } -> boolean;\n#else\n\t\t\tt == u; requires boolean<decltype((t == u))>;\n\t\t\tt != u; requires boolean<decltype((t != u))>;\n\t\t\tu == t; requires boolean<decltype((u == t))>;\n\t\t\tu != t; requires boolean<decltype((u != t))>;\n#endif // META_HAS_P1084\n\t\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// equality_comparable [concepts.lib.compare.equalitycomparable]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT equality_comparable =\n\t\tWeaklyEqualityComparable<T, T>;\n\n\ttemplate<class T, class U>\n\tMETA_CONCEPT equality_comparable_with =\n\t\tequality_comparable<T> &&\n\t\tequality_comparable<U> &&\n\t\tWeaklyEqualityComparable<T, U> &&\n\t\tcommon_reference_with<\n\t\t\tconst std::remove_reference_t<T>&,\n\t\t\tconst std::remove_reference_t<U>&> &&\n\t\tequality_comparable<\n\t\t\tcommon_reference_t<\n\t\t\t\tconst std::remove_reference_t<T>&,\n\t\t\t\tconst std::remove_reference_t<U>&>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// totally_ordered [concepts.lib.compare.stricttotallyordered]\n\t//\n\ttemplate<class T, class U>\n\tMETA_CONCEPT __totally_ordered =\n\t\trequires(const std::remove_reference_t<T>& t,\n\t\t         const std::remove_reference_t<U>& u) {\n#ifdef META_HAS_P1084\n\t\t\t{ t <  u } -> boolean;\n\t\t\t{ t >  u } -> boolean;\n\t\t\t{ t <= u } -> boolean;\n\t\t\t{ t >= u } -> boolean;\n#else\n\t\t\tt <  u; requires boolean<decltype((t <  u))>;\n\t\t\tt >  u; requires boolean<decltype((t >  u))>;\n\t\t\tt <= u; requires boolean<decltype((t <= u))>;\n\t\t\tt >= u; requires boolean<decltype((t >= u))>;\n#endif // META_HAS_P1084\n\t\t\t// Axiom: t < u, t > u, t <= u, t >= u have the same definition space.\n\t\t\t// Axiom: If bool(t < u) then bool(t <= u)\n\t\t\t// Axiom: If bool(t > u) then bool(t >= u)\n\t\t\t// Axiom: Exactly one of bool(t < u), bool(t > u), or\n\t\t\t//        (bool(t <= u) && bool(t >= u)) is true\n\t\t};\n\n\ttemplate<class T>\n\tMETA_CONCEPT totally_ordered =\n\t\tequality_comparable<T> && __totally_ordered<T, T>;\n\t\t// Axiom: t1 == t2 and t1 < t2 have the same definition space.\n\t\t// Axiom: bool(t <= t)\n\n\ttemplate<class T, class U>\n\tMETA_CONCEPT totally_ordered_with =\n\t\ttotally_ordered<T> &&\n\t\ttotally_ordered<U> &&\n\t\tequality_comparable_with<T, U> &&\n\t\t__totally_ordered<T, U> &&\n\t\t__totally_ordered<U, T> &&\n\t\tcommon_reference_with<\n\t\t\tconst std::remove_reference_t<T>&,\n\t\t\tconst std::remove_reference_t<U>&> &&\n\t\ttotally_ordered<\n\t\t\tcommon_reference_t<\n\t\t\t\tconst std::remove_reference_t<T>&,\n\t\t\t\tconst std::remove_reference_t<U>&>>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/core.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_CORE_HPP\n#define STL2_DETAIL_CONCEPTS_CORE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n\n///////////////////////////////////////////////////////////////////////////////\n// Language-related Concepts [concepts.lang]\n//\nSTL2_OPEN_NAMESPACE {\n\t// U is a cv/ref-qualified specialization of class template T.\n\ttemplate<class U, template<class...> class T>\n\tMETA_CONCEPT _SpecializationOf =\n\t\tMETA_CONCEPT_BARRIER(meta::is_v<__uncvref<U>, T>);\n\n\ttemplate<class T>\n\tusing __with_reference = T&;\n\ttemplate<class T>\n\tMETA_CONCEPT __can_reference = requires { typename __with_reference<T>; };\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// same_as\n\t//\n\ttemplate<class T, class U>\n\tMETA_CONCEPT same_as = meta::Same<T, U> && meta::Same<U, T>;\n\n\ttemplate<class T>\n\tMETA_CONCEPT _Decayed = meta::Same<T, std::decay_t<T>>;\n\n\ttemplate<class T, class... Args>\n\tMETA_CONCEPT _OneOf = (meta::Same<T, Args> || ...);\n\n\ttemplate<class T, class U>\n\tMETA_CONCEPT _NotSameAs = !meta::Same<__uncvref<T>, __uncvref<U>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// derived_from\n\t//\n\ttemplate<class Derived, class Base>\n\tMETA_CONCEPT derived_from =\n\t\tMETA_CONCEPT_BARRIER(STL2_IS_BASE(Base, Derived)) &&\n\t\tMETA_CONCEPT_BARRIER(STL2_IS_CONVERTIBLE(\n\t\t\tconst volatile Derived*, const volatile Base*));\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// convertible_to\n\t//\n\ttemplate<class From, class To>\n\tMETA_CONCEPT convertible_to =\n\t\tMETA_CONCEPT_BARRIER(STL2_IS_CONVERTIBLE(From, To)) &&\n#if 1 // This is the PR for https://wg21.link/lwg3151\n\t\trequires {\n\t\t\tstatic_cast<To>(std::declval<From>());\n\t\t};\n#else\n\t\trequires(From (&f)()) {\n\t\t\tstatic_cast<To>(f());\n\t\t};\n#endif\n\t\t// Axiom: implicit and explicit conversion have equal results.\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/function.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_FUNCTION_HPP\n#define STL2_DETAIL_CONCEPTS_FUNCTION_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/functional/invoke.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// invocable Concepts [concepts.lib.callables]\n//\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// invocable [concepts.lib.callables.callable]\n\t//\n\ttemplate<class F, class... Args>\n\tMETA_CONCEPT invocable =\n\t\trequires(F&& f, Args&&... args) {\n\t\t\t__stl2::invoke((F&&)f, (Args&&)args...);\n\t\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// regular_invocable [concepts.lib.callables.regularcallable]\n\t//\n\ttemplate<class F, class... Args>\n\tMETA_CONCEPT regular_invocable = invocable<F, Args...>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// predicate [concepts.lib.callables.predicate]\n\t//\n\ttemplate<class F, class... Args>\n\tMETA_CONCEPT predicate =\n\t\tregular_invocable<F, Args...> && boolean<invoke_result_t<F, Args...>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// relation [concepts.lib.callables.relation]\n\t//\n\ttemplate<class R, class T, class U>\n\tMETA_CONCEPT relation =\n\t\tpredicate<R, T, T> &&\n\t\tpredicate<R, U, U> &&\n\t\tpredicate<R, T, U> &&\n\t\tpredicate<R, U, T> &&\n\t\tcommon_reference_with<\n\t\t\tconst std::remove_reference_t<T>&,\n\t\t\tconst std::remove_reference_t<U>&> &&\n\t\tpredicate<\n\t\t\tR,\n\t\t\tcommon_reference_t<\n\t\t\t\tconst std::remove_reference_t<T>&,\n\t\t\t\tconst std::remove_reference_t<U>&>,\n\t\t\tcommon_reference_t<\n\t\t\t\tconst std::remove_reference_t<T>&,\n\t\t\t\tconst std::remove_reference_t<U>&>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// strict_weak_order [concepts.lib.callables.strictweakorder]\n\t//\n\ttemplate<class R, class T, class U>\n\tMETA_CONCEPT strict_weak_order = relation<R, T, U>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/fundamental.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_FUNDAMENTAL_HPP\n#define STL2_DETAIL_CONCEPTS_FUNDAMENTAL_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// Scalar [Extension]\n\t//\n\tnamespace ext {\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT Scalar =\n\t\t\tstd::is_scalar_v<T> && regular<T>;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Arithmetic [Extension]\n\t//\n\tnamespace ext {\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT Arithmetic =\n\t\t\tstd::is_arithmetic_v<T> && Scalar<T> && totally_ordered<T>;\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// floating_point\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT floating_point =\n\t\tstd::is_floating_point_v<T> && ext::Arithmetic<T>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// integral [concepts.lib.corelang.integral]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT integral =\n\t\tstd::is_integral_v<T> && ext::Arithmetic<T>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// signed_integral [concepts.lib.corelang.signedintegral]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT signed_integral =\n\t\tintegral<T> && (T(-1) < T(0));\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// unsigned_integral [concepts.lib.corelang.unsignedintegral]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT unsigned_integral =\n\t\tintegral<T> && !signed_integral<T>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/object/assignable.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_OBJECT_ASSIGNABLE_HPP\n#define STL2_DETAIL_CONCEPTS_OBJECT_ASSIGNABLE_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// assignable_from [concepts.lib.corelang.assignable]\n\t//\n\ttemplate<class LHS, class RHS>\n\tMETA_CONCEPT assignable_from =\n\t\tstd::is_lvalue_reference_v<LHS> &&\n#if 0 // TODO: investigate making this change\n\t\tcommon_reference_with<LHS, RHS> &&\n#else\n\t\tcommon_reference_with<\n\t\t\tconst std::remove_reference_t<LHS>&,\n\t\t\tconst std::remove_reference_t<RHS>&> &&\n#endif\n\t\trequires(LHS lhs, RHS&& rhs) {\n#ifdef META_HAS_P1084\n\t\t\t{ lhs = static_cast<RHS&&>(rhs) } -> same_as<LHS>;\n#else\n\t\t\tlhs = static_cast<RHS&&>(rhs); requires same_as<decltype(lhs = static_cast<RHS&&>(rhs)), LHS>;\n#endif // META_HAS_P1084\n\t\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/object/movable.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_OBJECT_MOVABLE_HPP\n#define STL2_DETAIL_CONCEPTS_OBJECT_MOVABLE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/swap.hpp>\n#include <stl2/detail/concepts/object/assignable.hpp>\n#include <stl2/detail/concepts/object/move_constructible.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// movable [concepts.lib.object.movable]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT movable =\n\t\tstd::is_object_v<T> && move_constructible<T> &&\n\t\tassignable_from<T&, T> && swappable<T>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/object/move_constructible.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_OBJECT_MOVE_CONSTRUCTIBLE_HPP\n#define STL2_DETAIL_CONCEPTS_OBJECT_MOVE_CONSTRUCTIBLE_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// object [Extension]\n\t//\n\tnamespace ext {\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT object = std::is_object_v<T>;\n\t} // namespace ext\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// destructible [concept.destructible]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT destructible = std::is_nothrow_destructible_v<T>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// constructible_from [concept.constructible]\n\t//\n\ttemplate<class T, class... Args>\n\tMETA_CONCEPT constructible_from =\n\t\tdestructible<T> && std::is_constructible_v<T, Args...>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// default_initializable [concept.defaultconstructible]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT default_initializable = constructible_from<T>\n#if !STL2_WORKAROUND_GCC_UNKNOWN0 // Implement P/R for LWG 3149\n\t\t&& requires { T{}; } // && is-default-initializable<T>\n#endif // LWG 3149\n\t\t;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// move_constructible [concept.moveconstructible]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT move_constructible = constructible_from<T, T> && convertible_to<T, T>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/object/regular.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_REGULAR_HPP\n#define STL2_DETAIL_CONCEPTS_REGULAR_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/object/semiregular.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// regular [concepts.lib.object.regular]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT regular = semiregular<T> && equality_comparable<T>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/object/semiregular.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_OBJECT_SEMIREGULAR_HPP\n#define STL2_DETAIL_CONCEPTS_OBJECT_SEMIREGULAR_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object/assignable.hpp>\n#include <stl2/detail/concepts/object/movable.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// copy_constructible [concepts.lib.object.copyconstructible]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT copy_constructible =\n\t\tmove_constructible<T> &&\n\t\tconstructible_from<T, T&> && convertible_to<T&, T> &&\n\t\tconstructible_from<T, const T&> && convertible_to<const T&, T> &&\n\t\tconstructible_from<T, const T> && convertible_to<const T, T>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// copyable [concepts.lib.object.copyable]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT copyable =\n\t\tcopy_constructible<T> && movable<T> && assignable_from<T&, const T&>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// semiregular [concepts.lib.object.semiregular]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT semiregular = copyable<T> && default_initializable<T>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/object.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_OBJECT_HPP\n#define STL2_DETAIL_CONCEPTS_OBJECT_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object/assignable.hpp>\n#include <stl2/detail/concepts/object/regular.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// __f [Implementation detail, at least for now]\n\t//\n\t// Utility alias that simplifies the specification of forwarding functions\n\t// whose target will eventually accept a parameter by value. E.g., the\n\t// range overload of find:\n\t//\n\t//   template<input_range Rng, class T, class Proj = identity>\n\t//     requires indirect_relation<equal_to,\n\t//                projected<iterator_t<Rng>, Proj>, const T*>()\n\t//   safe_iterator_t<Rng>\n\t//   find(Rng&& rng, const T& value, Proj proj = {});\n\t//\n\t// can be implemented to perfect-forward to the iterator overload as:\n\t//\n\t//   template<input_range Rng, class T, class Proj = identity>\n\t//     requires indirect_relation<equal_to,\n\t//                projected<iterator_t<Rng>, __f<Proj>>, // NW: __f<Proj>\n\t//                const T*>()\n\t//   safe_iterator_t<Rng>\n\t//   find(Rng&& rng, const T& value, Proj&& proj = {}) {\n\t//     return find(begin(rng), end(rng), value, std::forward<Proj>(proj));\n\t//   }\n\t//\n\t// __f<Proj> is an alias for the decayed type that will eventually\n\t// be used in the target function, and its constraints ensure that\n\t// the decayed type can in fact be constructed from the actual type.\n\t//\n\ttemplate<class T>\n\t\trequires constructible_from<std::decay_t<T>, T>\n\tusing __f = std::decay_t<T>;\n\n\tnamespace ext {\n\t\t///////////////////////////////////////////////////////////////////////////\n\t\t// 'structible object concepts\n\t\t//\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT destructible_object = object<T> && destructible<T>;\n\n\t\ttemplate<class T, class... Args>\n\t\tMETA_CONCEPT object_constructible_from = object<T> && constructible_from<T, Args...>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT default_initializable_object = object<T> && default_initializable<T>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT move_constructible_object = object<T> && move_constructible<T>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT copy_constructible_object = object<T> && copy_constructible<T>;\n\n\t\t///////////////////////////////////////////////////////////////////////////\n\t\t// trivially_XXX concepts\n\t\t//\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT trivially_destructible =\n\t\t\tdestructible<T> && std::is_trivially_destructible_v<T>;\n\n\t\ttemplate<class T, class... Args>\n\t\tMETA_CONCEPT trivially_constructible_from =\n\t\t\tconstructible_from<T, Args...> &&\n\t\t\tstd::is_trivially_constructible_v<T, Args...>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT trivially_default_initializable =\n\t\t\tdefault_initializable<T> &&\n\t\t\tstd::is_trivially_default_constructible_v<T>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT trivially_move_constructible =\n\t\t\tmove_constructible<T> && std::is_trivially_move_constructible_v<T>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT trivially_copy_constructible =\n\t\t\tcopy_constructible<T> &&\n\t\t\ttrivially_move_constructible<T> &&\n\t\t\tstd::is_trivially_copy_constructible_v<T>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT trivially_movable =\n\t\t\tmovable<T> &&\n\t\t\ttrivially_move_constructible<T> &&\n\t\t\tstd::is_trivially_move_assignable_v<T>;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT trivially_copyable =\n\t\t\tcopyable<T> &&\n\t\t\ttrivially_movable<T> &&\n\t\t\ttrivially_copy_constructible<T> &&\n\t\t\tstd::is_trivially_copy_assignable_v<T>;\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/concepts/urng.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONCEPTS_URNG_HPP\n#define STL2_DETAIL_CONCEPTS_URNG_HPP\n\n#include <stl2/detail/concepts/callable.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<auto> struct __require_constant; // not defined\n\n\ttemplate<class G>\n\tMETA_CONCEPT uniform_random_bit_generator =\n\t\tinvocable<G&> && unsigned_integral<invoke_result_t<G&>> &&\n\t\trequires {\n#ifdef META_HAS_P1084\n\t\t\t{ G::min() } -> same_as<invoke_result_t<G&>>;\n\t\t\t{ G::max() } -> same_as<invoke_result_t<G&>>;\n#else\n\t\t\tG::min(); requires same_as<decltype(G::min()), invoke_result_t<G&>>;\n\t\t\tG::max(); requires same_as<decltype(G::max()), invoke_result_t<G&>>;\n#endif\n#if 1 // This is the PR for https://wg21.link/lwg3150\n\t\t\ttypename __require_constant<G::min()>;\n\t\t\ttypename __require_constant<G::min()>;\n\t\t\trequires G::min() < G::max();\n#endif\n\t\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/construct_destruct.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_CONSTRUCT_DESTRUCT_HPP\n#define STL2_DETAIL_CONSTRUCT_DESTRUCT_HPP\n\n#include <new>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct destruct_fn {\n\t\t\ttemplate<destructible T>\n\t\t\tvoid operator()(T& t) const noexcept {\n\t\t\t\tt.~T();\n\t\t\t}\n\n\t\t\ttemplate<destructible T, std::size_t N>\n\t\t\tvoid operator()(T (&a)[N]) const noexcept {\n\t\t\t\tstd::size_t i = N;\n\t\t\t\twhile (i > 0) {\n\t\t\t\t\ta[--i].~T();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr destruct_fn destruct{};\n\n\t\tstruct construct_fn {\n\t\t\ttemplate<class T, class... Args>\n\t\t\trequires constructible_from<T, Args...>\n\t\t\tvoid operator()(T& t, Args&&... args) const\n\t\t\tnoexcept(std::is_nothrow_constructible<T, Args...>::value)\n\t\t\t{\n\t\t\t\t::new(static_cast<void*>(&t))\n\t\t\t\t\tT{std::forward<Args>(args)...};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr construct_fn construct{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/ebo_box.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_EBO_BOX_HPP\n#define STL2_DETAIL_EBO_BOX_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<ext::destructible_object T, class Tag = void>\n\t\tstruct ebo_box {\n\t\t\tebo_box() = default;\n\t\t\tconstexpr ebo_box(const T& t)\n\t\t\tnoexcept(std::is_nothrow_copy_constructible<T>::value)\n\t\t\trequires copy_constructible<T>\n\t\t\t: item_(t)\n\t\t\t{}\n\t\t\tconstexpr ebo_box(T&& t)\n\t\t\tnoexcept(std::is_nothrow_move_constructible<T>::value)\n\t\t\trequires move_constructible<T>\n\t\t\t: item_(std::move(t))\n\t\t\t{}\n\n\t\t\ttemplate<class First>\n\t\t\trequires (!_OneOf<std::decay_t<First>, ebo_box, T> &&\n\t\t\t\tconstructible_from<T, First> && convertible_to<First, T>)\n\t\t\tconstexpr ebo_box(First&& f)\n\t\t\tnoexcept(std::is_nothrow_constructible<T, First>::value)\n\t\t\t: item_(std::forward<First>(f))\n\t\t\t{}\n\t\t\ttemplate<class First, class... Rest>\n\t\t\trequires (sizeof...(Rest) > 0 || !_OneOf<std::decay_t<First>, ebo_box, T>) &&\n\t\t\t\tconstructible_from<T, First, Rest...>\n\t\t\tconstexpr explicit ebo_box(First&& f, Rest&&... r)\n\t\t\tnoexcept(std::is_nothrow_constructible<T, First, Rest...>::value)\n\t\t\t: item_(std::forward<First>(f), std::forward<Rest>(r)...)\n\t\t\t{}\n\n\t\t\tconstexpr T& get() & noexcept { return item_; }\n\t\t\tconstexpr const T& get() const& noexcept { return item_; }\n\t\t\tconstexpr T&& get() && noexcept { return std::move(item_); }\n\t\t\tconstexpr const T&& get() const&& noexcept { return std::move(item_); }\n\n\t\tprivate:\n\t\t\tT item_;\n\t\t};\n\n\t\ttemplate<ext::destructible_object T, class Tag>\n\t\trequires (std::is_empty<T>::value && !std::is_final<T>::value)\n\t\tstruct ebo_box<T, Tag> : private T {\n\t\t\tebo_box() = default;\n\t\t\tconstexpr ebo_box(const T& t)\n\t\t\tnoexcept(std::is_nothrow_copy_constructible<T>::value)\n\t\t\trequires copy_constructible<T>\n\t\t\t: T(t)\n\t\t\t{}\n\t\t\tconstexpr ebo_box(T&& t)\n\t\t\tnoexcept(std::is_nothrow_move_constructible<T>::value)\n\t\t\trequires move_constructible<T>\n\t\t\t: T(std::move(t))\n\t\t\t{}\n\t\t\tusing T::T;\n\n\t\t\tconstexpr T& get() & noexcept { return *this; }\n\t\t\tconstexpr const T& get() const& noexcept { return *this; }\n\t\t\tconstexpr T&& get() && noexcept { return std::move(*this); }\n\t\t\tconstexpr const T&& get() const&& noexcept { return std::move(*this); }\n\t\t};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/functional/comparisons.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_FUNCTIONAL_COMPARISONS_HPP\n#define STL2_DETAIL_FUNCTIONAL_COMPARISONS_HPP\n\n#include <functional>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// equal_to [comparisons]\n\t//\n\tstruct equal_to {\n\t\ttemplate<class T, equality_comparable_with<T> U>\n\t\tconstexpr decltype(auto) operator()(T&& t, U&& u) const {\n\t\t\treturn std::forward<T>(t) == std::forward<U>(u);\n\t\t}\n\n\t\tusing is_transparent = std::true_type;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// not_equal_to\n\t//\n\tstruct not_equal_to {\n\t\ttemplate<class T, equality_comparable_with<T> U>\n\t\tconstexpr decltype(auto) operator()(T&& t, U&& u) const {\n\t\t\treturn std::forward<T>(t) != std::forward<U>(u);\n\t\t}\n\n\t\tusing is_transparent = std::true_type;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// greater\n\t//\n\tstruct greater {\n\t\ttemplate<class T, totally_ordered_with<T> U>\n\t\tconstexpr decltype(auto) operator()(T&& t, U&& u) const {\n\t\t\treturn std::forward<T>(t) > std::forward<U>(u);\n\t\t}\n\n\t\tusing is_transparent = std::true_type;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// less\n\t//\n\tstruct less {\n\t\ttemplate<class T, totally_ordered_with<T> U>\n\t\tconstexpr decltype(auto) operator()(T&& t, U&& u) const {\n\t\t\treturn std::forward<T>(t) < std::forward<U>(u);\n\t\t}\n\n\t\tusing is_transparent = std::true_type;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// greater_equal\n\t//\n\tstruct greater_equal {\n\t\ttemplate<class T, totally_ordered_with<T> U>\n\t\tconstexpr decltype(auto) operator()(T&& t, U&& u) const {\n\t\t\treturn std::forward<T>(t) >= std::forward<U>(u);\n\t\t}\n\n\t\tusing is_transparent = std::true_type;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// less_equal\n\t//\n\tstruct less_equal {\n\t\ttemplate<class T, totally_ordered_with<T> U>\n\t\tconstexpr decltype(auto) operator()(T&& t, U&& u) const {\n\t\t\treturn std::forward<T>(t) <= std::forward<U>(u);\n\t\t}\n\n\t\tusing is_transparent = std::true_type;\n\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/functional/invoke.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_FUNCTIONAL_INVOKE_HPP\n#define STL2_DETAIL_FUNCTIONAL_INVOKE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\n////////////////////////////////////////////////////////////////////////////////\n// invoke(_result(_t)?)?, reference_wrapper, and c?ref all properly constexpr\n// per the proposed design in P1065.\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<__can_reference> struct reference_wrapper;\n\n\tnamespace __invoke {\n\t\ttemplate<class, class T1>\n\t\tconstexpr decltype(auto) coerce(T1&& t1)\n\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\t*static_cast<T1&&>(t1)\n\t\t)\n\n\t\ttemplate<class T, class T1>\n\t\trequires std::is_base_of_v<T, __uncvref<T1>>\n\t\tconstexpr auto&& coerce(T1&& t1) noexcept {\n\t\t\treturn static_cast<T1&&>(t1);\n\t\t}\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT is_reference_wrapper =\n\t\t\tmeta::is_v<T, reference_wrapper> ||\n\t\t\tmeta::is_v<T, std::reference_wrapper>;\n\n\t\ttemplate<class, class RW>\n\t\trequires is_reference_wrapper<RW>\n\t\tconstexpr auto& coerce(RW rw) noexcept {\n\t\t\treturn rw.get();\n\t\t}\n\t}\n\n\ttemplate<class F, class T, class T1, class... Args>\n\tconstexpr decltype(auto) invoke(F (T::*pmf), T1&& t1, Args&&... args)\n\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t(__invoke::coerce<T>(static_cast<T1&&>(t1)).*pmf)(static_cast<Args&&>(args)...)\n\t)\n\n#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 10\n\ttemplate<ext::object D, class T, class T1>\n#else\n\ttemplate<class D, class T, class T1>\n#endif\n\tconstexpr decltype(auto) invoke(D (T::*pmd), T1&& t1)\n\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t__invoke::coerce<T>(static_cast<T1&&>(t1)).*pmd\n\t)\n\n\ttemplate<class F, class... Args>\n\tconstexpr decltype(auto) invoke(F&& f, Args&&... args)\n\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\tstatic_cast<F&&>(f)(static_cast<Args&&>(args)...)\n\t)\n\n\ttemplate<class F, class... Args>\n\tusing invoke_result_t = decltype(__stl2::invoke(std::declval<F>(), std::declval<Args>()...));\n\ttemplate<class, class...> struct invoke_result {};\n\ttemplate<class F, class... Args>\n\trequires requires { typename invoke_result_t<F, Args...>; }\n\tstruct invoke_result<F, Args...> {\n\t\tusing type = invoke_result_t<F, Args...>;\n\t};\n\n\ttemplate<__can_reference T>\n\tstruct reference_wrapper {\n\tprivate:\n\t\tT* t_;\n\n\t\tstatic constexpr T& fun(T& t) noexcept { return t; }\n\t\tstatic constexpr void fun(T&& t) = delete;\n\tpublic:\n\t\tusing type = T;\n\n\t\ttemplate<class U>\n\t\trequires (!derived_from<U, reference_wrapper>)\n\t\tconstexpr reference_wrapper(U&& u)\n\t\tnoexcept(noexcept(fun(static_cast<U&&>(u))))\n\t\trequires requires { fun(static_cast<U&&>(u)); }\n\t\t: t_(std::addressof(fun(static_cast<U&&>(u)))) {}\n\n\t\tconstexpr operator T&() const noexcept { return *t_; }\n\t\tconstexpr T& get() const noexcept { return *t_; }\n\n\t\ttemplate<class... Args>\n\t\trequires requires(T& t, Args&&... args) { __stl2::invoke(t, static_cast<Args&&>(args)...); }\n\t\tconstexpr decltype(auto) operator()(Args&&... args) const\n\t\tnoexcept(noexcept(__stl2::invoke(*t_, static_cast<Args&&>(args)...))) {\n\t\t\treturn __stl2::invoke(*t_, static_cast<Args&&>(args)...);\n\t\t}\n\t};\n\n\ttemplate<class T>\n\treference_wrapper(T&) -> reference_wrapper<T>;\n\n\ttemplate<class T>\n\tconstexpr reference_wrapper<T> ref(reference_wrapper<T> rw) noexcept {\n\t\treturn rw;\n\t}\n\ttemplate<class T>\n\tconstexpr reference_wrapper<T> ref(std::reference_wrapper<T> rw) noexcept {\n\t\treturn rw.get();\n\t}\n\ttemplate<class T>\n\tconstexpr reference_wrapper<T> ref(T& t) noexcept { return {t}; }\n\ttemplate<class T>\n\tvoid ref(const T&&) = delete;\n\n\ttemplate<class T>\n\tconstexpr reference_wrapper<const T>\n\tcref(reference_wrapper<T> rw) noexcept {\n\t\treturn rw.get();\n\t}\n\ttemplate<class T>\n\tconstexpr reference_wrapper<const T>\n\tcref(std::reference_wrapper<T> rw) noexcept {\n\t\treturn rw.get();\n\t}\n\ttemplate<class T>\n\tconstexpr reference_wrapper<const T> cref(const T& t) noexcept {\n\t\treturn {t};\n\t}\n\ttemplate<class T>\n\tvoid cref(const T&&) = delete;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/functional/not_fn.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_FUNCTIONAL_NOT_FN_HPP\n#define STL2_DETAIL_FUNCTIONAL_NOT_FN_HPP\n\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/function.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/functional/invoke.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// not_fn from C++17\n\t//\n\ttemplate<class F, class... Args>\n\tMETA_CONCEPT _NegateInvocable = invocable<F, Args...> &&\n\t\trequires(F&& f, Args&&... args) {\n#ifdef META_HAS_P1084\n\t\t\t{ !__stl2::invoke(static_cast<F&&>(f), static_cast<Args&&>(args)...) } -> boolean;\n#else\n\t\t\t!__stl2::invoke(static_cast<F&&>(f),\n\t\t\t\tstatic_cast<Args&&>(args)...);\n\t\t\trequires boolean<decltype(!__stl2::invoke(static_cast<F&&>(f),\n\t\t\t\tstatic_cast<Args&&>(args)...))>;\n#endif\n\t\t};\n\n\ttemplate<ext::move_constructible_object F>\n\tstruct __not_fn : private detail::ebo_box<F, __not_fn<F>> {\n\tprivate:\n\t\tusing box_t = detail::ebo_box<F, __not_fn<F>>;\n\tpublic:\n\t\ttemplate<class FF>\n\t\trequires constructible_from<F, FF>\n\t\texplicit constexpr __not_fn(FF&& arg)\n\t\tnoexcept(std::is_nothrow_constructible_v<F, FF>)\n\t\t: box_t(static_cast<FF&&>(arg))\n\t\t{}\n\t\ttemplate<class... Args>\n\t\trequires _NegateInvocable<F&, Args...>\n\t\tconstexpr bool operator()(Args&&... args) &\n\t\tnoexcept(noexcept(!__stl2::invoke(std::declval<F&>(), static_cast<Args&&>(args)...)))\n\t\t{\n\t\t\treturn !__stl2::invoke(box_t::get(), static_cast<Args&&>(args)...);\n\t\t}\n\t\ttemplate<class... Args>\n\t\trequires _NegateInvocable<const F&, Args...>\n\t\tconstexpr bool operator()(Args&&... args) const &\n\t\tnoexcept(noexcept(!__stl2::invoke(std::declval<const F&>(), static_cast<Args&&>(args)...)))\n\t\t{\n\t\t\treturn !__stl2::invoke(box_t::get(), static_cast<Args&&>(args)...);\n\t\t}\n\t\ttemplate<class... Args>\n\t\trequires _NegateInvocable<F, Args...>\n\t\tconstexpr bool operator()(Args&&... args) &&\n\t\tnoexcept(noexcept(!__stl2::invoke(std::declval<F>(), static_cast<Args&&>(args)...)))\n\t\t{\n\t\t\treturn !__stl2::invoke(std::move(box_t::get()), static_cast<Args&&>(args)...);\n\t\t}\n\t\ttemplate<class... Args>\n\t\trequires _NegateInvocable<const F, Args...>\n\t\tconstexpr bool operator()(Args&&... args) const &&\n\t\tnoexcept(noexcept(!__stl2::invoke(std::declval<const F>(), static_cast<Args&&>(args)...)))\n\t\t{\n\t\t\treturn !__stl2::invoke(std::move(box_t::get()), static_cast<Args&&>(args)...);\n\t\t}\n\t};\n\n\ttemplate<class F>\n\trequires move_constructible<__f<F>>\n\tconstexpr __not_fn<__f<F>> not_fn(F&& f)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t__not_fn<__f<F>>{static_cast<F&&>(f)}\n\t)\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/fwd.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2016\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_FWD_HPP\n#define STL2_DETAIL_FWD_HPP\n\n#include <type_traits>\n#include <utility>\n#include <meta/meta.hpp>\n\n#ifdef __clang__\n #define STL2_HAS_BUILTIN(X) __has_builtin(__builtin_ ## X)\n#else // __clang__\n #define STL2_HAS_BUILTIN(X) STL2_HAS_BUILTIN_ ## X\n #if defined(__GNUC__)\n  #define STL2_HAS_BUILTIN_unreachable 1\n #endif // __GNUC__\n#endif // __clang__\n\n#ifndef STL2_WORKAROUND_GCC_69096\n #if defined(__GNUC__) && __GNUC__ < 10\n  // Return type deduction performed *before* checking constraints.\n  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69096\n  #define STL2_WORKAROUND_GCC_69096 1\n #else\n  #define STL2_WORKAROUND_GCC_69096 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_GCC_79591\n #if defined(__GNUC__) && __GNUC__ < 10\n  // Overloading function template declarations that differ only in their\n  // associated constraints does not work properly when at least one declaration\n  // is imported with a using declaration.\n  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79591\n  #define STL2_WORKAROUND_GCC_79591 1\n #else\n  #define STL2_WORKAROUND_GCC_79591 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_GCC_UNKNOWN0\n #if defined(__GNUC__) && __GNUC__ < 10\n  // Unfiled GCC bug triggered by the P/R for LWG 3149\n  #define STL2_WORKAROUND_GCC_UNKNOWN0 1\n #else\n  #define STL2_WORKAROUND_GCC_UNKNOWN0 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_GCC_UNKNOWN1\n #ifdef __GNUC__ // Unfiled GCC bug triggered by basic_iterator\n  #define STL2_WORKAROUND_GCC_UNKNOWN1 1\n #else\n  #define STL2_WORKAROUND_GCC_UNKNOWN1 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_CLANG_UNKNOWN1\n #if defined(__clang__) && __clang_major < 7\n  // Rejects-valid with CTAD nested in parens.\n  #define STL2_WORKAROUND_CLANG_UNKNOWN1 1\n #else\n  #define STL2_WORKAROUND_CLANG_UNKNOWN1 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_CLANG_37556\n #ifdef __clang__ // Workaround https://bugs.llvm.org/show_bug.cgi?id=37556\n  // Improper symbol redefinition diagnostic for names in different declarative regions\n  #define STL2_WORKAROUND_CLANG_37556 1\n #else\n  #define STL2_WORKAROUND_CLANG_37556 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_CLANG_40150\n #ifdef __clang__ // Workaround https://bugs.llvm.org/show_bug.cgi?id=40150\n  // deleted friend of template class conflicts with its own definition\n  #define STL2_WORKAROUND_CLANG_40150 1\n #else\n  #define STL2_WORKAROUND_CLANG_40150 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_106654 // \"multiple versions of a defaulted special member functions are not allowed\"\n #if defined(_MSC_VER) && !defined(__clang__)\n  #define STL2_WORKAROUND_MSVC_106654 1\n #else\n  #define STL2_WORKAROUND_MSVC_106654 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_830361 // \"The type of ternary operator sometimes keeps cv-qualifier\"\n #if defined(_MSC_VER) && !defined(__clang__)\n  #define STL2_WORKAROUND_MSVC_830361 1\n #else\n  #define STL2_WORKAROUND_MSVC_830361 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_830372 // \"explicit ctor is allowed in copy initialization\"\n #if defined(_MSC_VER) && !defined(__clang__)\n  #define STL2_WORKAROUND_MSVC_830372 1\n #else\n  #define STL2_WORKAROUND_MSVC_830372 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_836487 // \"constexpr assertion failure\"\n #if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1924 // Likely preview 2\n  #define STL2_WORKAROUND_MSVC_836487 1\n #else\n  #define STL2_WORKAROUND_MSVC_836487 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_841651 // \"RDParser uses the placeholder directly instead of resolving it\"\n #if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1924 // Likely preview 2\n  #define STL2_WORKAROUND_MSVC_841651 1\n #else\n  #define STL2_WORKAROUND_MSVC_841651 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_846967 // \"inheriting ctor and defaulted default ctor which is deleted\"\n #if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1924 // Likely preview 2\n  #define STL2_WORKAROUND_MSVC_846967 1\n #else\n  #define STL2_WORKAROUND_MSVC_846967 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_849755 // \"cmcstl2 test move_iterator fails\"\n #if defined(_MSC_VER) && !defined(__clang__)\n  #define STL2_WORKAROUND_MSVC_849755 1\n #else\n  #define STL2_WORKAROUND_MSVC_849755 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_895622 // \"Error when phase 1 name binding finds only deleted function\"\n #if defined(_MSC_VER) && !defined(__clang__)\n  #define STL2_WORKAROUND_MSVC_895622 1\n #else\n  #define STL2_WORKAROUND_MSVC_895622 0\n #endif\n#endif\n\n#ifndef STL2_WORKAROUND_MSVC_FUNCTION_CONVERSIONS // MSVC allows pointers-to-function to implicitly convert to void*\n #if defined(_MSC_VER) && !defined(__clang__)\n  #define STL2_WORKAROUND_MSVC_FUNCTION_CONVERSIONS 1\n #else\n  #define STL2_WORKAROUND_MSVC_FUNCTION_CONVERSIONS 0\n #endif\n#endif\n\n#define STL2_OPEN_NAMESPACE \\\n\tnamespace std { namespace experimental { namespace ranges { inline namespace v1\n#define STL2_CLOSE_NAMESPACE }}}\n\n// General namespace structure:\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\t// Implementation details, not to be accessed by user code.\n\t}\n\tnamespace ext {\n\t\t// Supported extensions beyond what is specified in C++ and\n\t\t// the Ranges proposal, acceptable for user code to access.\n\t}\n\tinline namespace __cpos {\n\t\t// Customization point objects, whose names would otherwise\n\t\t// clash with hidden friend functions if they were declared\n\t\t// directly in the stl2 namespace.\n\t}\n} STL2_CLOSE_NAMESPACE\n\n// Used to qualify STL2 names\nnamespace __stl2 = ::std::experimental::ranges;\n\n#if STL2_WORKAROUND_CLANG_UNKNOWN1\n#define STL2_NOEXCEPT_RETURN(...) \\\n\tnoexcept(noexcept(__VA_ARGS__)) \\\n\t{ return __VA_ARGS__; }\n\n#define STL2_REQUIRES_RETURN(...) \\\n\trequires requires { __VA_ARGS__; } \\\n\t{ return __VA_ARGS__; }\n\n#define STL2_NOEXCEPT_REQUIRES_RETURN(...) \\\n\tnoexcept(noexcept(__VA_ARGS__)) \\\n\trequires requires { __VA_ARGS__; } \\\n\t{ return __VA_ARGS__; }\n#else\n#define STL2_NOEXCEPT_RETURN(...) \\\n\tnoexcept(noexcept(__VA_ARGS__)) \\\n\t{ return (__VA_ARGS__); }\n\n#define STL2_REQUIRES_RETURN(...) \\\n\trequires requires { __VA_ARGS__; } \\\n\t{ return (__VA_ARGS__); }\n\n#define STL2_NOEXCEPT_REQUIRES_RETURN(...) \\\n\tnoexcept(noexcept(__VA_ARGS__)) \\\n\trequires requires { __VA_ARGS__; } \\\n\t{ return (__VA_ARGS__); }\n#endif\n\n#ifndef STL2_ASSERT\n #ifdef NDEBUG\n  #define STL2_ASSERT(...) void(0)\n #else\n  #include <cassert>\n  #define STL2_ASSERT(...) assert((__VA_ARGS__))\n #endif\n#endif\n\n#ifndef STL2_EXPENSIVE_ASSERT\n #ifdef STL2_USE_EXPENSIVE_ASSERTS\n  #define STL2_EXPENSIVE_ASSERT(...) STL2_ASSERT(__VA_ARGS__)\n #else\n  #define STL2_EXPENSIVE_ASSERT(...) void(0)\n #endif\n#endif\n\n#ifndef STL2_ASSUME\n #if STL2_HAS_BUILTIN(assume)\n  #define STL2_ASSUME(...) __builtin_assume(__VA_ARGS__)\n #elif STL2_HAS_BUILTIN(unreachable)\n  // Tell the compiler to optimize on the assumption that the condition holds.\n  #define STL2_ASSUME(...) ((__VA_ARGS__) ? void(0) : __builtin_unreachable())\n #else\n  #define STL2_ASSUME(...) void(0)\n #endif\n#endif\n\n#ifndef STL2_EXPECT\n #ifdef NDEBUG\n  #define STL2_EXPECT(...) STL2_ASSUME(__VA_ARGS__)\n #else\n  #define STL2_EXPECT(...) STL2_ASSERT(__VA_ARGS__)\n #endif\n#endif\n\n#if __has_cpp_attribute(no_unique_address)\n#define STL2_NO_UNIQUE_ADDRESS [[no_unique_address]]\n#else\n#define STL2_NO_UNIQUE_ADDRESS\n#endif\n\n#ifdef _MSC_VER\n#define STL2_EMPTY_BASES __declspec(empty_bases)\n#else\n#define STL2_EMPTY_BASES\n#endif\n\n#ifndef STL2_HOOK_ITERATOR_TRAITS\n#if defined(__cpp_lib_ranges) || \\\n\t(defined(_MSVC_STL_UPDATE) && _MSVC_STL_UPDATE >= 201908L && defined(__cpp_lib_concepts))\n#define STL2_HOOK_ITERATOR_TRAITS 0\n#else\n#define STL2_HOOK_ITERATOR_TRAITS 1\n#endif\n#endif\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\t// tags for manually specified overload ordering\n\t\ttemplate<unsigned N>\n\t\tstruct priority_tag : priority_tag<N - 1> {};\n\t\ttemplate<>\n\t\tstruct priority_tag<0> {};\n\t\tinline constexpr priority_tag<4> max_priority_tag{};\n\t}\n\n\tstruct __niebloid {\n\t\texplicit __niebloid() = default;\n\t\t__niebloid(const __niebloid&) = delete;\n\t\t__niebloid& operator=(const __niebloid&) = delete;\n\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_FWD_HPP\n"
  },
  {
    "path": "include/stl2/detail/hash.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_HASH_HPP\n#define STL2_DETAIL_HASH_HPP\n\n#include <cstddef>\n#include <functional>\n#include <stl2/detail/fwd.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// Hash machinery.\n//\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// Hashable [Extension]\n\t// Extremely limited since std::hash is not SFINAE-friendly.\n\t//\n\tnamespace ext {\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT Hashable = requires(const T& e) {\n\t\t\ttypename std::hash<T>;\n\t\t\t{ std::hash<T>{}(e) } -> std::size_t;\n\t\t};\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// hash_combine [Extension]\n\t// Stolen from Boost.\n\t//\n\tnamespace ext {\n\t\ttemplate<Hashable T>\n\t\tinline void hash_combine(std::size_t& seed, const T& v) {\n\t\t\tstd::hash<T> hasher;\n\t\t\tseed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);\n\t\t}\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iostream/concepts.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_IOSTREAM_CONCEPTS_HPP\n#define STL2_DETAIL_IOSTREAM_CONCEPTS_HPP\n\n#include <iosfwd>\n#include <stl2/detail/fwd.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// StreamExtractable [Extension]\n\t//\n\ttemplate<class T, class charT = char, class traits = std::char_traits<charT>>\n\tMETA_CONCEPT StreamExtractable =\n\t\trequires(std::basic_istream<charT, traits>& is, T& t) {\n#ifdef META_HAS_P1084\n\t\t\t{ is >> t } -> same_as<std::basic_istream<charT, traits>&>;\n#else\n\t\t\tis >> t; requires same_as<decltype((is >> t)), std::basic_istream<charT, traits>&>;\n#endif\n\t\t\t// Axiom: &is == &(is << t)\n\t\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// StreamInsertable [Extension]\n\t//\n\ttemplate<class T, class charT = char, class traits = std::char_traits<charT>>\n\tMETA_CONCEPT StreamInsertable =\n\t\trequires(std::basic_ostream<charT, traits>& os, const T& t) {\n#ifdef META_HAS_P1084\n\t\t\t{ os << t } -> same_as<std::basic_ostream<charT, traits>&>;\n#else\n\t\t\tos << t; requires same_as<decltype((os << t)), std::basic_ostream<charT, traits>&>;\n#endif\n\t\t\t// Axiom: &os == &(os << t)\n\t\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/any_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_ANY_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_ANY_ITERATOR_HPP\n\n#include <atomic>\n#include <exception>\n#include <new>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/swap.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace __any_iterator {\n\t\tenum class op { copy, move, nuke, bump, comp, rval };\n\n\t\ttemplate<input_iterator I>\n\t\tstruct shared_iterator {\n\t\t\texplicit shared_iterator(I i)\n\t\t\tnoexcept(std::is_nothrow_move_constructible_v<I>)\n\t\t\t: it(std::move(i)) {}\n\n\t\t\tSTL2_NO_UNIQUE_ADDRESS I it;\n\t\t\tstd::atomic<long> cnt{1};\n\t\t};\n\n\t\tunion blob {\n\t\t\tvoid* big;\n\t\t\talignas(std::max_align_t) unsigned char tiny[2 * sizeof(void*)];\n\t\t};\n\n\t\ttemplate<class It>\n\t\tinline constexpr bool is_small = sizeof(It) <= sizeof(blob::tiny) &&\n\t\t\talignof(It) <= alignof(std::max_align_t);\n\n\t\ttemplate<class RValueReference>\n\t\tusing iter_move_fn = RValueReference (*)(const blob&);\n\n\t\ttemplate<class RValueReference>\n\t\tinline iter_move_fn<RValueReference> uninit_noop(op, blob*, blob*) {\n\t\t\treturn nullptr;\n\t\t}\n\n\t\ttemplate<class Reference>\n\t\t[[noreturn]] inline Reference uninit_deref(const blob&) {\n\t\t\tstd::terminate();\n\t\t}\n\n\t\ttemplate<class Reference, input_iterator I>\n\t\tReference deref_small(const blob& src) {\n\t\t\treturn *reinterpret_cast<const I&>(src.tiny);\n\t\t}\n\n\t\ttemplate<class Reference, input_iterator I>\n\t\tReference deref_big(const blob& src) {\n\t\t\treturn *static_cast<const shared_iterator<I>*>(src.big)->it;\n\t\t}\n\n\t\ttemplate<class I, class J>\n\t\tconstexpr bool iter_equal(const I& i, const J& j) {\n\t\t\tif constexpr (sentinel_for<J, I>) {\n\t\t\t\treturn i == j;\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<class RValueReference, input_iterator I>\n\t\titer_move_fn<RValueReference> exec_small(op o, blob* src, blob* dst) {\n\t\t\tswitch (o) {\n\t\t\tcase op::copy:\n\t\t\t\t::new (static_cast<void*>(&dst->tiny))\n\t\t\t\t\tI(reinterpret_cast<const I&>(src->tiny));\n\t\t\t\tbreak;\n\t\t\tcase op::move:\n\t\t\t\t::new (static_cast<void*>(&dst->tiny))\n\t\t\t\t\tI(reinterpret_cast<I&&>(src->tiny));\n\t\t\t\t[[fallthrough]];\n\t\t\tcase op::nuke:\n\t\t\t\treinterpret_cast<I&>(src->tiny).~I();\n\t\t\t\tbreak;\n\t\t\tcase op::bump:\n\t\t\t\t++reinterpret_cast<I&>(src->tiny);\n\t\t\t\tbreak;\n\t\t\tcase op::comp:\n\t\t\t\tif (__any_iterator::iter_equal(\n\t\t\t\t\treinterpret_cast<const I&>(src->tiny),\n\t\t\t\t\treinterpret_cast<const I&>(dst->tiny))) {\n\t\t\t\t\t[[fallthrough]];\n\t\t\tcase op::rval:\n\t\t\t\t\treturn +[](const blob& src) -> RValueReference {\n\t\t\t\t\t\treturn iter_move(reinterpret_cast<const I&>(src.tiny));\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nullptr;\n\t\t}\n\n\t\ttemplate<class RValueReference, input_iterator I>\n\t\titer_move_fn<RValueReference> exec_big(op o, blob* src, blob* dst) {\n\t\t\tswitch (o) {\n\t\t\tcase op::copy:\n\t\t\t\tdst->big = src->big;\n\t\t\t\t++static_cast<shared_iterator<I>*>(src->big)->cnt;\n\t\t\t\tbreak;\n\t\t\tcase op::move:\n\t\t\t\tdst->big = __stl2::exchange(src->big, nullptr);\n\t\t\t\tbreak;\n\t\t\tcase op::nuke:\n\t\t\t\tif (--static_cast<shared_iterator<I>*>(src->big)->cnt == 0) {\n\t\t\t\t\tdelete static_cast<shared_iterator<I>*>(src->big);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase op::bump:\n\t\t\t\t++static_cast<shared_iterator<I>*>(src->big)->it;\n\t\t\t\tbreak;\n\t\t\tcase op::comp:\n\t\t\t\tif (__any_iterator::iter_equal(\n\t\t\t\t\tstatic_cast<const shared_iterator<I>*>(src->big)->it,\n\t\t\t\t\tstatic_cast<const shared_iterator<I>*>(dst->big)->it)) {\n\t\t\t\t\t[[fallthrough]];\n\t\t\tcase op::rval:\n\t\t\t\t\treturn +[](const blob& src) -> RValueReference {\n\t\t\t\t\t\treturn iter_move(\n\t\t\t\t\t\t\tstatic_cast<const shared_iterator<I>*>(src.big)->it);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nullptr;\n\t\t}\n\n\t\ttemplate<class Reference, class ValueType, class RValueReference>\n\t\tstruct cursor {\n\t\tprivate:\n\t\t\tblob data_{nullptr};\n\t\t\tReference (*deref_)(const blob&) = &uninit_deref<Reference>;\n\t\t\titer_move_fn<RValueReference> (*exec_)(op, blob*, blob*) =\n\t\t\t\t&uninit_noop<RValueReference>;\n\n\t\t\tvoid reset() noexcept {\n\t\t\t\texec_(op::nuke, &data_, nullptr);\n\t\t\t\tderef_ = &uninit_deref<Reference>;\n\t\t\t\texec_ = &uninit_noop<RValueReference>;\n\t\t\t}\n\t\t\tvoid copy_from(const cursor& that) {\n\t\t\t\t// Pre: *this is empty\n\t\t\t\tthat.exec_(op::copy, const_cast<blob*>(&that.data_), &data_);\n\t\t\t\tderef_ = that.deref_;\n\t\t\t\texec_ = that.exec_;\n\t\t\t}\n\t\t\tvoid move_from(cursor& that) {\n\t\t\t\t// Pre: *this is empty\n\t\t\t\tthat.exec_(op::move, &that.data_, &data_);\n\t\t\t\t__stl2::swap(deref_, that.deref_);\n\t\t\t\t__stl2::swap(exec_, that.exec_);\n\t\t\t}\n\t\tpublic:\n\t\t\tusing value_type = ValueType;\n\t\t\tusing single_pass = std::true_type;\n\n\t\t\tstruct mixin : basic_mixin<cursor> {\n\t\t\tprivate:\n\t\t\t\tusing base_t = basic_mixin<cursor>;\n\t\t\tpublic:\n\t\t\t\tmixin() = default;\n\t\t\t\ttemplate<class I>\n\t\t\t\trequires (!derived_from<I, mixin>) && input_iterator<I>\n\t\t\t\texplicit mixin(I i)\n\t\t\t\t: base_t(cursor{std::move(i)})\n\t\t\t\t{}\n\t\t\t\tusing base_t::base_t;\n#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8\n\t\t\t\texplicit mixin(cursor c)\n\t\t\t\t: base_t(std::move(c))\n\t\t\t\t{}\n#endif // unknown gcc7 bug\n\t\t\t};\n\n\t\t\tcursor() = default;\n\t\t\tcursor(const cursor& that) {\n\t\t\t\tcopy_from(that);\n\t\t\t}\n\t\t\tcursor(cursor&& that) {\n\t\t\t\tmove_from(that);\n\t\t\t}\n\t\t\ttemplate<class I>\n\t\t\trequires (!derived_from<I, cursor>) && input_iterator<I>\n\t\t\tcursor(I i) {\n\t\t\t\tif constexpr (is_small<I>) {\n\t\t\t\t\t::new (static_cast<void *>(&data_.tiny)) I(std::move(i));\n\t\t\t\t\tderef_ = &deref_small<Reference, I>;\n\t\t\t\t\texec_ = &exec_small<RValueReference, I>;\n\t\t\t\t} else {\n\t\t\t\t\tdata_.big = new shared_iterator<I>(std::move(i));\n\t\t\t\t\tderef_ = &deref_big<Reference, I>;\n\t\t\t\t\texec_ = &exec_big<RValueReference, I>;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t~cursor() {\n\t\t\t\texec_(op::nuke, &data_, nullptr);\n\t\t\t}\n\n\t\t\tcursor& operator=(const cursor& that) {\n\t\t\t\tif (&that != this) {\n\t\t\t\t\treset();\n\t\t\t\t\tcopy_from(that);\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tcursor& operator=(cursor&& that) {\n\t\t\t\tif (&that != this) {\n\t\t\t\t\treset();\n\t\t\t\t\tmove_from(that);\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tReference read() const {\n\t\t\t\treturn deref_(data_);\n\t\t\t}\n\t\t\tbool equal(const cursor& that) const {\n\t\t\t\treturn exec_(op::comp, const_cast<blob*>(&data_),\n\t\t\t\t\tconst_cast<blob*>(&that.data_)) != nullptr;\n\t\t\t}\n\t\t\tvoid next() {\n\t\t\t\texec_(op::bump, &data_, nullptr);\n\t\t\t}\n\t\t\tRValueReference indirect_move() const {\n\t\t\t\treturn exec_(op::rval, nullptr, nullptr)(data_);\n\t\t\t}\n\t\t};\n\t} // namespace any_iterator\n\n\tnamespace ext {\n\t\ttemplate<class Reference,\n\t\t\tclass ValueType = __uncvref<Reference>,\n\t\t\tclass RValueReference = __iter_move::rvalue<Reference>>\n\t\tusing any_input_iterator =\n\t\t\tbasic_iterator<__any_iterator::cursor<Reference, ValueType, RValueReference>>;\n\t} // namespace ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/basic_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2014-2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_BASIC_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_BASIC_ITERATOR_HPP\n\n#include <memory>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/fundamental.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n\n// TODO:\n// * Specify that get() must not throw.\n// * Think long and hard about the various proxies and reference\n//   validity requirements for forward iterators.\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<ext::destructible_object T>\n\trequires (std::is_class<T>::value && !std::is_final<T>::value)\n\tclass basic_mixin : T {\n\tpublic:\n\t\tbasic_mixin() = default;\n\n\t\tconstexpr explicit basic_mixin(const T& t)\n\t\tnoexcept(std::is_nothrow_copy_constructible<T>::value)\n\t\trequires copy_constructible<T>\n\t\t: T(t) {}\n\n\t\tconstexpr explicit basic_mixin(T&& t)\n\t\tnoexcept(std::is_nothrow_move_constructible<T>::value)\n\t\trequires move_constructible<T>\n\t\t: T(std::move(t)) {}\n\n\tprotected:\n\t\tconstexpr T& get() & noexcept { return *this; }\n\t\tconstexpr const T& get() const& noexcept { return *this; }\n\t\tconstexpr T&& get() && noexcept { return std::move(*this); }\n\t\tconstexpr const T&& get() const&& noexcept { return std::move(*this); }\n\t};\n\n\tnamespace detail {\n\t\ttemplate<class T>\n\t\tstruct mixin_base {\n\t\t\tusing type = basic_mixin<T>;\n\t\t};\n\t\ttemplate<class T>\n\t\trequires requires { typename T::mixin; }\n\t\tstruct mixin_base<T> {\n\t\t\tusing type = typename T::mixin;\n\t\t};\n\n\t\ttemplate<class T>\n\t\tconstexpr bool IsValueType = !STL2_IS_VOID(T);\n\t} // namespace detail\n\ttemplate<class T>\n\trequires\n\t\trequires {\n\t\t\ttypename meta::_t<detail::mixin_base<T>>;\n\t\t\trequires ext::destructible_object<meta::_t<detail::mixin_base<T>>>;\n\t\t\trequires std::is_class<meta::_t<detail::mixin_base<T>>>::value;\n\t\t\trequires !std::is_final<meta::_t<detail::mixin_base<T>>>::value;\n\t\t}\n\tusing mixin_t = meta::_t<detail::mixin_base<T>>;\n\n\tnamespace cursor {\n\t\t// This would perhaps more appropriately be named \"disable_multi_pass.\" It\n\t\t// is an opt-out trait that tells basic_iterator that an Input cursor is NOT\n\t\t// Forward despite having equality.\n\t\ttemplate<class>\n\t\tconstexpr bool single_pass = false;\n\t\ttemplate<class C>\n\t\trequires\n\t\t\trequires {\n\t\t\t\ttypename C::single_pass;\n\t\t\t\trequires bool(C::single_pass::value);\n\t\t\t}\n\t\tconstexpr bool single_pass<C> = true;\n\n\t\t// A RandomAccess cursor whose reference_t is a reference type and\n\t\t// whose member type \"contiguous\" looks like true_type will generate\n\t\t// a contiguous_iterator. i.e., this is an opt-in trait for contiguity.\n\t\ttemplate<class>\n\t\tconstexpr bool contiguous = false;\n\t\ttemplate<class C>\n\t\trequires\n\t\t\trequires {\n\t\t\t\ttypename C::contiguous;\n\t\t\t\trequires bool(C::contiguous::value);\n\t\t\t}\n\t\tconstexpr bool contiguous<C> =  true;\n\n\t\ttemplate<class>\n\t\tstruct difference_type {\n\t\t\tusing type = std::ptrdiff_t;\n\t\t};\n\t\ttemplate<class C>\n\t\trequires requires { typename C::difference_type; }\n\t\tstruct difference_type<C> {\n\t\t\tusing type = typename C::difference_type;\n\t\t\tstatic_assert(signed_integral<type>,\n\t\t\t\t\"Cursor's member difference_type is not a signed integer type.\");\n\t\t};\n\t\ttemplate<class C>\n\t\trequires (!requires { typename C::difference_type; } &&\n\t\t\trequires(const C& lhs, const C& rhs) { rhs.distance_to(lhs); })\n\t\tstruct difference_type<C> {\n\t\t\tusing type =\n\t\t\t\tdecltype(std::declval<const C&>().distance_to(std::declval<const C&>()));\n\t\t\tstatic_assert(signed_integral<type>,\n\t\t\t\t\"Return type of Cursor's member distance_to is not a signed integer type.\");\n\t\t};\n\t\ttemplate<class C>\n\t\trequires\n\t\t\tsigned_integral<meta::_t<difference_type<C>>>\n\t\tusing difference_type_t = meta::_t<difference_type<C>>;\n\n\t\ttemplate<class> struct reference_type {};\n\t\ttemplate<class C>\n\t\trequires requires(const C& c) {\n#ifdef META_HAS_P1084\n\t\t\t{ c.read() } -> __can_reference;\n#else\n\t\t\tc.read(); requires __can_reference<decltype(c.read())>;\n#endif\n\t\t}\n\t\tstruct reference_type<C> {\n\t\t\tusing type = decltype(std::declval<const C&>().read());\n\t\t};\n\t\ttemplate<class C>\n\t\tusing reference_t = meta::_t<reference_type<C>>;\n\n\t\ttemplate<class> struct value_type {};\n\t\ttemplate<detail::MemberValueType C>\n\t\tstruct value_type<C> {\n\t\t\tusing type = typename C::value_type;\n\t\t\tstatic_assert(detail::IsValueType<type>,\n\t\t\t\t\"Cursor's member \\\"value_type\\\" is not a value type.\");\n\t\t};\n\t\ttemplate<class C>\n\t\trequires\n\t\t\t(!detail::MemberValueType<C>) && requires { typename reference_t<C>; }\n\t\tstruct value_type<C> {\n\t\t\tusing type = std::decay_t<reference_t<C>>;\n\t\t\tstatic_assert(detail::IsValueType<type>,\n\t\t\t\t\"Cursor's reference type does not decay to a value type.\");\n\t\t};\n\t\ttemplate<class C>\n\t\trequires\n\t\t\tdetail::IsValueType<meta::_t<value_type<C>>>\n\t\tusing value_type_t = meta::_t<value_type<C>>;\n\n\t\ttemplate<class C, class M>\n\t\tMETA_CONCEPT _Cursor =\n\t\t\tsemiregular<C> &&\n\t\t\tsemiregular<M> &&\n\t\t\tconstructible_from<M, C> &&\n\t\t\tconstructible_from<M, const C&>;\n\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Cursor =\n\t\t\trequires {\n\t\t\t\ttypename difference_type_t<C>;\n\t\t\t\ttypename mixin_t<std::remove_cv_t<C>>;\n\t\t\t} &&\n\t\t\t_Cursor<std::remove_cv_t<C>, mixin_t<std::remove_cv_t<C>>>;\n\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT readable =\n\t\t\tCursor<C> &&\n\t\t\trequires(const C& c) {\n#ifdef META_HAS_P1084\n\t\t\t\t{ c.read() } -> __can_reference;\n#else\n\t\t\t\tc.read(); requires __can_reference<decltype(c.read())>;\n#endif\n\t\t\t\ttypename reference_t<C>;\n\t\t\t\ttypename value_type_t<C>;\n\t\t\t};\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Arrow =\n\t\t\treadable<C> &&\n\t\t\trequires(const C& c) {\n#ifdef META_HAS_P1084\n\t\t\t\t{ c.arrow() } ->__can_reference;\n#else\n\t\t\t\tc.arrow(); requires __can_reference<decltype(c.arrow())>;\n#endif\n\t\t\t};\n\t\ttemplate<class C, class T>\n\t\tMETA_CONCEPT writable =\n\t\t\tCursor<C> &&\n\t\t\trequires(C& c, T&& t) {\n\t\t\t\tc.write(std::forward<T>(t)); // Not required to be equality-preserving\n\t\t\t};\n\n\t\ttemplate<class S, class C>\n\t\tMETA_CONCEPT sentinel_for =\n\t\t\tCursor<C> &&\n\t\t\tsemiregular<S> &&\n\t\t\trequires(const C& c, const S& s) {\n\t\t\t\t{ c.equal(s) } -> same_as<bool>;\n\t\t\t};\n\t\ttemplate<class S, class C>\n\t\tMETA_CONCEPT sized_sentinel_for =\n\t\t\tsentinel_for<S, C> &&\n\t\t\trequires(const C& c, const S& s) {\n#ifdef META_HAS_P1084\n\t\t\t\t{ c.distance_to(s) } -> same_as<difference_type_t<C>>;\n#else\n\t\t\t\tc.distance_to(s); requires same_as<decltype((c.distance_to(s))), difference_type_t<C>>;\n#endif // META_HAS_P1084\n\t\t\t};\n\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Next =\n\t\t\tCursor<C> && requires(C& c) { c.next(); };\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT PostIncrement =\n\t\t\tCursor<C> &&\n\t\t\trequires(C& c) {\n\t\t\t\tc.post_increment();\n\t\t\t};\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Prev =\n\t\t\tCursor<C> && requires(C& c) { c.prev(); };\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Advance =\n\t\t\tCursor<C> && requires(C& c, difference_type_t<C> n) {\n\t\t\t\tc.advance(n);\n\t\t\t};\n\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT IndirectMove =\n\t\t\treadable<C> && requires(const C& c) {\n#ifdef META_HAS_P1084\n\t\t\t\t{ c.indirect_move() } -> __can_reference;\n#else\n\t\t\t\tc.indirect_move(); requires __can_reference<decltype(c.indirect_move())>;\n#endif\n\t\t\t};\n\n\t\ttemplate<class> struct rvalue_reference {};\n\t\ttemplate<class C>\n\t\trequires\n\t\t\treadable<C>\n\t\tstruct rvalue_reference<C> {\n\t\t\tusing type = meta::if_<\n\t\t\t\tstd::is_reference<reference_t<C>>,\n\t\t\t\tstd::remove_reference_t<reference_t<C>>&&,\n\t\t\t\tstd::decay_t<reference_t<C>>>;\n\t\t};\n\t\ttemplate<class C>\n\t\trequires\n\t\t\tIndirectMove<C>\n\t\tstruct rvalue_reference<C> {\n\t\t\tusing type = decltype(std::declval<const C&>().indirect_move());\n\t\t};\n\t\ttemplate<class C>\n\t\tusing rvalue_reference_t = meta::_t<rvalue_reference<C>>;\n\n\t\ttemplate<class C1, class C2>\n\t\tMETA_CONCEPT IndirectSwap =\n\t\t\treadable<C1> &&\n\t\t\treadable<C2> &&\n\t\t\trequires(const C1& c1, const C2& c2) {\n\t\t\t\tc1.indirect_swap(c2);\n\t\t\t\tc2.indirect_swap(c1);\n\t\t\t\t// Axiom: If c1.read() == x and c2.read() == y then after either\n\t\t\t\t//   c1.indirect_swap(c2) or c2.indirect_swap(c1), c1.read() == y\n\t\t\t\t//   and c2.read() == x.\n\t\t\t};\n\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Input =\n\t\t\treadable<C> && Next<C>;\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Forward =\n\t\t\tInput<C> && !single_pass<C> && sentinel_for<C, C>;\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Bidirectional =\n\t\t\tForward<C> && Prev<C>;\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT RandomAccess =\n\t\t\tBidirectional<C> && Advance<C> && sized_sentinel_for<C, C>;\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT Contiguous =\n\t\t\tRandomAccess<C> &&\n\t\t\tcontiguous<C> &&\n\t\t\tstd::is_lvalue_reference<reference_t<C>>::value;\n\n\t\ttemplate<class From, class To>\n\t\tMETA_CONCEPT convertible_to =\n\t\t\tCursor<From> &&\n\t\t\tCursor<To> &&\n\t\t\t__stl2::convertible_to<From, To> &&\n\t\t\tconstructible_from<mixin_t<To>, From> &&\n\t\t\tconstructible_from<mixin_t<To>, const From&>;\n\n\t\ttemplate<class>\n\t\tstruct category {};\n\t\ttemplate<Input C>\n\t\tstruct category<C> { using type = input_iterator_tag; };\n\t\ttemplate<Forward C>\n\t\tstruct category<C> { using type = forward_iterator_tag; };\n\t\ttemplate<Bidirectional C>\n\t\tstruct category<C> { using type = bidirectional_iterator_tag; };\n\t\ttemplate<RandomAccess C>\n\t\tstruct category<C> { using type = random_access_iterator_tag; };\n\t\ttemplate<Contiguous C>\n\t\tstruct category<C> { using type = contiguous_iterator_tag; };\n\t\ttemplate<class C>\n\t\tusing category_t = meta::_t<category<C>>;\n\t}\n\n\ttemplate<cursor::Cursor>\n\tclass basic_iterator;\n\n\tnamespace detail {\n\t\ttemplate<class Derived, class Head>\n\t\tstruct proxy_reference_conversion {\n\t\t\toperator Head() const\n\t\t\tnoexcept(noexcept(Head(Head(std::declval<const Derived&>().get_()))))\n\t\t\t{\n\t\t\t\treturn Head(static_cast<const Derived*>(this)->get_());\n\t\t\t}\n\t\t};\n\n\t\ttemplate<class>\n\t\tstruct cursor_traits {\n\t\tprivate:\n\t\t\tstruct private_ {};\n\t\tpublic:\n\t\t\tusing value_t_ = private_;\n\t\t\tusing reference_t_ = private_;\n\t\t\tusing rvalue_reference_t_ = private_;\n\t\t\tusing common_refs = meta::list<>;\n\t\t};\n\n\t\ttemplate<cursor::readable C>\n\t\tstruct cursor_traits<C> {\n\t\t\tusing value_t_ = cursor::value_type_t<C>;\n\t\t\tusing reference_t_ = cursor::reference_t<C>;\n\t\t\tusing rvalue_reference_t_ = cursor::rvalue_reference_t<C>;\n\t\tprivate:\n\t\t\tusing R1 = reference_t_;\n\t\t\tusing R2 = common_reference_t<reference_t_&&, value_t_&>;\n\t\t\tusing R3 = common_reference_t<reference_t_&&, rvalue_reference_t_&&>;\n\t\t\tusing tmp1 = meta::list<value_t_, R1>;\n\t\t\tusing tmp2 =\n\t\t\t\tmeta::if_<meta::in<tmp1, __uncvref<R2>>, tmp1, meta::push_back<tmp1, R2>>;\n\t\t\tusing tmp3 =\n\t\t\t\tmeta::if_<meta::in<tmp2, __uncvref<R3>>, tmp2, meta::push_back<tmp2, R3>>;\n\t\tpublic:\n\t\t\tusing common_refs = meta::unique<meta::pop_front<tmp3>>;\n\t\t};\n\n\t\ttemplate<class Cur>\n\t\tstruct STL2_EMPTY_BASES basic_proxy_reference\n\t\t: cursor_traits<Cur>\n\t\t, meta::inherit<\n\t\t\t\tmeta::transform<\n\t\t\t\t\ttypename cursor_traits<Cur>::common_refs,\n\t\t\t\t\tmeta::bind_front<\n\t\t\t\t\t\tmeta::quote<proxy_reference_conversion>,\n\t\t\t\t\t\tbasic_proxy_reference<Cur>>>>\n\t\t{\n\t\tprivate:\n\t\t\traw_ptr<Cur> cur_;\n\t\t\ttemplate<class>\n\t\t\tfriend struct basic_proxy_reference;\n\t\t\ttemplate<class, class>\n\t\t\tfriend struct proxy_reference_conversion;\n\t\t\tusing typename cursor_traits<Cur>::value_t_;\n\t\t\tusing typename cursor_traits<Cur>::reference_t_;\n\t\t\tusing typename cursor_traits<Cur>::rvalue_reference_t_;\n\t\t\tstatic_assert(common_reference_with<value_t_&, reference_t_&&>,\n\t\t\t\t\"Your readable and writable cursor must have a value type and a reference \"\n\t\t\t\t\"type that share a common reference type. See the ranges::common_reference \"\n\t\t\t\t\"type trait.\");\n\n\t\t\tconstexpr reference_t_ get_() const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\treference_t_(cur_->read())\n\t\t\t)\n\t\t\ttemplate<class T>\n\t\t\tconstexpr void set_(T&& t) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tstatic_cast<void>(cur_->write(static_cast<T&&>(t)))\n\t\t\t)\n\n\t\tpublic:\n\t\t\tbasic_proxy_reference() = default;\n\t\t\tbasic_proxy_reference(const basic_proxy_reference&) = default;\n\t\t\ttemplate<class OtherCur>\n\t\t\trequires convertible_to<OtherCur*, Cur*>\n\t\t\tconstexpr basic_proxy_reference(\n\t\t\t\tconst basic_proxy_reference<OtherCur>& that) noexcept\n\t\t\t: cur_(that.cur_)\n\t\t\t{}\n\t\t\texplicit constexpr basic_proxy_reference(Cur& cur) noexcept\n\t\t\t: cur_(&cur)\n\t\t\t{}\n\t\t\tconstexpr basic_proxy_reference& operator=(basic_proxy_reference&& that)\n\t\t\trequires cursor::readable<Cur>\n\t\t\t{\n\t\t\t\treturn *this = that;\n\t\t\t}\n\t\t\tconstexpr basic_proxy_reference& operator=(const basic_proxy_reference& that)\n\t\t\trequires cursor::readable<Cur>\n\t\t\t{\n\t\t\t\tthis->set_(that.get_());\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tconstexpr const basic_proxy_reference& operator=(basic_proxy_reference&& that) const\n\t\t\trequires cursor::readable<Cur>\n\t\t\t{\n\t\t\t\treturn *this = that;\n\t\t\t}\n\t\t\tconstexpr const basic_proxy_reference& operator=(const basic_proxy_reference& that) const\n\t\t\trequires cursor::readable<Cur>\n\t\t\t{\n\t\t\t\tthis->set_(that.get_());\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\ttemplate<class OtherCur>\n\t\t\trequires\n\t\t\t\tcursor::readable<OtherCur> &&\n\t\t\t\tcursor::writable<Cur, cursor::reference_t<OtherCur>>\n\t\t\tconstexpr basic_proxy_reference& operator=(\n\t\t\t\tbasic_proxy_reference<OtherCur>&& that)\n\t\t\t{\n\t\t\t\treturn *this = that;\n\t\t\t}\n\t\t\ttemplate<class OtherCur>\n\t\t\trequires\n\t\t\t\tcursor::readable<OtherCur> &&\n\t\t\t\tcursor::writable<Cur, cursor::reference_t<OtherCur>>\n\t\t\tconstexpr basic_proxy_reference& operator=(\n\t\t\t\tconst basic_proxy_reference<OtherCur>& that)\n\t\t\t{\n\t\t\t\tthis->set_(that.get_());\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\ttemplate<class OtherCur>\n\t\t\trequires\n\t\t\t\tcursor::readable<OtherCur> &&\n\t\t\t\tcursor::writable<Cur, cursor::reference_t<OtherCur>>\n\t\t\tconstexpr const basic_proxy_reference& operator=(\n\t\t\t\tbasic_proxy_reference<OtherCur>&& that) const\n\t\t\t{\n\t\t\t\treturn *this = that;\n\t\t\t}\n\t\t\ttemplate<class OtherCur>\n\t\t\trequires\n\t\t\t\tcursor::readable<OtherCur> &&\n\t\t\t\tcursor::writable<Cur, cursor::reference_t<OtherCur>>\n\t\t\tconstexpr const basic_proxy_reference& operator=(\n\t\t\t\tconst basic_proxy_reference<OtherCur>& that) const\n\t\t\t{\n\t\t\t\tthis->set_(that.get_());\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\ttemplate<class T>\n\t\t\trequires cursor::writable<Cur, T&&>\n\t\t\tconstexpr basic_proxy_reference& operator=(T&& t)\n\t\t\t{\n\t\t\t\tthis->set_(static_cast<T&&>(t));\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\ttemplate<class T>\n\t\t\trequires cursor::writable<Cur, T&&>\n\t\t\tconstexpr const basic_proxy_reference& operator=(T&& t) const\n\t\t\t{\n\t\t\t\tthis->set_(static_cast<T&&>(t));\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tfriend constexpr bool operator==(\n\t\t\t\tconst basic_proxy_reference& x, const value_t_& y)\n\t\t\trequires cursor::readable<Cur> && equality_comparable<value_t_>\n\t\t\t{\n\t\t\t\treturn x.get_() == y;\n\t\t\t}\n\t\t\tfriend constexpr bool operator!=(\n\t\t\t\tconst basic_proxy_reference& x, const value_t_& y)\n\t\t\trequires cursor::readable<Cur> && equality_comparable<value_t_>\n\t\t\t{\n\t\t\t\treturn !(x == y);\n\t\t\t}\n\t\t\tfriend constexpr bool operator==(\n\t\t\t\tconst value_t_& x, const basic_proxy_reference& y)\n\t\t\trequires cursor::readable<Cur> && equality_comparable<value_t_>\n\t\t\t{\n\t\t\t\treturn x == y.get_();\n\t\t\t}\n\t\t\tfriend constexpr bool operator!=(\n\t\t\t\tconst value_t_& x, const basic_proxy_reference& y)\n\t\t\trequires cursor::readable<Cur> && equality_comparable<value_t_>\n\t\t\t{\n\t\t\t\treturn !(x == y);\n\t\t\t}\n\t\t\tfriend constexpr bool operator==(\n\t\t\t\tconst basic_proxy_reference& x, const basic_proxy_reference& y)\n\t\t\trequires cursor::readable<Cur> && equality_comparable<value_t_>\n\t\t\t{\n\t\t\t\treturn x.get_() == y.get_();\n\t\t\t}\n\t\t\tfriend constexpr bool operator!=(\n\t\t\t\tconst basic_proxy_reference& x, const basic_proxy_reference& y)\n\t\t\trequires cursor::readable<Cur> && equality_comparable<value_t_>\n\t\t\t{\n\t\t\t\treturn !(x == y);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<class>\n\t\tconstexpr bool is_writable = true;\n\t\ttemplate<class C>\n\t\trequires\n\t\t\tcursor::readable<std::remove_cv_t<C>>\n\t\tconstexpr bool is_writable<C> = false;\n\t\ttemplate<class C>\n\t\trequires\n\t\t\tcursor::readable<std::remove_cv_t<C>> &&\n\t\t\tcursor::writable<C, cursor::value_type_t<C>&&>\n\t\tconstexpr bool is_writable<C> = true;\n\n\t\ttemplate<class Cur>\n\t\tstruct iterator_associated_types_base {\n\t\t\tusing reference_t = basic_proxy_reference<Cur>;\n\t\t\tusing const_reference_t = basic_proxy_reference<const Cur>;\n\t\t};\n\n\t\ttemplate<cursor::readable Cur>\n\t\tstruct iterator_associated_types_base<Cur> {\n\t\t\tusing reference_t =\n\t\t\t\tmeta::if_c<\n\t\t\t\t\tis_writable<const Cur>,\n\t\t\t\t\tbasic_proxy_reference<const Cur>,\n\t\t\t\t\tmeta::if_c<\n\t\t\t\t\t\tis_writable<Cur>,\n\t\t\t\t\t\tbasic_proxy_reference<Cur>,\n\t\t\t\t\t\tcursor::reference_t<Cur>>>;\n\t\t\tusing const_reference_t =\n\t\t\t\tmeta::if_c<\n\t\t\t\t\tis_writable<const Cur>,\n\t\t\t\t\tbasic_proxy_reference<const Cur>,\n\t\t\t\t\tcursor::reference_t<Cur>>;\n\t\t};\n\n\t\ttemplate<class C>\n\t\tMETA_CONCEPT PostIncrementCursor = cursor::PostIncrement<C> && requires(C& c) {\n#ifdef META_HAS_P1084\n\t\t\t{ c.post_increment() } -> same_as<C>;\n#else\n\t\t\tc.post_increment(); requires same_as<decltype((c.post_increment())), C>;\n#endif // META_HAS_P1084\n\t\t};\n\t} // namespace detail\n\n\t// common_reference specializations for basic_proxy_reference\n\ttemplate<cursor::readable Cur, class U,\n\t\ttemplate<class> class TQual, template<class> class UQual>\n\tstruct basic_common_reference<\n\t\tdetail::basic_proxy_reference<Cur>, U, TQual, UQual>\n\t: basic_common_reference<cursor::reference_t<Cur>, U, TQual, UQual>\n\t{};\n\ttemplate<class T, cursor::readable Cur,\n\t\ttemplate<class> class TQual, template<class> class UQual>\n\tstruct basic_common_reference<\n\t\tT, detail::basic_proxy_reference<Cur>, TQual, UQual>\n\t: basic_common_reference<T, cursor::reference_t<Cur>, TQual, UQual>\n\t{};\n\ttemplate<cursor::readable Cur1, cursor::readable Cur2,\n\t\ttemplate<class> class TQual, template<class> class UQual>\n\tstruct basic_common_reference<\n\t\tdetail::basic_proxy_reference<Cur1>, detail::basic_proxy_reference<Cur2>,\n\t\tTQual, UQual>\n\t: basic_common_reference<\n\t\t\tcursor::reference_t<Cur1>, cursor::reference_t<Cur2>, TQual, UQual>\n\t{};\n\n\t// common_type specializations for basic_proxy_reference\n\ttemplate<cursor::readable Cur, class U>\n\tstruct common_type<detail::basic_proxy_reference<Cur>, U>\n\t: common_type<cursor::value_type_t<Cur>, U>\n\t{};\n\ttemplate<class T, cursor::readable Cur>\n\tstruct common_type<T, detail::basic_proxy_reference<Cur>>\n\t: common_type<T, cursor::value_type_t<Cur>>\n\t{};\n\ttemplate<cursor::readable Cur1, cursor::readable Cur2>\n\tstruct common_type<\n\t\tdetail::basic_proxy_reference<Cur1>, detail::basic_proxy_reference<Cur2>>\n\t: common_type<cursor::value_type_t<Cur1>, cursor::value_type_t<Cur2>>\n\t{};\n\n\tstruct __get_cursor_fn {\n\t\ttemplate<_SpecializationOf<basic_iterator> BI>\n\t\tconstexpr auto&& operator()(BI&& i) const\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\tstatic_cast<BI&&>(i).get()\n\t\t)\n\t};\n\tinline constexpr __get_cursor_fn get_cursor{};\n\n\tnamespace basic_iterator_adl {\n\t\tstruct hook {};\n\n\t\ttemplate<class C>\n\t\trequires cursor::IndirectMove<C>\n\t\tconstexpr decltype(auto) iter_move(const basic_iterator<C>& i)\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\tget_cursor(i).indirect_move()\n\t\t)\n\n\t\ttemplate<class C1, class C2>\n\t\trequires cursor::IndirectSwap<C1, C2>\n\t\tconstexpr void iter_swap(\n\t\t\tconst basic_iterator<C1>& x, const basic_iterator<C2>& y)\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\tstatic_cast<void>(get_cursor(x).indirect_swap(get_cursor(y)))\n\t\t)\n\t} // namespace basic_iterator_adl\n\n\ttemplate<cursor::Cursor C>\n\tclass STL2_EMPTY_BASES basic_iterator\n\t: public mixin_t<C>\n\t, detail::iterator_associated_types_base<C>\n\t, basic_iterator_adl::hook\n\t{\n\t\tfriend __get_cursor_fn;\n\n\t\tusing mixin = mixin_t<C>;\n\t\tusing mixin::get;\n\n\t\tusing assoc_t = detail::iterator_associated_types_base<C>;\n\t\tusing typename assoc_t::reference_t;\n\t\tusing typename assoc_t::const_reference_t;\n\n\t\tusing D = cursor::difference_type_t<C>;\n\n\tpublic:\n\t\tbasic_iterator() = default;\n\t\ttemplate<cursor::convertible_to<C> O>\n\t\tconstexpr basic_iterator(basic_iterator<O>&& that)\n\t\tnoexcept(std::is_nothrow_constructible<mixin, O>::value)\n\t\t: mixin(get_cursor(std::move(that))) {}\n\t\ttemplate<cursor::convertible_to<C> O>\n\t\tconstexpr basic_iterator(const basic_iterator<O>& that)\n\t\tnoexcept(std::is_nothrow_constructible<mixin, const O&>::value)\n\t\t: mixin(get_cursor(that)) {}\n\t\tconstexpr explicit basic_iterator(const C& c)\n\t\tnoexcept(std::is_nothrow_constructible<mixin, const C&>::value)\n\t\t: mixin(c) {}\n\t\tconstexpr explicit basic_iterator(C&& c)\n\t\tnoexcept(std::is_nothrow_constructible<mixin, C>::value)\n\t\t: mixin(std::move(c)) {}\n\t\tusing mixin::mixin;\n\n\t\ttemplate<cursor::convertible_to<C> O>\n\t\tconstexpr basic_iterator& operator=(basic_iterator<O>&& that) &\n\t\tnoexcept(std::is_nothrow_assignable<C&, O>::value)\n\t\t{\n\t\t\tget() = get_cursor(std::move(that));\n\t\t\treturn *this;\n\t\t}\n\t\ttemplate<cursor::convertible_to<C> O>\n\t\tconstexpr basic_iterator& operator=(const basic_iterator<O>& that) &\n\t\tnoexcept(std::is_nothrow_assignable<C&, const O&>::value)\n\t\t{\n\t\t\tget() = get_cursor(that);\n\t\t\treturn *this;\n\t\t}\n\t\ttemplate<class T>\n\t\trequires (!same_as<std::decay_t<T>, basic_iterator> && !cursor::Next<C> &&\n\t\t\tcursor::writable<C, T>)\n\t\tconstexpr basic_iterator& operator=(T&& t)\n\t\tnoexcept(noexcept(\n\t\t\tstd::declval<C&>().write(static_cast<T&&>(t))))\n\t\t{\n\t\t\tget().write(static_cast<T&&>(t));\n\t\t\treturn *this;\n\t\t}\n\t\t// Not to spec: This operator= needs to be proposed for\n\t\t// http://wg21.link/P0186\n\t\ttemplate<class O>\n\t\trequires\n\t\t\t(!same_as<std::decay_t<O>, basic_iterator> &&\n\t\t\tassignable_from<C&, O>)\n\t\tconstexpr basic_iterator& operator=(O&& o) &\n\t\tnoexcept(std::is_nothrow_assignable<C&, O>::value)\n\t\t{\n\t\t\tget() = std::forward<O>(o);\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr decltype(auto) operator*() const\n\t\tnoexcept(noexcept(std::declval<const C&>().read()))\n\t\trequires (cursor::readable<C> && !detail::is_writable<C>)\n\t\t{\n\t\t\treturn get().read();\n\t\t}\n\t\tconstexpr decltype(auto) operator*()\n\t\tnoexcept(noexcept(reference_t{std::declval<mixin&>().get()}))\n\t\trequires cursor::Next<C> && detail::is_writable<C>\n\t\t{\n\t\t\treturn reference_t{get()};\n\t\t}\n\t\tconstexpr decltype(auto) operator*() const\n\t\tnoexcept(noexcept(\n\t\t\tconst_reference_t{std::declval<const mixin&>().get()}))\n\t\trequires cursor::Next<C> && detail::is_writable<C>\n\t\t{\n\t\t\treturn const_reference_t{get()};\n\t\t}\n\t\tconstexpr basic_iterator& operator*() noexcept\n\t\trequires (!cursor::Next<C>)\n\t\t{\n\t\t\treturn *this;\n\t\t}\n\n\t\t// Use cursor's arrow() member, if any.\n\t\tconstexpr decltype(auto) operator->() const\n\t\tnoexcept(noexcept(std::declval<const C&>().arrow()))\n\t\trequires cursor::Arrow<C>\n\t\t{\n\t\t\treturn get().arrow();\n\t\t}\n\t\t// Otherwise, if reference_t is an lvalue reference to cv-qualified\n\t\t// value_type_t, return the address of **this.\n\t\ttemplate<class BugsBugs = C> // Workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71965\n\t\tconstexpr auto operator->() const\n\t\tnoexcept(noexcept(*std::declval<const basic_iterator&>()))\n\t\trequires\n\t\t\t(!cursor::Arrow<C> && cursor::readable<C> &&\n\t\t\tstd::is_lvalue_reference<const_reference_t>::value &&\n\t\t\tsame_as<cursor::value_type_t<BugsBugs>, __uncvref<const_reference_t>>)\n\t\t{\n\t\t\treturn std::addressof(**this);\n\t\t}\n\n\t\tconstexpr basic_iterator& operator++() & noexcept {\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr basic_iterator& operator++() &\n\t\tnoexcept(noexcept(std::declval<C&>().next()))\n\t\trequires cursor::Next<C>\n\t\t{\n\t\t\tget().next();\n\t\t\treturn *this;\n\t\t}\n\n#if STL2_WORKAROUND_GCC_UNKNOWN1\n\t\ttemplate<class CC = C>\n\t\tconstexpr basic_iterator operator++(int) &\n\t\tnoexcept(std::is_nothrow_copy_constructible<basic_iterator>::value &&\n\t\t\tstd::is_nothrow_move_constructible<basic_iterator>::value &&\n\t\t\tnoexcept(++std::declval<basic_iterator&>()))\n\t\t{\n\t\t\tauto tmp(*this);\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\ttemplate<class CC = C>\n\t\tconstexpr void operator++(int) &\n\t\tnoexcept(noexcept(++std::declval<basic_iterator&>()))\n\t\trequires (cursor::Input<CC> && !cursor::Forward<CC>\n\t\t\t&& !cursor::PostIncrement<CC>)\n\t\t{\n\t\t\t++*this;\n\t\t}\n\n\t\ttemplate<class CC = C>\n\t\tconstexpr decltype(auto) operator++(int) &\n\t\tnoexcept(noexcept(std::declval<C&>().post_increment()))\n\t\trequires cursor::PostIncrement<CC>\n\t\t{\n\t\t\treturn get().post_increment();\n\t\t}\n\t\ttemplate<class CC = C>\n\t\tconstexpr basic_iterator operator++(int) &\n\t\tnoexcept(noexcept(basic_iterator{std::declval<C&>().post_increment()}))\n\t\trequires detail::PostIncrementCursor<CC>\n\t\t{\n\t\t\treturn basic_iterator{get().post_increment()};\n\t\t}\n#else // ^^^ workaround / no workaround vvv\n\t\tconstexpr basic_iterator operator++(int) &\n\t\tnoexcept(std::is_nothrow_copy_constructible<basic_iterator>::value &&\n\t\t\tstd::is_nothrow_move_constructible<basic_iterator>::value &&\n\t\t\tnoexcept(++std::declval<basic_iterator&>()))\n\t\t{\n\t\t\tauto tmp(*this);\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr void operator++(int) &\n\t\tnoexcept(noexcept(++std::declval<basic_iterator&>()))\n\t\trequires (cursor::Input<C> && !cursor::Forward<C> && !cursor::PostIncrement<C>)\n\t\t{\n\t\t\t++*this;\n\t\t}\n\n\t\tconstexpr decltype(auto) operator++(int) &\n\t\tnoexcept(noexcept(std::declval<C&>().post_increment()))\n\t\trequires cursor::PostIncrement<C>\n\t\t{\n\t\t\treturn get().post_increment();\n\t\t}\n\t\tconstexpr basic_iterator operator++(int) &\n\t\tnoexcept(noexcept(basic_iterator{std::declval<C&>().post_increment()}))\n\t\trequires detail::PostIncrementCursor<C>\n\t\t{\n\t\t\treturn basic_iterator{get().post_increment()};\n\t\t}\n#endif // STL2_WORKAROUND_GCC_UNKNOWN1\n\n\t\tconstexpr basic_iterator& operator--() &\n\t\tnoexcept(noexcept(std::declval<C&>().prev()))\n\t\trequires cursor::Bidirectional<C>\n\t\t{\n\t\t\tget().prev();\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr basic_iterator operator--(int) &\n\t\tnoexcept(std::is_nothrow_copy_constructible<basic_iterator>::value &&\n\t\t\tstd::is_nothrow_move_constructible<basic_iterator>::value &&\n\t\t\tnoexcept(--std::declval<basic_iterator&>()))\n\t\trequires cursor::Bidirectional<C>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t--*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr basic_iterator& operator+=(D n) &\n\t\tnoexcept(noexcept(std::declval<C&>().advance(n)))\n\t\trequires cursor::RandomAccess<C>\n\t\t{\n\t\t\tget().advance(n);\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr basic_iterator& operator-=(D n) &\n\t\tnoexcept(noexcept(std::declval<C&>().advance(-n)))\n\t\trequires cursor::RandomAccess<C>\n\t\t{\n\t\t\tget().advance(-n);\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr decltype(auto) operator[](D n) const\n\t\tnoexcept(noexcept(*(std::declval<basic_iterator&>() + n)))\n\t\trequires cursor::RandomAccess<C>\n\t\t{\n\t\t\treturn *(*this + n);\n\t\t}\n\n\t\t// non-template type-symmetric operators to enable\n\t\t// implicit conversions.\n\t\tfriend constexpr bool operator==(\n\t\t\tconst basic_iterator& x, const basic_iterator& y)\n\t\tnoexcept(noexcept(x.get().equal(y.get())))\n\t\trequires cursor::sentinel_for<C, C>\n\t\t{\n\t\t\treturn x.get().equal(y.get());\n\t\t}\n\t\tfriend constexpr bool operator!=(\n\t\t\tconst basic_iterator& x, const basic_iterator& y)\n\t\tnoexcept(noexcept(!(x == y)))\n\t\trequires cursor::sentinel_for<C, C>\n\t\t{\n\t\t\treturn !(x == y);\n\t\t}\n\n\t\tfriend constexpr D operator-(\n\t\t\tconst basic_iterator& x, const basic_iterator& y)\n\t\tnoexcept(noexcept(y.get().distance_to(x.get())))\n\t\trequires cursor::sized_sentinel_for<C, C>\n\t\t{\n\t\t\treturn y.get().distance_to(x.get());\n\t\t}\n\n\t\tfriend constexpr bool operator<(\n\t\t\tconst basic_iterator& x, const basic_iterator& y)\n\t\tnoexcept(noexcept(x - y))\n\t\trequires cursor::sized_sentinel_for<C, C>\n\t\t{\n\t\t\treturn x - y < 0;\n\t\t}\n\t\tfriend constexpr bool operator>(\n\t\t\tconst basic_iterator& x, const basic_iterator& y)\n\t\tnoexcept(noexcept(x - y))\n\t\trequires cursor::sized_sentinel_for<C, C>\n\t\t{\n\t\t\treturn x - y > 0;\n\t\t}\n\t\tfriend constexpr bool operator<=(\n\t\t\tconst basic_iterator& x, const basic_iterator& y)\n\t\tnoexcept(noexcept(x - y))\n\t\trequires cursor::sized_sentinel_for<C, C>\n\t\t{\n\t\t\treturn x - y <= 0;\n\t\t}\n\t\tfriend constexpr bool operator>=(\n\t\t\tconst basic_iterator& x, const basic_iterator& y)\n\t\tnoexcept(noexcept(x - y))\n\t\trequires cursor::sized_sentinel_for<C, C>\n\t\t{\n\t\t\treturn x - y >= 0;\n\t\t}\n\t};\n\n\ttemplate<class C>\n\tstruct incrementable_traits<basic_iterator<C>> {\n\t\tusing difference_type = cursor::difference_type_t<C>;\n\t};\n\n\ttemplate<cursor::Input C>\n\tstruct iterator_category<basic_iterator<C>> {\n\t\tusing type = cursor::category_t<C>;\n\t};\n\n\ttemplate<cursor::Input C>\n\tstruct readable_traits<basic_iterator<C>> {\n\t\tusing value_type = cursor::value_type_t<C>;\n\t};\n\n\ttemplate<class C>\n\tconstexpr basic_iterator<C> operator+(\n\t\tconst basic_iterator<C>& i, cursor::difference_type_t<C> n)\n\tnoexcept(std::is_nothrow_copy_constructible<basic_iterator<C>>::value &&\n\t\tstd::is_nothrow_move_constructible<basic_iterator<C>>::value &&\n\t\tnoexcept(std::declval<basic_iterator<C>&>() += n))\n\trequires cursor::RandomAccess<C>\n\t{\n\t\tauto tmp = i;\n\t\ttmp += n;\n\t\treturn tmp;\n\t}\n\ttemplate<class C>\n\tconstexpr basic_iterator<C> operator+(\n\t\tcursor::difference_type_t<C> n, const basic_iterator<C>& i)\n\tnoexcept(noexcept(i + n))\n\trequires cursor::RandomAccess<C>\n\t{\n\t\treturn i + n;\n\t}\n\ttemplate<class C>\n\tconstexpr basic_iterator<C> operator-(\n\t\tconst basic_iterator<C>& i, cursor::difference_type_t<C> n)\n\tnoexcept(noexcept(i + -n))\n\trequires cursor::RandomAccess<C>\n\t{\n\t\treturn i + -n;\n\t}\n\n\ttemplate<class C1, class C2>\n\trequires cursor::sentinel_for<C2, C1>\n\tconstexpr bool operator==(\n\t\tconst basic_iterator<C1>& lhs, const basic_iterator<C2>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tget_cursor(lhs).equal(get_cursor(rhs))\n\t)\n\n\ttemplate<class C, class S>\n\trequires cursor::sentinel_for<S, C>\n\tconstexpr bool operator==(\n\t\tconst basic_iterator<C>& lhs, const S& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tget_cursor(lhs).equal(rhs)\n\t)\n\n\ttemplate<class C, class S>\n\trequires cursor::sentinel_for<S, C>\n\tconstexpr bool operator==(\n\t\tconst S& lhs, const basic_iterator<C>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\trhs == lhs\n\t)\n\n\ttemplate<class C1, class C2>\n\trequires cursor::sentinel_for<C2, C1>\n\tconstexpr bool operator!=(\n\t\tconst basic_iterator<C1>& lhs, const basic_iterator<C2>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t!(lhs == rhs)\n\t)\n\n\ttemplate<class C, class S>\n\trequires cursor::sentinel_for<S, C>\n\tconstexpr bool operator!=(\n\t\tconst basic_iterator<C>& lhs, const S& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t!get_cursor(lhs).equal(rhs)\n\t)\n\n\ttemplate<class C, class S>\n\trequires cursor::sentinel_for<S, C>\n\tconstexpr bool operator!=(\n\t\tconst S& lhs, const basic_iterator<C>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t!get_cursor(rhs).equal(lhs)\n\t)\n\n\ttemplate<class C1, class C2>\n\trequires cursor::sized_sentinel_for<C1, C2>\n\tconstexpr cursor::difference_type_t<C2> operator-(\n\t\tconst basic_iterator<C1>& lhs, const basic_iterator<C2>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tget_cursor(rhs).distance_to(get_cursor(lhs))\n\t)\n\n\ttemplate<class C, class S>\n\trequires cursor::sized_sentinel_for<S, C>\n\tconstexpr cursor::difference_type_t<C> operator-(\n\t\tconst S& lhs, const basic_iterator<C>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tget_cursor(rhs).distance_to(lhs)\n\t)\n\n\ttemplate<class C, class S>\n\trequires cursor::sized_sentinel_for<S, C>\n\tconstexpr cursor::difference_type_t<C> operator-(\n\t\tconst basic_iterator<C>& lhs, const S& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t-(rhs - lhs)\n\t)\n\n\ttemplate<class C1, class C2>\n\trequires cursor::sized_sentinel_for<C1, C2>\n\tconstexpr bool operator<(\n\t\tconst basic_iterator<C1>& lhs, const basic_iterator<C2>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tlhs - rhs < 0\n\t)\n\n\ttemplate<class C1, class C2>\n\trequires cursor::sized_sentinel_for<C1, C2>\n\tconstexpr bool operator>(\n\t\tconst basic_iterator<C1>& lhs, const basic_iterator<C2>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tlhs - rhs > 0\n\t)\n\n\ttemplate<class C1, class C2>\n\trequires cursor::sized_sentinel_for<C1, C2>\n\tconstexpr bool operator<=(\n\t\tconst basic_iterator<C1>& lhs, const basic_iterator<C2>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tlhs - rhs <= 0\n\t)\n\n\ttemplate<class C1, class C2>\n\trequires cursor::sized_sentinel_for<C1, C2>\n\tconstexpr bool operator>=(\n\t\tconst basic_iterator<C1>& lhs, const basic_iterator<C2>& rhs)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tlhs - rhs >= 0\n\t)\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/common_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_COMMON_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_COMMON_ITERATOR_HPP\n\n#include <memory>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/variant.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/operations.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// common_iterator [common.iterators]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\trequires (!same_as<I, S>)\n\tclass common_iterator;\n\n\tnamespace __common_iterator {\n\t\ttemplate<class T>\n\t\tstruct operator_arrow_proxy {\n\t\t\ttemplate<class U>\n\t\t\tconstexpr explicit operator_arrow_proxy(U&& u)\n\t\t\tnoexcept(std::is_nothrow_constructible_v<T, U>)\n\t\t\trequires constructible_from<T, U>\n\t\t\t: value_(std::forward<U>(u)) {}\n\n\t\t\tconstexpr const T* operator->() const noexcept {\n\t\t\t\treturn std::addressof(value_);\n\t\t\t}\n\t\tprivate:\n\t\t\tT value_;\n\t\t};\n\n\t\tstruct access {\n\t\t\ttemplate<_SpecializationOf<common_iterator> C>\n\t\t\tstatic constexpr decltype(auto) v(C&& c) noexcept {\n\t\t\t\treturn (std::forward<C>(c).v_);\n\t\t\t}\n\n\t\t\t// Not to spec: Here to avoid LLVM 37556\n\t\t\ttemplate<input_iterator I, class S>\n\t\t\tfriend iter_rvalue_reference_t<I>\n\t\t\titer_move(const common_iterator<I, S>& i)\n\t\t\tnoexcept(noexcept(__stl2::iter_move(std::declval<const I&>()))) {\n\t\t\t\treturn __stl2::iter_move(__stl2::__unchecked_get<I>(v(i)));\n\t\t\t}\n\t\t\ttemplate<class I1, class S1, indirectly_swappable<I1> I2, class S2>\n\t\t\tfriend void iter_swap(\n\t\t\t\tconst common_iterator<I1, S1>& x, const common_iterator<I2, S2>& y)\n\t\t\tnoexcept(noexcept(__stl2::iter_swap(std::declval<const I1&>(),\n\t\t\t\tstd::declval<const I2&>())))\n\t\t\t{\n\t\t\t\t__stl2::iter_swap(\n\t\t\t\t\t__stl2::__unchecked_get<I1>(v(x)),\n\t\t\t\t\t__stl2::__unchecked_get<I2>(v(y)));\n\t\t\t}\n\n\t\t\t// Not to spec: here avoid GCC hidden friend constraint bugs\n\t\t\ttemplate<class I1, class S1, sized_sentinel_for<I1> I2, sized_sentinel_for<I1> S2>\n\t\t\trequires sized_sentinel_for<S1, I2>\n\t\t\tfriend iter_difference_t<I2> operator-(\n\t\t\t\tconst common_iterator<I1, S1>& x, const common_iterator<I2, S2>& y)\n\t\t\t{\n\t\t\t\treturn __stl2::__unchecked_visit(\n\t\t\t\t\tdifference_visitor<I1, S1, I2, S2>{}, v(x), v(y));\n\t\t\t}\n\n\t\tprivate:\n\t\t\ttemplate<class I1, sentinel_for<I1> S1, class I2, sentinel_for<I2> S2>\n\t\t\trequires sized_sentinel_for<I2, I1> && sized_sentinel_for<S2, I1> &&\n\t\t\t\tsized_sentinel_for<S1, I2>\n\t\t\tstruct difference_visitor {\n\t\t\t\ttemplate<class T, class U>\n\t\t\t\tconstexpr iter_difference_t<I2>\n\t\t\t\toperator()(const T& lhs, const U& rhs) const\n\t\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t\tstatic_cast<iter_difference_t<I2>>(lhs - rhs)\n\t\t\t\t)\n\t\t\t\tconstexpr iter_difference_t<I2>\n\t\t\t\toperator()(const S1&, const S2&) const noexcept {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\n\t\ttemplate<class I1, sentinel_for<I1> S1, class I2, sentinel_for<I2> S2>\n\t\trequires convertible_to<const I2&, I1> && convertible_to<const S2&, S1>\n\t\tstruct convert_visitor {\n\t\t\tconstexpr auto operator()(const I2& i) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tstd::variant<I1, S1>{std::in_place_index<0>, i}\n\t\t\t)\n\t\t\tconstexpr auto operator()(const S2& s) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tstd::variant<I1, S1>{std::in_place_index<1>, s}\n\t\t\t)\n\t\t};\n\n\t\ttemplate<class I1, sentinel_for<I1> S1, class I2, sentinel_for<I2> S2>\n\t\trequires convertible_to<const I2&, I1> && convertible_to<const S2&, S1> &&\n\t\t\tassignable_from<I1&, const I2&> && assignable_from<S1&, const S2&>\n\t\tstruct assign_visitor {\n\t\t\tstd::variant<I1, S1>& v_;\n\n\t\t\tvoid operator()(I1& i1, const I2& i2) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)(i1 = i2)\n\t\t\t)\n\t\t\tvoid operator()(S1& s1, const S2& s2) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)(s1 = s2)\n\t\t\t)\n\t\t\tvoid operator()(const S1&, const I2& i2) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)v_.template emplace<I1>(i2)\n\t\t\t)\n\t\t\tvoid operator()(const I1&, const S2& s2) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)v_.template emplace<S1>(s2)\n\t\t\t)\n\t\t};\n\n\t\ttemplate<class I1, sentinel_for<I1> S1, class I2, sentinel_for<I2> S2>\n\t\trequires sentinel_for<S1, I2>\n\t\tstruct equal_visitor {\n\t\t\tconstexpr bool operator()(const I1&, const I2&) const noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconstexpr bool operator()(const I1& i1, const I2& i2) const\n\t\t\tnoexcept(noexcept(bool(i1 == i2)))\n\t\t\trequires equality_comparable_with<I1, I2> {\n\t\t\t\treturn i1 == i2;\n\t\t\t}\n\t\t\tconstexpr bool operator()(const S1&, const S2&) const noexcept {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttemplate<class T, class U>\n\t\t\tconstexpr bool operator()(const T& lhs, const U& rhs) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tbool(lhs == rhs)\n\t\t\t)\n\t\t};\n\t}\n\n\ttemplate<class I>\n\tMETA_CONCEPT _HasArrow = requires(I& i) { i.operator->(); };\n\n\t// common_iterator [common.iterator]\n\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\trequires (!same_as<I, S>)\n\tclass common_iterator\n\t: __common_iterator::access\n\t{\n\t\tfriend __common_iterator::access;\n\n\t\tstd::variant<I, S> v_;\n\n\tpublic:\n\t\tconstexpr common_iterator() = default;\n\n\t\tconstexpr common_iterator(I i)\n\t\tnoexcept(std::is_nothrow_constructible_v<std::variant<I, S>, I>) // strengthened\n\t\t: v_{std::in_place_type<I>, std::move(i)} {}\n\n\t\tconstexpr common_iterator(S s)\n\t\tnoexcept(std::is_nothrow_constructible_v<std::variant<I, S>, S>) // strengthened\n\t\t: v_{std::in_place_type<S>, std::move(s)} {}\n\n\t\ttemplate<class I2, class S2>\n\t\trequires convertible_to<const I2&, I> && convertible_to<const S2&, S>\n\t\tconstexpr common_iterator(const common_iterator<I2, S2>& i)\n\t\tnoexcept(\n\t\t\tstd::is_nothrow_constructible_v<I, const I2&> &&\n\t\t\tstd::is_nothrow_constructible_v<S, const S2&>) // strengthened\n\t\t: v_{__stl2::__unchecked_visit(\n\t\t\t__common_iterator::convert_visitor<I, S, I2, S2>{},\n\t\t\t__common_iterator::access::v(i))}\n\t\t{}\n\n\t\ttemplate<class I2, class S2>\n\t\trequires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&\n\t\t\tassignable_from<I&, const I2&> && assignable_from<S&, const S2&>\n\t\tcommon_iterator& operator=(const common_iterator<I2, S2>& i)\n\t\tnoexcept(\n\t\t\tstd::is_nothrow_assignable_v<I&, const I2&> &&\n\t\t\tstd::is_nothrow_assignable_v<S&, const S2&>) // strengthened\n\t\t{\n\t\t\t__stl2::__unchecked_visit(\n\t\t\t\t__common_iterator::assign_visitor<I, S, I2, S2>{v_}, v_,\n\t\t\t\t__common_iterator::access::v(i));\n\t\t\treturn *this;\n\t\t}\n\n\t\tdecltype(auto) operator*()\n\t\tnoexcept(noexcept(*std::declval<I&>())) { // strengthened\n\t\t\treturn *__stl2::__unchecked_get<I>(v_);\n\t\t}\n\t\tdecltype(auto) operator*() const\n\t\tnoexcept(noexcept(*std::declval<const I&>())) // strengthened\n\t\trequires __dereferenceable<const I> {\n\t\t\treturn *__stl2::__unchecked_get<I>(v_);\n\t\t}\n\t\tdecltype(auto) operator->() const\n\t\trequires readable<const I> &&\n\t\t\t(_HasArrow<const I> ||\n\t\t\t std::is_reference_v<iter_reference_t<I>> ||\n\t\t\t constructible_from<iter_value_t<I>, iter_reference_t<I>>)\n\t\t{\n\t\t\tif constexpr (std::is_pointer_v<I> || _HasArrow<const I>)\n\t\t\t\treturn __stl2::__unchecked_get<I>(v_);\n\t\t\telse if constexpr (std::is_reference_v<iter_reference_t<const I>>) { // TODO: file LWG issue (const I instead of I)\n\t\t\t\tauto&& tmp = *__stl2::__unchecked_get<I>(v_);\n\t\t\t\treturn std::addressof(tmp);\n\t\t\t} else {\n\t\t\t\treturn __common_iterator::operator_arrow_proxy<iter_value_t<I>>{\n\t\t\t\t\t*__stl2::__unchecked_get<I>(v_)\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tcommon_iterator& operator++()\n\t\tnoexcept(noexcept(++std::declval<I&>())) { // strengthened\n\t\t\t++__stl2::__unchecked_get<I>(v_);\n\t\t\treturn *this;\n\t\t}\n\t\tdecltype(auto) operator++(int)\n\t\t{\n\t\t\tauto& i = __stl2::__unchecked_get<I>(v_);\n\t\t\tif constexpr (forward_iterator<I>) {\n\t\t\t\tauto tmp = *this;\n\t\t\t\t++i;\n\t\t\t\treturn tmp;\n\t\t\t} else\n\t\t\t\treturn i++;\n\t\t}\n\n\t\ttemplate<class I2, sentinel_for<I> S2>\n\t\trequires sentinel_for<S, I2>\n\t\tfriend bool\n\t\toperator==(const common_iterator& x, const common_iterator<I2, S2>& y) {\n\t\t\treturn __stl2::__unchecked_visit(\n\t\t\t\t__common_iterator::equal_visitor<I, S, I2, S2>{}, x.v_,\n\t\t\t\t__common_iterator::access::v(y));\n\t\t}\n\t\ttemplate<class I2, sentinel_for<I> S2>\n\t\trequires sentinel_for<S, I2>\n\t\tfriend bool\n\t\toperator!=(const common_iterator& x, const common_iterator<I2, S2>& y) {\n\t\t\treturn !(x == y);\n\t\t}\n\t};\n\n\ttemplate<class I, class S>\n\tstruct incrementable_traits<common_iterator<I, S>> {\n\t\tusing difference_type = iter_difference_t<I>;\n\t};\n\n\ttemplate<readable I, class S>\n\tstruct readable_traits<common_iterator<I, S>> {\n\t\tusing value_type = iter_value_t<I>;\n\t};\n\n\ttemplate<input_iterator I, class S>\n\tstruct iterator_category<common_iterator<I, S>> {\n\t\tusing type = input_iterator_tag;\n\t};\n\ttemplate<forward_iterator I, class S>\n\tstruct iterator_category<common_iterator<I, S>> {\n\t\tusing type = forward_iterator_tag;\n\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/concepts.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_CONCEPTS_HPP\n#define STL2_DETAIL_ITERATOR_CONCEPTS_HPP\n\n#include <functional>\n#include <iterator>\n\n#include <stl2/type_traits.hpp>\n#include <stl2/utility.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/fundamental.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/increment.hpp>\n\n////////////////////////////////////////////////////////////////////////////////\n// Iterator concepts [iterator.requirements]\n//\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class T>\n\tMETA_CONCEPT __dereferenceable = requires(T& t) {\n#ifdef META_HAS_P1084\n\t\t{ *t } -> __can_reference;\n#else\n\t\t*t; typename __with_reference<decltype(*t)>;\n#endif\n\t};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// iter_reference_t [iterator.assoc]\n\t//\n\ttemplate<__dereferenceable R>\n\tusing iter_reference_t = decltype(*std::declval<R&>());\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// iter_move\n\t//\n\tnamespace __iter_move {\n\t\t// Not a poison pill, simply a non-ADL block.\n\t\tvoid iter_move(); // undefined\n\n\t\ttemplate<class>\n\t\tconstexpr bool has_customization = false;\n\t\ttemplate<class R>\n\t\trequires __dereferenceable<R> &&\n\t\t\trequires(R&& r) {\n#ifdef META_HAS_P1084\n\t\t\t\t{ iter_move(static_cast<R&&>(r)) } ->__can_reference;\n#else\n\t\t\t\titer_move(static_cast<R&&>(r));\n\t\t\t\trequires __can_reference<decltype(iter_move(static_cast<R&&>(r)))>;\n#endif\n\t\t\t}\n\t\tconstexpr bool has_customization<R> = true;\n\n\t\ttemplate<class R>\n\t\tusing rvalue =\n\t\t\tmeta::if_<std::is_reference<R>, std::remove_reference_t<R>&&, std::decay_t<R>>;\n\n\t\tstruct fn {\n\t\t\ttemplate<class R>\n\t\t\trequires __dereferenceable<R> && has_customization<R>\n\t\t\tconstexpr decltype(auto) operator()(R&& r) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\titer_move((R&&)r)\n\t\t\t)\n\n\t\t\ttemplate<class R>\n\t\t\trequires __dereferenceable<R>\n\t\t\tconstexpr rvalue<iter_reference_t<R>> operator()(R&& r) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tstatic_cast<rvalue<iter_reference_t<R>>>(*r)\n\t\t\t)\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __iter_move::fn iter_move{};\n\t}\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// iter_rvalue_reference_t [Extension]\n\t// From the proxy iterator work (P0022).\n\t//\n\ttemplate<__dereferenceable R>\n\tusing iter_rvalue_reference_t =\n\t\tdecltype(iter_move(std::declval<R&>()));\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// readable_traits [readable.traits]\n\t//\n\tnamespace detail {\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT MemberValueType =\n\t\t\trequires { typename T::value_type; };\n\t}\n\n\ttemplate<class T> struct __cond_value_type {};\n\ttemplate<class T>\n\trequires std::is_object_v<T>\n\tstruct __cond_value_type<T> {\n\t\tusing value_type = std::remove_cv_t<T>;\n\t};\n\n\ttemplate<class> struct readable_traits {};\n\n\ttemplate<class T>\n\tstruct readable_traits<T*> : __cond_value_type<T> {};\n\n\ttemplate<class I>\n\trequires std::is_array_v<I>\n\tstruct readable_traits<I> {\n\t\tusing value_type = std::remove_cv_t<std::remove_extent_t<I>>;\n\t};\n\n\ttemplate<class I>\n\tstruct readable_traits<I const> : readable_traits<I> {};\n\n\ttemplate<class I>\n\trequires requires { typename I::value_type; }\n\tstruct readable_traits<I> : __cond_value_type<typename I::value_type> {};\n\n\ttemplate<class I>\n\trequires requires { typename I::element_type; }\n\tstruct readable_traits<I> : __cond_value_type<typename I::element_type> {};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// iter_value_t [readable.iterators]\n\t//\n\ttemplate<class I>\n\tusing iter_value_t = typename readable_traits<I>::value_type;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// readable [readable.iterators]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT readable =\n\t\trequires {\n\t\t\t// Associated types\n\t\t\ttypename iter_value_t<I>;\n\t\t\ttypename iter_reference_t<I>;\n\t\t\ttypename iter_rvalue_reference_t<I>;\n\t\t} &&\n\t\t// Relationships between associated types\n\t\tcommon_reference_with<iter_reference_t<I>&&, iter_value_t<I>&> &&\n\t\tcommon_reference_with<iter_reference_t<I>&&, iter_rvalue_reference_t<I>&&> &&\n\t\tcommon_reference_with<iter_rvalue_reference_t<I>&&, const iter_value_t<I>&>;\n\n\t// A generally useful dependent type\n\ttemplate<readable I>\n\tusing iter_common_reference_t =\n\t\tcommon_reference_t<iter_reference_t<I>, iter_value_t<I>&>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// writable [iterators.writable]\n\t//\n\ttemplate<class Out, class R>\n\tMETA_CONCEPT writable =\n\t\t__dereferenceable<Out> &&\n\t\trequires(Out&& o, R&& r) {\n\t\t\t*o = static_cast<R&&>(r);\n\t\t\t*static_cast<Out&&>(o) = static_cast<R&&>(r);\n\t\t\tconst_cast<const iter_reference_t<Out>&&>(*o) = static_cast<R&&>(r);\n\t\t\tconst_cast<const iter_reference_t<Out>&&>(*static_cast<Out&&>(o)) = static_cast<R&&>(r);\n\t\t};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// indirectly_movable [alg.req.ind.move]\n\t//\n\ttemplate<class In, class Out>\n\tMETA_CONCEPT indirectly_movable =\n\t\treadable<In> && writable<Out, iter_rvalue_reference_t<In>>;\n\n\ttemplate<class In, class Out>\n\tconstexpr bool is_nothrow_indirectly_movable_v = false;\n\n\ttemplate<class Out, indirectly_movable<Out> In>\n\tconstexpr bool is_nothrow_indirectly_movable_v<In, Out> =\n\t\tnoexcept(noexcept(std::declval<iter_reference_t<Out>>()\n\t\t\t= iter_move(std::declval<In>())));\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// indirectly_movable_storable [alg.req.ind.move]\n\t//\n\ttemplate<class In, class Out>\n\tMETA_CONCEPT indirectly_movable_storable =\n\t\tindirectly_movable<In, Out> &&\n\t\twritable<Out, iter_value_t<In>&&> &&\n\t\tmovable<iter_value_t<In>> &&\n\t\tconstructible_from<iter_value_t<In>, iter_rvalue_reference_t<In>> &&\n\t\tassignable_from<iter_value_t<In>&, iter_rvalue_reference_t<In>>;\n\n\ttemplate<class In, class Out>\n\tconstexpr bool is_nothrow_indirectly_movable_storable_v = false;\n\n\ttemplate<class Out, indirectly_movable_storable<Out> In>\n\tconstexpr bool is_nothrow_indirectly_movable_storable_v<In, Out> =\n\t\tis_nothrow_indirectly_movable_v<In, Out> &&\n\t\tstd::is_nothrow_assignable<iter_reference_t<Out>, iter_value_t<In>>::value &&\n\t\tstd::is_nothrow_constructible<iter_value_t<In>, iter_rvalue_reference_t<In>>::value &&\n\t\tstd::is_nothrow_assignable<iter_value_t<In>&, iter_rvalue_reference_t<In>>::value;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// indirectly_copyable [alg.req.ind.copy]\n\t//\n\ttemplate<class In, class Out>\n\tMETA_CONCEPT indirectly_copyable =\n\t\treadable<In> && writable<Out, iter_reference_t<In>>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// indirectly_copyable_storable [alg.req.ind.copy]\n\t//\n\ttemplate<class In, class Out>\n\tMETA_CONCEPT indirectly_copyable_storable =\n\t\tindirectly_copyable<In, Out> &&\n\t\twritable<Out, const iter_value_t<In>&> &&\n\t\tcopyable<iter_value_t<In>> &&\n\t\tconstructible_from<iter_value_t<In>, iter_reference_t<In>> &&\n\t\tassignable_from<iter_value_t<In>&, iter_reference_t<In>>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// iter_swap\n\t//\n\tnamespace __iter_swap {\n\t\t// Poison pill for iter_swap. (See the detailed discussion at\n\t\t// https://github.com/ericniebler/stl2/issues/139)\n\t\ttemplate<class T, class U>\n\t\tvoid iter_swap(T, U) = delete;\n\n\t\ttemplate<class R1, class R2>\n\t\tMETA_CONCEPT has_customization = requires(R1&& r1, R2&& r2) {\n\t\t\titer_swap(static_cast<R1&&>(r1), static_cast<R2&&>(r2));\n\t\t};\n\n\t\ttemplate<class R1, class R2>\n\t\trequires swappable_with<iter_reference_t<R1>, iter_reference_t<R2>>\n\t\tconstexpr void impl(R1&& r1, R2&& r2)\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t__stl2::swap(*r1, *r2)\n\t\t)\n\n\t\ttemplate<class R1, class R2>\n\t\trequires (!swappable_with<iter_reference_t<R1>, iter_reference_t<R2>> &&\n\t\t\tindirectly_movable_storable<R1, R2> &&\n\t\t\tindirectly_movable_storable<R2, R1>)\n\t\tconstexpr void impl(R1& r1, R2& r2)\n\t\t\tnoexcept(\n\t\t\t\tis_nothrow_indirectly_movable_storable_v<R1, R2> &&\n\t\t\t\tis_nothrow_indirectly_movable_storable_v<R2, R1>)\n\t\t{\n\t\t\titer_value_t<R1> tmp = iter_move(r1);\n\t\t\t*r1 = iter_move(r2);\n\t\t\t*r2 = std::move(tmp);\n\t\t}\n\n\t\tstruct fn {\n\t\t\ttemplate<class R1, class R2>\n\t\t\trequires has_customization<R1, R2>\n\t\t\tconstexpr void operator()(R1&& r1, R2&& r2) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tstatic_cast<void>(iter_swap((R1&&)r1, (R2&&)r2))\n\t\t\t)\n\n\t\t\ttemplate<class R1, class R2>\n\t\t\trequires\n\t\t\t\treadable<std::remove_reference_t<R1>> &&\n\t\t\t\treadable<std::remove_reference_t<R2>> &&\n\t\t\t\t(!has_customization<R1&, R2&>) &&\n\t\t\t\trequires(R1& r1, R2& r2) {\n\t\t\t\t\t__iter_swap::impl(r1, r2);\n\t\t\t\t}\n\t\t\tconstexpr void operator()(R1&& r1, R2&& r2) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t__iter_swap::impl(r1, r2)\n\t\t\t)\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __iter_swap::fn iter_swap{};\n\t}\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// indirectly_swappable [commonalgoreq.indirectlyswappable]\n\t//\n\ttemplate<class I1, class I2 = I1>\n\tMETA_CONCEPT indirectly_swappable =\n\t\trequires(I1&& i1, I2&& i2) {\n\t\t\titer_swap((I1&&)i1, (I2&&)i2);\n\t\t\titer_swap((I2&&)i2, (I1&&)i1);\n\t\t\titer_swap((I1&&)i1, (I1&&)i1);\n\t\t\titer_swap((I2&&)i2, (I2&&)i2);\n\t\t};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// Iterator tags [std.iterator.tags]\n\t// Extension: contiguous_iterator_tag for denoting contiguous iterators.\n\t//\n\tstruct output_iterator_tag {};\n\tstruct input_iterator_tag {};\n\tstruct forward_iterator_tag : input_iterator_tag {};\n\tstruct bidirectional_iterator_tag : forward_iterator_tag {};\n\tstruct random_access_iterator_tag : bidirectional_iterator_tag {};\n\tstruct contiguous_iterator_tag : random_access_iterator_tag {};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// iterator_category and iterator_category_t [iterator.assoc]\n\t// Extension: Category for pointers is contiguous_iterator_tag,\n\t//     which derives from random_access_iterator_tag.\n\t//\n\tnamespace detail {\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT MemberIteratorCategory =\n\t\t\trequires { typename T::iterator_category; };\n\n\t\tnamespace std_to_stl2_iterator_category_ {\n\t\t\tinput_iterator_tag f(std::input_iterator_tag*);\n\t\t\tforward_iterator_tag f(std::forward_iterator_tag*);\n\t\t\tbidirectional_iterator_tag f(std::bidirectional_iterator_tag*);\n\t\t\trandom_access_iterator_tag f(std::random_access_iterator_tag*);\n\t\t}\n\n\t\ttemplate<class T>\n\t\tusing std_to_stl2_iterator_category =\n\t\t\tdecltype(std_to_stl2_iterator_category_::f((T*)nullptr));\n\t}\n\n\ttemplate<class> struct iterator_category {};\n\n\ttemplate<class T>\n\tstruct iterator_category<T*>\n\t: std::enable_if<std::is_object<T>::value, contiguous_iterator_tag> {};\n\n\ttemplate<class T>\n\tstruct iterator_category<const T>\n\t: iterator_category<T> {};\n\n\ttemplate<detail::MemberIteratorCategory T>\n\tstruct iterator_category<T> {\n\t\tusing type = typename T::iterator_category;\n\t};\n\n\ttemplate<detail::MemberIteratorCategory T>\n\trequires derived_from<typename T::iterator_category, std::input_iterator_tag>\n\tstruct iterator_category<T> {\n\t\tusing type = detail::std_to_stl2_iterator_category<typename T::iterator_category>;\n\t};\n\n\ttemplate<detail::MemberIteratorCategory T>\n\trequires\n\t\tderived_from<typename T::iterator_category, std::output_iterator_tag> &&\n\t\t(!derived_from<typename T::iterator_category, std::input_iterator_tag>)\n\tstruct iterator_category<T> {};\n\n\ttemplate<class T>\n\tusing iterator_category_t = meta::_t<iterator_category<T>>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// input_or_output_iterator [iterators.iterator]\n\t//\n\t// Denotes an element of a range, i.e., is a position.\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT input_or_output_iterator =\n\t\t__dereferenceable<I&> && weakly_incrementable<I>;\n\t\t// Axiom?: i is non-singular iff it denotes an element\n\t\t// Axiom?: if i equals j then i and j denote equal elements\n\t\t// Axiom?: I{} is in the domain of copy/move construction/assignment\n\t\t//        (This should probably be a requirement of the object concepts,\n\t\t//         or at least semiregular.)\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// sentinel_for [sentinel.iterators]\n\t//\n\t// A relationship between an input_or_output_iterator and a semiregular (\"sentinel\")\n\t// that denote a range.\n\t//\n\ttemplate<class S, class I>\n\tMETA_CONCEPT sentinel_for =\n\t\tinput_or_output_iterator<I> &&\n\t\tsemiregular<S> &&\n\t\tWeaklyEqualityComparable<S, I>;\n\t\t// Axiom: if [i,s) denotes a range then:\n\t\t//        * i == s is well-defined\n\t\t//        * if bool(i == s) then [i,s) is empty\n\t\t//        * if bool(i != s) then:\n\t\t//          * i is dereferenceable\n\t\t//          * the element denoted by i is the first element of [i,s)\n\t\t//          * [++i,s) denotes a range\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// sized_sentinel_for [iterators.sizedsentinel]\n\t//\n\t// Refinement of sentinel_for that provides the capability to compute the\n\t// distance between a input_or_output_iterator and sentinel_for that denote a range in\n\t// constant time.\n\t//\n\ttemplate<class S, class I>\n\tconstexpr bool disable_sized_sentinel = false;\n\n\ttemplate<class S, class I>\n\tMETA_CONCEPT sized_sentinel_for =\n\t\tsentinel_for<S, I> &&\n\t\t!disable_sized_sentinel<std::remove_cv_t<S>, std::remove_cv_t<I>> &&\n\t\trequires(const I i, const S s) {\n#ifdef META_HAS_P1084\n\t\t\t{ s - i } -> same_as<iter_difference_t<I>>;\n\t\t\t{ i - s } -> same_as<iter_difference_t<I>>;\n#else\n\t\t\ts - i; requires same_as<decltype((s - i)), iter_difference_t<I>>;\n\t\t\ti - s; requires same_as<decltype((i - s)), iter_difference_t<I>>;\n#endif // META_HAS_P1084\n\t\t\t// Axiom: If [i,s) denotes a range and N is the smallest\n\t\t\t//        non-negative integer such that N applications of\n\t\t\t//        ++i make bool(i == s) == true\n\t\t\t//        * if N is representable by iter_difference_t<I> then\n\t\t\t//          s - i is well-defined and equal to N\n\t\t\t//        * if -N is representable by iter_difference_t<I> then\n\t\t\t//          i - s is well-defined and equal to -N\n\t\t};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// output_iterator [iterators.output]\n\t//\n\ttemplate<class I, class T>\n\tMETA_CONCEPT output_iterator =\n\t\tinput_or_output_iterator<I> &&\n\t\twritable<I, T> &&\n\t\trequires(I& i, T&& t) {\n\t\t\t*i++ = std::forward<T>(t);\n\t\t};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// input_iterator [iterators.input]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT input_iterator =\n\t\tinput_or_output_iterator<I> &&\n\t\treadable<I> &&\n\t\trequires(I& i, const I& ci) {\n\t\t\ttypename iterator_category_t<I>;\n\t\t\tderived_from<iterator_category_t<I>, input_iterator_tag>;\n\t\t\ti++;\n\t\t};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// Exposition-only has-arrow [range.utility.helpers]\n\ttemplate<class I>\n\tMETA_CONCEPT __has_arrow = input_iterator<I> &&\n\t\t(std::is_pointer_v<I> || requires(I i) { i.operator->(); });\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// forward_iterator [iterators.forward]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT forward_iterator =\n\t\tinput_iterator<I> &&\n\t\tderived_from<iterator_category_t<I>, forward_iterator_tag> &&\n\t\tincrementable<I> &&\n\t\tsentinel_for<I, I>;\n\t\t// Axiom: I{} is equality-preserving and non-singular\n\t\t// Axiom: if i equals j then i and j denote the same element.\n\t\t// Axiom: if [i,s) denotes a range && bool(i != s) then [i,i+1) denotes\n\t\t//        a range and i == j has the same definition space as\n\t\t//        i+1 == j\n\t\t//        Note: intent is to require == et al to be well-defined over\n\t\t//        all iterator values that participate in a range.\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// bidirectional_iterator [iterators.bidirectional]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT bidirectional_iterator =\n\t\tforward_iterator<I> &&\n\t\tderived_from<iterator_category_t<I>, bidirectional_iterator_tag> &&\n\t\text::Decrementable<I>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// random_access_iterator [iterators.random.access]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT random_access_iterator =\n\t\tbidirectional_iterator<I> &&\n\t\tderived_from<iterator_category_t<I>, random_access_iterator_tag> &&\n\t\tsized_sentinel_for<I, I> &&\n\t\t// Should ordering be in sized_sentinel_for and/or RandomAccessIncrementable?\n\t\ttotally_ordered<I> &&\n\t\text::RandomAccessIncrementable<I> &&\n\t\trequires(const I& ci, const iter_difference_t<I> n) {\n#ifdef META_HAS_P1084\n\t\t\t{ ci[n] } -> same_as<iter_reference_t<I>>;\n#else\n\t\t\tci[n];\n\t\t\trequires same_as<decltype(ci[n]), iter_reference_t<I>>;\n#endif\n\t\t};\n\t\t// FIXME: Axioms for definition space of ordering operations. Don't\n\t\t// require them to be the same space as ==, since pointers can't meet\n\t\t// that requirement. Formulation should be similar to that for == in\n\t\t// forward_iterator, e.g., \"if [i,j) denotes a range, i < j et al are\n\t\t// well-defined.\"\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// contiguous_iterator\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT contiguous_iterator =\n\t\trandom_access_iterator<I> &&\n\t\tderived_from<iterator_category_t<I>, contiguous_iterator_tag> &&\n\t\tstd::is_lvalue_reference<iter_reference_t<I>>::value &&\n\t\tsame_as<iter_value_t<I>, __uncvref<iter_reference_t<I>>>;\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// iterator_traits [iterator.assoc]\n\t//\n\ttemplate<input_iterator I>\n\tstruct __pointer_type {\n\t\tusing type = std::add_pointer_t<iter_reference_t<I>>;\n\t};\n\n\ttemplate<input_iterator I>\n\trequires\n\t\trequires(I i) {\n#ifdef META_HAS_P1084\n\t\t\t{ i.operator->() } -> __can_reference;\n#else\n\t\t\ti.operator->(); requires __can_reference<decltype(i.operator->())>;\n#endif\n\t\t}\n\tstruct __pointer_type<I> {\n\t\tusing type = decltype(std::declval<I&>().operator->());\n\t};\n\n\ttemplate<class>\n\tstruct __iterator_traits {};\n\n\ttemplate<input_or_output_iterator I>\n\tstruct __iterator_traits<I> {\n\t\tusing difference_type = iter_difference_t<I>;\n\t\tusing value_type = void;\n\t\tusing reference = void;\n\t\tusing pointer = void;\n\t\tusing iterator_category = output_iterator_tag;\n\t};\n\n\ttemplate<input_iterator I>\n\tstruct __iterator_traits<I> {\n\t\tusing difference_type = iter_difference_t<I>;\n\t\tusing value_type = iter_value_t<I>;\n\t\tusing reference = iter_reference_t<I>;\n\t\tusing pointer = meta::_t<__pointer_type<I>>;\n\t\tusing iterator_category = iterator_category_t<I>;\n\t};\n\n\ttemplate<class I>\n\tusing iterator_traits = __iterator_traits<I>;\n\n#if STL2_HOOK_ITERATOR_TRAITS\n\t////////////////////////////////////////////////////////////////////////////\n\t// Standard iterator traits [iterator.stdtraits]\n\t//\n\tnamespace detail {\n\t\tnamespace stl2_to_std_iterator_category_ {\n\t\t\ttemplate<class Ref, class Cat> Cat g(std::input_iterator_tag*, Cat*);\n\t\t\ttemplate<class Ref, class Cat> Cat g(std::output_iterator_tag*, Cat*);\n\t\t\ttemplate<class Ref, class Cat> std::input_iterator_tag g(void*, Cat*, Ref* = 0);\n\t\t\ttemplate<class Ref> std::input_iterator_tag g(const void*, input_iterator_tag*);\n\t\t\ttemplate<class Ref> std::forward_iterator_tag g(const void*, forward_iterator_tag*);\n\t\t\ttemplate<class Ref> std::bidirectional_iterator_tag g(const void*, bidirectional_iterator_tag*);\n\t\t\ttemplate<class Ref> std::random_access_iterator_tag g(const void*, random_access_iterator_tag*);\n\t\t}\n\n\t\ttemplate<class Cat, class Ref>\n\t\tusing stl2_to_std_iterator_category =\n\t\t\tdecltype(stl2_to_std_iterator_category_::g<Ref>((Cat*)0, (Cat*)0));\n\n\t\ttemplate<class T, class U = void>\n\t\tstruct value_type_with_a_default : meta::id<U> {};\n\t\ttemplate<class T, class U>\n\t\t\trequires requires { typename T::value_type; }\n\t\tstruct value_type_with_a_default<T, U> : meta::id<typename T::value_type> {};\n\n\t\ttemplate<class T, class U = void>\n\t\tstruct reference_with_a_default : meta::id<U> {};\n\t\ttemplate<class T, class U>\n\t\t\trequires requires { typename T::reference; }\n\t\tstruct reference_with_a_default<T, U> : meta::id<typename T::reference> {};\n\n\t\ttemplate<class T, class U = void>\n\t\tstruct pointer_with_a_default : meta::id<U> {};\n\t\ttemplate<class T, class U>\n\t\t\trequires requires { typename T::pointer; }\n\t\tstruct pointer_with_a_default<T, U> : meta::id<typename T::pointer> {};\n\n\t\ttemplate<class I>\n\t\tMETA_CONCEPT LooksLikeSTL1Iterator =\n\t\t\trequires {\n\t\t\t\ttypename I::iterator_category;\n\t\t\t\trequires derived_from<typename I::iterator_category, std::input_iterator_tag> ||\n\t\t\t\t\t\t derived_from<typename I::iterator_category, std::output_iterator_tag>;\n\t\t\t};\n\t\ttemplate<class I>\n\t\tMETA_CONCEPT ProbablySTL2Iterator = !LooksLikeSTL1Iterator<I> && input_or_output_iterator<I>;\n\t} // namespace detail\n#endif // STL2_HOOK_ITERATOR_TRAITS\n} STL2_CLOSE_NAMESPACE\n\n#if STL2_HOOK_ITERATOR_TRAITS\nnamespace std {\n\ttemplate<::__stl2::detail::ProbablySTL2Iterator Out>\n\t\t// HACKHACK to avoid partial specialization after instantiation errors. Platform\n\t\t// vendors can avoid this hack by fixing up stdlib headers to fwd declare these\n\t\t// partial specializations in the same place that std::iterator_traits is first\n\t\t// defined.\n\tstruct iterator_traits<Out> {\n\t\tusing difference_type   = ::__stl2::iter_difference_t<Out>;\n\t\tusing value_type        = meta::_t<::__stl2::detail::value_type_with_a_default<Out>>;\n\t\tusing reference         = meta::_t<::__stl2::detail::reference_with_a_default<Out>>;\n\t\tusing pointer           = meta::_t<::__stl2::detail::pointer_with_a_default<Out>>;\n\t\tusing iterator_category = std::output_iterator_tag;\n\t};\n\n\ttemplate<::__stl2::detail::ProbablySTL2Iterator In>\n\trequires ::__stl2::input_iterator<In>\n\tstruct iterator_traits<In> { };\n\n\ttemplate<::__stl2::detail::ProbablySTL2Iterator In>\n\trequires ::__stl2::input_iterator<In> && ::__stl2::sentinel_for<In, In>\n\tstruct iterator_traits<In> {\n\t\tusing difference_type   = ::__stl2::iter_difference_t<In>;\n\t\tusing value_type        = ::__stl2::iter_value_t<In>;\n\t\tusing reference         =\n\t\t\tmeta::_t<::__stl2::detail::reference_with_a_default<\n\t\t\t\t\tIn, ::__stl2::iter_reference_t<In>>>;\n\t\tusing pointer           =\n\t\t\tmeta::_t<::__stl2::detail::pointer_with_a_default<In,\n\t\t\t\t\ttypename ::__stl2::iterator_traits<In>::pointer>>;\n\t\tusing iterator_category =\n\t\t\t::__stl2::detail::stl2_to_std_iterator_category<\n\t\t\t\t\t::__stl2::iterator_category_t<In>,\n\t\t\t\t\t::__stl2::iter_reference_t<In>>;\n\t};\n} // namespace std\n#endif // STL2_HOOK_ITERATOR_TRAITS\n\n#ifdef __GLIBCXX__ // HACKHACK: pointer iterator wrappers are contiguous\n#include <bits/stl_iterator.h>\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class T, class C>\n\tstruct iterator_category<::__gnu_cxx::__normal_iterator<T, C>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n} STL2_CLOSE_NAMESPACE\n#elif defined(_MSVC_STL_VERSION)\nnamespace std {\n\ttemplate<class, size_t> class _Array_iterator;\n\ttemplate<class, size_t> class _Array_const_iterator;\n\ttemplate<class, size_t> class _Span_iterator;       // My crystal ball tells me we'll pick\n\ttemplate<class, size_t> class _Span_const_iterator; // these names when we implement span.\n\ttemplate<class> class _String_iterator;\n\ttemplate<class> class _String_const_iterator;\n\ttemplate<class> class _String_view_iterator;\n\ttemplate<class> class _Vector_iterator;\n\ttemplate<class> class _Vector_const_iterator;\n}\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class T, size_t N>\n\tstruct iterator_category<::std::_Array_iterator<T, N>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T, size_t N>\n\tstruct iterator_category<::std::_Array_const_iterator<T, N>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T, size_t N>\n\tstruct iterator_category<::std::_Span_iterator<T, N>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T, size_t N>\n\tstruct iterator_category<::std::_Span_const_iterator<T, N>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T>\n\tstruct iterator_category<::std::_String_iterator<T>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T>\n\tstruct iterator_category<::std::_String_const_iterator<T>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T>\n\tstruct iterator_category<::std::_String_view_iterator<T>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T>\n\tstruct iterator_category<::std::_Vector_iterator<T>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n\ttemplate<class T>\n\tstruct iterator_category<::std::_Vector_const_iterator<T>> {\n\t\tusing type = __stl2::contiguous_iterator_tag;\n\t};\n} STL2_CLOSE_NAMESPACE\n#endif\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/counted_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_COUNTED_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_COUNTED_ITERATOR_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n#include <stl2/detail/iterator/operations.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<input_or_output_iterator> class counted_iterator;\n\n\tnamespace __counted_iterator {\n\t\tstruct access {\n\t\t\ttemplate<_SpecializationOf<counted_iterator> CI>\n\t\t\tstatic constexpr auto&& current(CI&& ci) noexcept {\n\t\t\t\treturn std::forward<CI>(ci).current_;\n\t\t\t}\n\t\t\ttemplate<_SpecializationOf<counted_iterator> CI>\n\t\t\tstatic constexpr auto&& count(CI&& ci) noexcept {\n\t\t\t\treturn std::forward<CI>(ci).length_;\n\t\t\t}\n\t\t};\n\n#if STL2_WORKAROUND_CLANG_37556\n\t\ttemplate<class I>\n\t\tconstexpr iter_rvalue_reference_t<I>\n\t\titer_move(const counted_iterator<I>& i)\n\t\t\tnoexcept(noexcept(__stl2::iter_move(access::current(i))))\n\t\t\trequires input_iterator<I> {\n\t\t\treturn __stl2::iter_move(access::current(i));\n\t\t}\n\t\ttemplate<class I, indirectly_swappable<I> I2>\n\t\tconstexpr void iter_swap(\n\t\t\tconst counted_iterator<I>& x, const counted_iterator<I2>& y)\n\t\t\tnoexcept(noexcept(__stl2::iter_swap(\n\t\t\t\tstd::declval<const I&>(),\n\t\t\t\tstd::declval<const I2&>()))) {\n\t\t\t__stl2::iter_swap(access::current(x), access::current(y));\n\t\t}\n#endif // STL2_WORKAROUND_CLANG_37556\n\t}\n\n\t// counted_iterator [counted.iterator]\n\ttemplate<input_or_output_iterator I>\n\tclass counted_iterator\n#if STL2_WORKAROUND_CLANG_37556\n\t: __counted_iterator::access\n#endif // STL2_WORKAROUND_CLANG_37556\n\t{\n\t\tfriend __counted_iterator::access;\n\n\t\tI current_;\n\t\titer_difference_t<I> length_;\n\n\tpublic:\n\t\tusing iterator_type = I;\n\n\t\tconstexpr counted_iterator() = default;\n\t\tconstexpr counted_iterator(I x, iter_difference_t<I> n)\n\t\tnoexcept(std::is_nothrow_move_constructible_v<I>) // strengthened\n\t\t: current_(std::move(x)), length_{n} {\n\t\t\tSTL2_EXPECT(n >= 0);\n\t\t}\n\t\ttemplate<class I2>\n\t\trequires convertible_to<const I2&, I>\n\t\tconstexpr counted_iterator(const counted_iterator<I2>& i)\n\t\tnoexcept(std::is_nothrow_copy_constructible_v<I>) // strengthened\n\t\t: current_(__counted_iterator::access::current(i))\n\t\t, length_{__counted_iterator::access::count(i)} {}\n\t\ttemplate<class I2>\n\t\trequires assignable_from<I&, const I2&>\n\t\tconstexpr counted_iterator& operator=(const counted_iterator<I2>& i)\n\t\tnoexcept(std::is_nothrow_assignable_v<I&, const I2&>) { // strengthened\n\t\t\tcurrent_ = __counted_iterator::access::current(i);\n\t\t\tlength_ = __counted_iterator::access::count(i);\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr I base() const\n\t\tnoexcept(std::is_nothrow_copy_constructible_v<I>) { // strengthened\n\t\t\treturn current_;\n\t\t}\n\t\tconstexpr iter_difference_t<I> count() const noexcept {\n\t\t\treturn length_;\n\t\t}\n\t\tconstexpr decltype(auto) operator*()\n\t\tnoexcept(noexcept(*std::declval<I&>())) { // strengthened\n\t\t\treturn *current_;\n\t\t}\n\t\tconstexpr decltype(auto) operator*() const\n\t\tnoexcept(noexcept(*std::declval<const I&>())) // strengthened\n\t\trequires __dereferenceable<const I> {\n\t\t\treturn *current_;\n\t\t}\n\t\tconstexpr counted_iterator& operator++() {\n\t\t\tSTL2_EXPECT(length_ > 0);\n\t\t\t++current_;\n\t\t\t--length_;\n\t\t\treturn *this;\n\t\t}\n\t\t/* STL2_CXX20_CONSTEXPR */ decltype(auto) operator++(int) {\n\t\t\tSTL2_EXPECT(length_ > 0);\n\t\t\t--length_;\n\t\t\ttry {\n\t\t\t\treturn current_++;\n\t\t\t} catch(...) {\n\t\t\t\t++length_;\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\t\tconstexpr counted_iterator operator++(int) requires forward_iterator<I> {\n\t\t\tauto tmp = *this;\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\t\tconstexpr counted_iterator& operator--()\n\t\trequires bidirectional_iterator<I> {\n\t\t\t--current_;\n\t\t\t++length_;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr counted_iterator operator--(int)\n\t\trequires bidirectional_iterator<I> {\n\t\t\tauto tmp = *this;\n\t\t\t--*this;\n\t\t\treturn tmp;\n\t\t}\n\t\tconstexpr counted_iterator operator+(iter_difference_t<I> n) const\n\t\trequires random_access_iterator<I> {\n\t\t\tSTL2_EXPECT(n <= length_);\n\t\t\treturn counted_iterator(current_ + n, length_ - n);\n\t\t}\n\t\tfriend constexpr counted_iterator\n\t\toperator+(iter_difference_t<I> n, const counted_iterator& x)\n\t\trequires random_access_iterator<I> {\n\t\t\treturn x + n;\n\t\t}\n\t\tconstexpr counted_iterator& operator+=(iter_difference_t<I> n)\n\t\trequires random_access_iterator<I> {\n\t\t\tSTL2_EXPECT(n <= length_);\n\t\t\tcurrent_ += n;\n\t\t\tlength_ -= n;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr counted_iterator operator-(iter_difference_t<I> n) const\n\t\trequires random_access_iterator<I> {\n\t\t\tSTL2_EXPECT(-n <= length_);\n\t\t\treturn counted_iterator(current_ - n, length_ + n);\n\t\t}\n\t\ttemplate<common_with<I> I2>\n\t\tfriend constexpr iter_difference_t<I2>\n\t\toperator-(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn y.count() - x.length_;\n\t\t}\n\t\tfriend constexpr iter_difference_t<I>\n\t\toperator-(const counted_iterator& x, default_sentinel_t)\n\t\tnoexcept { // strengthened\n\t\t\treturn -x.length_;\n\t\t}\n\t\tfriend constexpr iter_difference_t<I>\n\t\toperator-(default_sentinel_t, const counted_iterator& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn y.length_;\n\t\t}\n\t\tconstexpr counted_iterator& operator-=(iter_difference_t<I> n)\n\t\trequires random_access_iterator<I> {\n\t\t\tSTL2_EXPECT(-n <= length_);\n\t\t\tcurrent_ -= n;\n\t\t\tlength_ += n;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr decltype(auto) operator[](iter_difference_t<I> n) const\n\t\tnoexcept(noexcept(std::declval<const I&>()[n])) // strengthened\n\t\trequires random_access_iterator<I> {\n\t\t\tSTL2_EXPECT(n <= length_);\n\t\t\treturn current_[n];\n\t\t}\n\n\t\ttemplate<common_with<I> I2>\n\t\tfriend constexpr bool\n\t\toperator==(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn x.length_ == y.count();\n\t\t}\n\t\tfriend constexpr bool\n\t\toperator==(const counted_iterator& x, default_sentinel_t)\n\t\tnoexcept { // strengthened\n\t\t\treturn x.length_ == 0;\n\t\t}\n\t\tfriend constexpr bool\n\t\toperator==(default_sentinel_t, const counted_iterator& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn y.length_ == 0;\n\t\t}\n\t\ttemplate<common_with<I> I2>\n\t\tfriend constexpr bool\n\t\toperator!=(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\t noexcept { // strengthened\n\t\t\treturn !(x == y);\n\t\t}\n\t\tfriend constexpr bool\n\t\toperator!=(const counted_iterator& x, default_sentinel_t y)\n\t\t noexcept { // strengthened\n\t\t\treturn !(x == y);\n\t\t}\n\t\tfriend constexpr bool\n\t\toperator!=(default_sentinel_t x, const counted_iterator& y)\n\t\t noexcept { // strengthened\n\t\t\treturn !(x == y);\n\t\t}\n\n\t\ttemplate<common_with<I> I2>\n\t\tfriend constexpr bool\n\t\toperator<(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn y.count() < x.length_;\n\t\t}\n\t\ttemplate<common_with<I> I2>\n\t\tfriend constexpr bool\n\t\toperator>(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn y < x;\n\t\t}\n\t\ttemplate<common_with<I> I2>\n\t\tfriend constexpr bool\n\t\toperator<=(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn !(y < x);\n\t\t}\n\t\ttemplate<common_with<I> I2>\n\t\tfriend constexpr bool\n\t\toperator>=(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\tnoexcept { // strengthened\n\t\t\treturn !(x < y);\n\t\t}\n\n#if !STL2_WORKAROUND_CLANG_37556\n\t\tfriend constexpr iter_rvalue_reference_t<I>\n\t\titer_move(const counted_iterator& i)\n\t\tnoexcept(noexcept(__stl2::iter_move(i.current_)))\n\t\trequires input_iterator<I> {\n\t\t\treturn __stl2::iter_move(i.current_);\n\t\t}\n\t\ttemplate<indirectly_swappable<I> I2>\n\t\tfriend constexpr void\n\t\titer_swap(const counted_iterator& x, const counted_iterator<I2>& y)\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t__stl2::iter_swap(x.current_,\n\t\t\t\t__counted_iterator::access::current(y))\n\t\t)\n#endif // !STL2_WORKAROUND_CLANG_37556\n\t};\n\n\ttemplate<class I>\n\tstruct incrementable_traits<counted_iterator<I>> {\n\t\tusing difference_type = iter_difference_t<I>;\n\t};\n\n\ttemplate<readable I>\n\tstruct readable_traits<counted_iterator<I>> {\n\t\tusing value_type = iter_value_t<I>;\n\t};\n\ttemplate<input_iterator I>\n\tstruct iterator_category<counted_iterator<I>> {\n\t\tusing type = iterator_category_t<I>;\n\t};\n\n\ttemplate<input_or_output_iterator I>\n\tconstexpr void __advance_fn::operator()(\n\t\tcounted_iterator<I>& i, iter_difference_t<I> n) const\n\t{\n\t\tif constexpr (random_access_iterator<I>) {\n\t\t\ti += n;\n\t\t} else {\n\t\t\tauto& length = __counted_iterator::access::count(i);\n\t\t\tSTL2_EXPECT(n <= length);\n\t\t\t(*this)(__counted_iterator::access::current(i), n);\n\t\t\tlength -= n;\n\t\t}\n\t}\n\n\tnamespace ext {\n\t\ttemplate<input_or_output_iterator I>\n\t\tconstexpr auto uncounted(const I& i)\n\t\tnoexcept(std::is_nothrow_copy_constructible<I>::value) {\n\t\t\treturn i;\n\t\t}\n\n\t\ttemplate<class I>\n\t\tconstexpr auto uncounted(const counted_iterator<I>& i)\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\ti.base()\n\t\t)\n\n\t\ttemplate<input_or_output_iterator I>\n\t\tconstexpr auto recounted(const I&, const I& i, iter_difference_t<I> = 0)\n\t\tnoexcept(std::is_nothrow_copy_constructible<I>::value)\n\t\t{\n\t\t\treturn i;\n\t\t}\n\n\t\ttemplate<class I>\n\t\tconstexpr auto recounted(const counted_iterator<I>& o, I i)\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\tcounted_iterator<I>{std::move(i), o.count()}\n\t\t)\n\n\t\ttemplate<class I>\n\t\tconstexpr auto recounted(\n\t\t\tconst counted_iterator<I>& o, I i, iter_difference_t<I> n)\n\t\tnoexcept(noexcept(counted_iterator<I>{std::move(i), o.count() - n}))\n\t\t{\n\t\t\tSTL2_EXPENSIVE_ASSERT(!forward_iterator<I> ||\n\t\t\t\ti == next(o.base(), n));\n\t\t\treturn counted_iterator<I>{std::move(i), o.count() - n};\n\t\t}\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/default_sentinel.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_DEFAULT_SENTINEL_HPP\n#define STL2_DETAIL_ITERATOR_DEFAULT_SENTINEL_HPP\n\n#include <stl2/detail/fwd.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tstruct default_sentinel_t {};\n\n\tinline constexpr default_sentinel_t default_sentinel{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/increment.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2016\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_INCREMENT_HPP\n#define STL2_DETAIL_ITERATOR_INCREMENT_HPP\n\n#include <cstddef>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/fundamental.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t////////////////////////////////////////////////////////////////////////////\n\t// incrementable_traits [incrementable.traits]\n\t// Not to spec:\n\t// * Workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78173; it is\n\t//   necessary to guard the requires clause of the \"fallback\" specialization\n\t//   to prevent hard errors for pointers to incomplete types.\n\t//\n\ttemplate<class> struct incrementable_traits {};\n\n\ttemplate<class T>\n\trequires std::is_object_v<T>\n\tstruct incrementable_traits<T*> {\n\t\tusing difference_type = std::ptrdiff_t;\n\t};\n\n\ttemplate<class I>\n\tstruct incrementable_traits<const I> : incrementable_traits<I> {};\n\n\ttemplate<class T>\n\trequires requires { typename T::difference_type; }\n\tstruct incrementable_traits<T> {\n\t\tusing difference_type = typename T::difference_type;\n\t};\n\n\ttemplate<class T>\n\trequires (!requires { typename T::difference_type; } &&\n\t\t!std::is_pointer_v<T> && // Avoid GCC PR 78173 (See above)\n\t\trequires(const T& a, const T& b) {\n#ifdef META_HAS_P1084\n\t\t\t{ a - b } -> integral;\n#else\n\t\t\ta - b; requires integral<decltype(a - b)>;\n#endif\n\t\t})\n\tstruct incrementable_traits<T> {\n\t\tusing difference_type = std::make_signed_t<\n\t\t\tdecltype(std::declval<T>() - std::declval<T>())>;\n\t};\n\n\ttemplate<class T>\n\tusing iter_difference_t = typename incrementable_traits<T>::difference_type;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// weakly_incrementable [weaklyincrementable.iterators]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT weakly_incrementable =\n\t\tsemiregular<I> &&\n\t\trequires(I i) {\n\t\t\ttypename iter_difference_t<I>;\n\t\t\trequires signed_integral<iter_difference_t<I>>;\n#ifdef META_HAS_P1084\n\t\t\t{ ++i } -> same_as<I&>; // not required to be equality-preserving\n#else\n\t\t\t++i; requires same_as<decltype((++i)), I&>; // not required to be equality-preserving\n#endif // META_HAS_P1084\n\t\t\ti++; // not required to be equality-preserving\n\t\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// incrementable [incrementable.iterators]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT incrementable =\n\t\tregular<I> &&\n\t\tweakly_incrementable<I> &&\n\t\trequires(I i) {\n#ifdef META_HAS_P1084\n\t\t\t{ i++ } -> same_as<I>;\n#else\n\t\t\ti++; requires same_as<decltype(i++), I>;\n#endif\n\t\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// Decrementable [Extension]\n\t//\n\tnamespace ext {\n\t\ttemplate<class I>\n\t\tMETA_CONCEPT Decrementable =\n\t\t\tincrementable<I> &&\n\t\t\trequires(I i) {\n#ifdef META_HAS_P1084\n\t\t\t\t{ --i } -> same_as<I&>;\n\t\t\t\t{ i-- } -> same_as<I>;\n#else\n\t\t\t\t--i; requires same_as<decltype((--i)), I&>;\n\t\t\t\ti--; requires same_as<I, decltype(i--)>;\n#endif\n\t\t\t};\n\t\t\t// Let a and b be objects of type I.\n\t\t\t// Axiom: &--a == &a\n\t\t\t// Axiom: bool(a == b) implies bool(a-- == b)\n\t\t\t// Axiom: bool(a == b) implies bool((a--, a) == --b)\n\t\t\t// Axiom: bool(a == b) implies bool(--(++a) == b)\n\t\t\t// Axiom: bool(a == b) implies bool(++(--a) == b)\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// RandomAccessIncrementable [Extension]\n\t//\n\tnamespace ext {\n\t\ttemplate<class I>\n\t\tMETA_CONCEPT RandomAccessIncrementable =\n\t\t\tDecrementable<I> &&\n\t\t\trequires(I& i, const I& ci, const iter_difference_t<I> n) {\n#ifdef META_HAS_P1084\n\t\t\t\t{ i += n } -> same_as<I&>;\n\t\t\t\t{ i -= n } -> same_as<I&>;\n\t\t\t\t{ ci + n } -> same_as<I>;\n\t\t\t\t{ n + ci } -> same_as<I>;\n\t\t\t\t{ ci - n } -> same_as<I>;\n#else\n\t\t\t\ti += n; requires same_as<decltype((i += n)), I&>;\n\t\t\t\ti -= n; requires same_as<decltype((i -= n)), I&>;\n\t\t\t\tci + n; requires same_as<decltype((ci + n)), I>;\n\t\t\t\tn + ci; requires same_as<decltype((n + ci)), I>;\n\t\t\t\tci - n; requires same_as<decltype((ci - n)), I>;\n#endif // META_HAS_P1084\n\t\t\t\t{ ci - ci } -> convertible_to<iter_difference_t<I>>;\n\t\t\t};\n\t\t\t// FIXME: Axioms\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/insert_iterators.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_INSERT_ITERATORS_HPP\n#define STL2_DETAIL_ITERATOR_INSERT_ITERATORS_HPP\n\n#include <cstddef>\n#include <memory>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<MemberValueType Container>\n\t\tclass insert_cursor_base {\n\t\tpublic:\n\t\t\tusing difference_type = std::ptrdiff_t;\n\n\t\t\tconstexpr insert_cursor_base() noexcept = default;\n\n\t\t\tconstexpr explicit insert_cursor_base(Container& x) noexcept\n\t\t\t: container_{std::addressof(x)}\n\t\t\t{}\n\t\tprotected:\n\t\t\traw_ptr<Container> container_ = nullptr;\n\t\t};\n\n\t\ttemplate<class Cursor, class Container>\n\t\tstruct insert_cursor_mixin : protected ebo_box<Cursor, insert_cursor_mixin<Cursor, Container>> {\n\t\t\tusing difference_type =\n\t\t\t\ttypename insert_cursor_base<Container>::difference_type;\n\t\t\tusing container_type = Container;\n\t\t\tusing insert_cursor_mixin::ebo_box::ebo_box;\n\t\t};\n\n\t\ttemplate<class T, class C>\n\t\tMETA_CONCEPT BackInsertableInto =\n\t\t\trequires(T&& t, C& c) {\n\t\t\t\tc.push_back((T&&)t);\n\t\t\t};\n\n\t\ttemplate<MemberValueType Container>\n\t\tstruct back_insert_cursor : insert_cursor_base<Container> {\n\t\t\tusing base_t = insert_cursor_base<Container>;\n\t\t\tusing mixin = insert_cursor_mixin<back_insert_cursor, Container>;\n\n\t\t\tconstexpr back_insert_cursor() = default;\n\t\t\tusing base_t::base_t;\n\n\t\t\ttemplate<BackInsertableInto<Container> T>\n\t\t\tconstexpr void write(T&& t) {\n\t\t\t\tbase_t::container_->push_back(std::forward<T>(t));\n\t\t\t}\n\t\t};\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// back_insert_iterator [back.insert.iterator]\n\t//\n\ttemplate<detail::MemberValueType Container>\n\tusing back_insert_iterator =\n\t\tbasic_iterator<detail::back_insert_cursor<Container>>;\n\n\ttemplate<detail::MemberValueType Container>\n\tconstexpr auto back_inserter(Container& c) noexcept {\n\t\treturn back_insert_iterator<Container>{c};\n\t}\n\n\tnamespace detail {\n\t\ttemplate<class T, class C>\n\t\tMETA_CONCEPT FrontInsertableInto =\n\t\t\trequires(T&& t, C& c) {\n\t\t\t\tc.push_front((T&&)t);\n\t\t\t};\n\n\t\ttemplate<MemberValueType Container>\n\t\tstruct front_insert_cursor : insert_cursor_base<Container> {\n\t\t\tusing base_t = insert_cursor_base<Container>;\n\t\t\tusing mixin = insert_cursor_mixin<front_insert_cursor, Container>;\n\n\t\t\tconstexpr front_insert_cursor() = default;\n\t\t\tusing base_t::base_t;\n\n\t\t\ttemplate<FrontInsertableInto<Container> T>\n\t\t\tconstexpr void write(T&& t) {\n\t\t\t\tbase_t::container_->push_front(std::forward<T>(t));\n\t\t\t}\n\t\t};\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// front_insert_iterator [front.insert.iterator]\n\t//\n\ttemplate<detail::MemberValueType Container>\n\tusing front_insert_iterator =\n\t\tbasic_iterator<detail::front_insert_cursor<Container>>;\n\n\ttemplate<detail::MemberValueType Container>\n\tconstexpr auto front_inserter(Container& x) noexcept {\n\t\treturn front_insert_iterator<Container>{x};\n\t}\n\n\tnamespace detail {\n\t\ttemplate<class T, class C>\n\t\tMETA_CONCEPT InsertableInto =\n\t\t\trequires(T&& t, C& c, iterator_t<C> i) {\n\t\t\t\t{  c.insert(i, (T&&)t) } -> same_as<iterator_t<C>>;\n\t\t\t};\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// insert_iterator [insert.iterator]\n\t//\n\ttemplate<detail::MemberValueType Container>\n\trequires requires { typename iterator_t<Container>; }\n\tclass insert_iterator {\n\tpublic:\n\t\tusing container_type = Container;\n\t\tusing difference_type = std::ptrdiff_t;\n\n\t\tinsert_iterator() = default;\n\t\tconstexpr insert_iterator(Container& x, iterator_t<Container> i)\n\t\t: container(std::addressof(x)), iter(std::move(i)) {}\n\t\tconstexpr insert_iterator& operator=(const iter_value_t<Container>& value)\n\t\trequires detail::InsertableInto<const iter_value_t<Container>&, Container>\n\t\t{\n\t\t\titer = container->insert(iter, value);\n\t\t\t++iter;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr insert_iterator& operator=(iter_value_t<Container>&& value)\n\t\trequires detail::InsertableInto<iter_value_t<Container>&&, Container>\n\t\t{\n\t\t\titer = container->insert(iter, std::move(value));\n\t\t\t++iter;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr insert_iterator& operator*() {\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr insert_iterator& operator++() {\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr insert_iterator& operator++(int) {\n\t\t\treturn *this;\n\t\t}\n\tprivate:\n\t\tdetail::raw_ptr<Container> container = nullptr;\n\t\titerator_t<Container> iter = iterator_t<Container>();\n\t};\n\n\ttemplate<detail::MemberValueType Container>\n\tconstexpr auto inserter(Container& x, iterator_t<Container> i)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tinsert_iterator<Container>{x, std::move(i)}\n\t)\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/istream_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_ISTREAM_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_ISTREAM_ITERATOR_HPP\n\n#include <iosfwd>\n#include <memory>\n#include <string>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iostream/concepts.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\t///////////////////////////////////////////////////////////////////////////\n\t\t// istream_cursor [Implementation detail]\n\t\t//\n\t\ttemplate<semiregular T, class charT = char,\n\t\t\tclass traits = std::char_traits<charT>,\n\t\t\tsigned_integral Distance = std::ptrdiff_t>\n\t\trequires\n\t\t\tStreamExtractable<T, charT, traits>\n\t\tclass istream_cursor : semiregular_box<T> {\n\t\t\tusing box_t = semiregular_box<T>;\n\t\tpublic:\n\t\t\tusing difference_type = Distance;\n\t\t\tusing value_type = T;\n\t\t\tusing istream_type = std::basic_istream<charT, traits>;\n\t\t\tusing single_pass = std::true_type;\n\n\t\t\tclass mixin : protected basic_mixin<istream_cursor> {\n\t\t\t\tusing base_t = basic_mixin<istream_cursor>;\n\t\t\tpublic:\n\t\t\t\tusing iterator_category = input_iterator_tag;\n\t\t\t\tusing difference_type = istream_cursor::difference_type;\n\t\t\t\tusing value_type = istream_cursor::value_type;\n\t\t\t\tusing reference = const T&;\n\t\t\t\tusing pointer = const T*;\n\t\t\t\tusing char_type = charT;\n\t\t\t\tusing traits_type = traits;\n\t\t\t\tusing istream_type = istream_cursor::istream_type;\n\n\t\t\t\tmixin() = default;\n\t\t\t\tmixin(istream_type& s)\n\t\t\t\t: base_t{istream_cursor{s}}\n\t\t\t\t{}\n\t\t\t\tconstexpr mixin(default_sentinel_t)\n\t\t\t\t: base_t{}\n\t\t\t\t{}\n\t\t\t\tusing base_t::base_t;\n\t\t\t};\n\n\t\t\tconstexpr istream_cursor()\n\t\t\tnoexcept(std::is_nothrow_default_constructible<T>::value) = default;\n\n\t\t\tistream_cursor(istream_type& s)\n\t\t\t: stream_{std::addressof(s)}\n\t\t\t{ next(); }\n\n\t\t\tconstexpr istream_cursor(default_sentinel_t)\n\t\t\tnoexcept(std::is_nothrow_default_constructible<T>::value)\n\t\t\t: istream_cursor{}\n\t\t\t{}\n\n\t\t\tconst T& read() const noexcept {\n\t\t\t\treturn box_t::get();\n\t\t\t}\n\n\t\t\tvoid next() {\n\t\t\t\t*stream_ >> box_t::get();\n\t\t\t\tif (!*stream_) {\n\t\t\t\t\tstream_ = nullptr;\n\t\t\t\t}\n\t\t\t}\n\t\t\tistream_cursor post_increment() {\n\t\t\t\tauto tmp = *this;\n\t\t\t\tnext();\n\t\t\t\treturn tmp;\n\t\t\t}\n\n\t\t\tbool equal(const istream_cursor& that) const noexcept {\n\t\t\t\treturn stream_ == that.stream_;\n\t\t\t}\n\n\t\t\tbool equal(default_sentinel_t) const noexcept {\n\t\t\t\treturn stream_ == nullptr;\n\t\t\t}\n\n\t\tprivate:\n\t\t\traw_ptr<istream_type> stream_ = nullptr;\n\t\t};\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// istream_iterator [iterator.istream]\n\t//\n\ttemplate<semiregular T, class charT = char, class traits = std::char_traits<charT>,\n\t\tsigned_integral Distance = std::ptrdiff_t>\n\trequires\n\t\tStreamExtractable<T, charT, traits>\n\tusing istream_iterator =\n\t\tbasic_iterator<detail::istream_cursor<T, charT, traits, Distance>>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/istreambuf_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_ISTREAMBUF_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_ISTREAMBUF_ITERATOR_HPP\n\n#include <iosfwd>\n#include <string>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/concepts/fundamental.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace __istreambuf_iterator {\n\t\ttemplate<class charT, class traits = std::char_traits<charT>>\n\t\trequires\n\t\t\tsigned_integral<typename traits::off_type>\n\t\tclass cursor;\n\t}\n\n\t// Not to spec:\n\t// * requirements are implicit.\n\t//   See https://github.com/ericniebler/stl2/issues/246)\n\t//\n\ttemplate<class charT, class traits = std::char_traits<charT>>\n\trequires\n\t\tmove_constructible<charT> &&\n\t\tdefault_initializable<charT> &&\n\t\tsigned_integral<typename traits::off_type>\n\tusing istreambuf_iterator =\n\t\tbasic_iterator<__istreambuf_iterator::cursor<charT, traits>>;\n\n\tnamespace __istreambuf_iterator {\n\t\ttemplate<class charT, class traits>\n\t\trequires\n\t\t\tsigned_integral<typename traits::off_type>\n\t\tclass cursor {\n\t\tpublic:\n\t\t\tusing value_type = charT;\n\t\t\tusing difference_type = typename traits::off_type;\n\t\t\tusing streambuf_type = std::basic_streambuf<charT, traits>;\n\t\t\tusing istream_type = std::basic_istream<charT, traits>;\n\t\t\tusing int_type = typename traits::int_type;\n\t\t\tusing single_pass = std::true_type;\n\n\t\t\tclass pointer {\n\t\t\tpublic:\n\t\t\t\tconstexpr charT* operator->() noexcept {\n\t\t\t\t\treturn &keep_;\n\t\t\t\t}\n\n\t\t\tprivate:\n\t\t\t\tfriend cursor;\n\n\t\t\t\texplicit constexpr pointer(const cursor& i)\n\t\t\t\tnoexcept(std::is_nothrow_move_constructible<charT>::value)\n\t\t\t\t: keep_{i.current()}\n\t\t\t\t{}\n\n\t\t\t\tcharT keep_;\n\t\t\t};\n\n\t\t\tclass __proxy {\n\t\t\tpublic:\n\t\t\t\tusing value_type = charT;\n\n\t\t\t\tconstexpr charT operator*() const\n\t\t\t\tnoexcept(std::is_nothrow_copy_constructible<charT>::value)\n\t\t\t\t{\n\t\t\t\t\treturn keep_;\n\t\t\t\t}\n\n\t\t\tprivate:\n\t\t\t\tfriend cursor;\n\n\t\t\t\tconstexpr __proxy() noexcept = default;\n\t\t\t\tconstexpr __proxy(charT c, streambuf_type* sbuf)\n\t\t\t\tnoexcept(std::is_nothrow_move_constructible<charT>::value)\n\t\t\t\t: keep_{std::move(c)}, sbuf_{sbuf}\n\t\t\t\t{}\n\n\t\t\t\tcharT keep_;\n\t\t\t\tdetail::raw_ptr<streambuf_type> sbuf_;\n\t\t\t};\n\n\t\t\tclass mixin : protected basic_mixin<cursor> {\n\t\t\t\tusing base_t = basic_mixin<cursor>;\n\t\t\tpublic:\n\t\t\t\tusing iterator_category = input_iterator_tag;\n\t\t\t\tusing value_type = cursor::value_type;\n\t\t\t\tusing difference_type = cursor::difference_type;\n\t\t\t\tusing reference = charT;\n\t\t\t\tusing pointer = cursor::pointer;\n\t\t\t\tusing char_type = charT;\n\t\t\t\tusing traits_type = traits;\n\t\t\t\tusing int_type = cursor::int_type;\n\t\t\t\tusing streambuf_type = cursor::streambuf_type;\n\t\t\t\tusing istream_type = cursor::istream_type;\n\n\t\t\t\tmixin() = default;\n\t\t\t\tconstexpr mixin(default_sentinel_t) noexcept\n\t\t\t\t: base_t{}\n\t\t\t\t{}\n\t\t\t\tmixin(streambuf_type* s) noexcept\n\t\t\t\t: base_t{cursor{s}}\n\t\t\t\t{}\n\t\t\t\tmixin(const __proxy& p) noexcept\n\t\t\t\t: base_t{cursor{p}}\n\t\t\t\t{}\n\t\t\t\tmixin(istream_type& s) noexcept\n\t\t\t\t: base_t{cursor{s}}\n\t\t\t\t{}\n\t\t\t\tusing base_t::base_t;\n\n\t\t\t\t// Yuck. This can't be simply \"basic_iterator<cursor>\".\n\t\t\t\t// Since basic_iterator<cursor> derives from mixin, mixin must be\n\t\t\t\t// instantiable before basic_iterator<cursor> is complete.\n\t\t\t\ttemplate<same_as<cursor> C>\n\t\t\t\tbool equal(const basic_iterator<C>& that) const noexcept {\n\t\t\t\t\treturn base_t::get().equal(get_cursor(that));\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconstexpr cursor() noexcept = default;\n\t\t\tconstexpr cursor(default_sentinel_t) noexcept\n\t\t\t: cursor{}\n\t\t\t{}\n\t\t\tcursor(streambuf_type* s) noexcept\n\t\t\t: sbuf_{s}\n\t\t\t{}\n\t\t\tcursor(const __proxy& p) noexcept\n\t\t\t: cursor{p.sbuf_}\n\t\t\t{}\n\t\t\tcursor(istream_type& s) noexcept\n\t\t\t: cursor{s.rdbuf()}\n\t\t\t{}\n\n\t\t\tcharT read() const {\n\t\t\t\treturn current();\n\t\t\t}\n\t\t\tpointer arrow() const {\n\t\t\t\treturn pointer{*this};\n\t\t\t}\n\n\t\t\tvoid next() {\n\t\t\t\tadvance();\n\t\t\t}\n\t\t\t__proxy post_increment() {\n\t\t\t\treturn {traits::to_char_type(advance()), sbuf_};\n\t\t\t}\n\n\t\t\tbool equal(const cursor& that) const noexcept {\n\t\t\t\treturn at_end() == that.at_end();\n\t\t\t}\n\t\t\tbool equal(default_sentinel_t) const noexcept {\n\t\t\t\treturn at_end();\n\t\t\t}\n\n\t\tprivate:\n\t\t\tdetail::raw_ptr<streambuf_type> sbuf_ = nullptr;\n\n\t\t\tbool at_end() const {\n\t\t\t\tif (!sbuf_) return true;\n\t\t\t\treturn traits::eq_int_type(sbuf_->sgetc(), traits::eof());\n\t\t\t}\n\n\t\t\tcharT current() const {\n\t\t\t\tauto c = sbuf_->sgetc();\n\t\t\t\tSTL2_ASSERT(!traits::eq_int_type(c, traits::eof()));\n\t\t\t\treturn traits::to_char_type(std::move(c));\n\t\t\t}\n\n\t\t\tint_type advance() {\n\t\t\t\tauto old_c = sbuf_->sbumpc();\n\t\t\t\tSTL2_ASSERT(!traits::eq_int_type(old_c, traits::eof()));\n\t\t\t\tif (traits::eq_int_type(sbuf_->sgetc(), traits::eof())) {\n\t\t\t\t\tsbuf_ = nullptr;\n\t\t\t\t}\n\t\t\t\treturn old_c;\n\t\t\t}\n\t\t};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/move_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_MOVE_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_MOVE_ITERATOR_HPP\n\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<semiregular> class move_sentinel;\n\n\tnamespace __move_iterator {\n\t\ttemplate<input_iterator> class cursor;\n\n\t\tstruct access {\n\t\t\ttemplate<_SpecializationOf<cursor> C>\n\t\t\tstatic constexpr decltype(auto) current(C&& c) noexcept {\n\t\t\t\treturn (std::forward<C>(c).current_);\n\t\t\t}\n\t\t\ttemplate<_SpecializationOf<move_sentinel> MS>\n\t\t\tstatic constexpr decltype(auto) sentinel(MS&& ms) noexcept {\n\t\t\t\treturn std::forward<MS>(ms).get();\n\t\t\t}\n\t\t};\n\n\t\ttemplate<input_iterator I>\n\t\tclass cursor {\n\t\t\tfriend access;\n\t\t\tI current_{};\n\t\tpublic:\n\t\t\tusing difference_type = iter_difference_t<I>;\n\t\t\tusing value_type = iter_value_t<I>;\n\t\t\tusing single_pass = meta::bool_<!forward_iterator<I>>;\n\n\t\t\tclass mixin : protected basic_mixin<cursor> {\n\t\t\t\tusing base_t = basic_mixin<cursor>;\n\t\t\tpublic:\n\t\t\t\tusing iterator_type = I;\n\t\t\t\tusing difference_type = cursor::difference_type;\n\t\t\t\tusing value_type = cursor::value_type;\n\t\t\t\tusing iterator_category = input_iterator_tag;\n\t\t\t\tusing reference = iter_rvalue_reference_t<I>;\n\n\t\t\t\tconstexpr mixin() = default;\n\t\t\t\tconstexpr explicit mixin(I&& i)\n\t\t\t\tnoexcept(std::is_nothrow_move_constructible<I>::value)\n\t\t\t\t: base_t{cursor{std::move(i)}}\n\t\t\t\t{}\n\t\t\t\tconstexpr explicit mixin(const I& i)\n\t\t\t\tnoexcept(std::is_nothrow_copy_constructible<I>::value)\n\t\t\t\t: base_t{cursor{i}}\n\t\t\t\t{}\n\t\t\t\tusing base_t::base_t;\n\n\t\t\t\tconstexpr I base() const\n\t\t\t\tnoexcept(std::is_nothrow_copy_constructible<I>::value)\n\t\t\t\t{\n\t\t\t\t\treturn base_t::get().current_;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconstexpr cursor() = default;\n\t\t\tconstexpr explicit cursor(I&& i)\n\t\t\tnoexcept(std::is_nothrow_move_constructible<I>::value)\n\t\t\t: current_{std::move(i)}\n\t\t\t{}\n\t\t\tconstexpr explicit cursor(const I& i)\n\t\t\tnoexcept(std::is_nothrow_copy_constructible<I>::value)\n\t\t\t: current_{i}\n\t\t\t{}\n\t\t\ttemplate<convertible_to<I> U>\n\t\t\tconstexpr cursor(const cursor<U>& u)\n\t\t\tnoexcept(std::is_nothrow_constructible<I, const U&>::value)\n\t\t\t: current_{access::current(u)}\n\t\t\t{}\n\n\t\t\tconstexpr iter_rvalue_reference_t<I> read() const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\titer_move(current_)\n\t\t\t)\n\n\t\t\tconstexpr void next()\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tstatic_cast<void>(++current_)\n\t\t\t)\n\n\t\t\t// Not to spec\n\t\t\t// Experimental support for move_iterator post-increment\n\t\t\t// BUGBUG doesn't correctly handle when decltype(current_++)\n\t\t\t// is a reference.\n\t\t\tusing __postinc_t = std::decay_t<decltype(current_++)>;\n\t\t\ttemplate<readable R>\n\t\t\tstruct __proxy {\n\t\t\t\tusing value_type = __stl2::iter_value_t<R>;\n\t\t\t\tR __tmp;\n\t\t\t\tconstexpr decltype(auto) operator*()\n\t\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t\t__stl2::iter_move(__tmp)\n\t\t\t\t)\n\t\t\t\tfriend constexpr decltype(auto) iter_move(const __proxy& that)\n\t\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t\t__stl2::iter_move(that.__tmp)\n\t\t\t\t)\n\t\t\t};\n\n#if STL2_WORKAROUND_GCC_69096\n\t\t\ttemplate<class = void>\n#endif // STL2_WORKAROUND_GCC_69096\n\t\t\tconstexpr auto post_increment()\n\t\t\tnoexcept(noexcept(__proxy<__postinc_t>{current_++}))\n\t\t\trequires (!forward_iterator<I> && readable<__postinc_t>) {\n\t\t\t\treturn __proxy<__postinc_t>{current_++};\n\t\t\t}\n\n\t\t\tconstexpr void prev()\n\t\t\tnoexcept(noexcept(--current_))\n\t\t\trequires bidirectional_iterator<I>\n\t\t\t{\n\t\t\t\t--current_;\n\t\t\t}\n\n\t\t\tconstexpr void advance(iter_difference_t<I> n)\n\t\t\tnoexcept(noexcept(current_ += n))\n\t\t\trequires random_access_iterator<I>\n\t\t\t{\n\t\t\t\tcurrent_ += n;\n\t\t\t}\n\n\t\t\ttemplate<equality_comparable_with<I> I2>\n\t\t\tconstexpr bool equal(const cursor<I2>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tcurrent_ == access::current(that)\n\t\t\t)\n\n\t\t\ttemplate<sentinel_for<I> S>\n\t\t\tconstexpr bool equal(const move_sentinel<S>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tcurrent_ == access::sentinel(that)\n\t\t\t)\n\n\t\t\ttemplate<sized_sentinel_for<I> S>\n\t\t\tconstexpr iter_difference_t<I>\n\t\t\tdistance_to(const cursor<S>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\taccess::current(that) - current_\n\t\t\t)\n\n\t\t\ttemplate<sized_sentinel_for<I> S>\n\t\t\tconstexpr iter_difference_t<I>\n\t\t\tdistance_to(const move_sentinel<S>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\taccess::sentinel(that) - current_\n\t\t\t)\n\n\t\t\tconstexpr decltype(auto) indirect_move() const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\titer_move(current_)\n\t\t\t)\n\n\t\t\ttemplate<indirectly_swappable<I> I2>\n\t\t\tconstexpr void indirect_swap(const cursor<I2>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\titer_swap(current_, access::current(that))\n\t\t\t)\n\t\t};\n\t}\n\n\ttemplate<input_iterator I>\n\tusing move_iterator = basic_iterator<__move_iterator::cursor<I>>;\n\n\ttemplate<class I>\n\tstruct iterator_category<move_iterator<I>> {\n\t\tusing type = input_iterator_tag;\n\t};\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool\n\toperator<(const move_iterator<I1>& a, const move_iterator<I2>& b)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t__move_iterator::access::current(get_cursor(a)) <\n\t\t\t__move_iterator::access::current(get_cursor(b))\n\t)\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool\n\toperator>(const move_iterator<I1>& a, const move_iterator<I2>& b)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tb < a\n\t)\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool\n\toperator<=(const move_iterator<I1>& a, const move_iterator<I2>& b)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t!(b < a)\n\t)\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool\n\toperator>=(const move_iterator<I1>& a, const move_iterator<I2>& b)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t!(a < b)\n\t)\n\n\ttemplate<class I>\n\trequires\n\t\tinput_iterator<__f<I>>\n\tconstexpr auto make_move_iterator(I&& i)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tmove_iterator<__f<I>>{std::forward<I>(i)}\n\t)\n\n\ttemplate<semiregular S>\n\tclass move_sentinel : detail::ebo_box<S, move_sentinel<S>> {\n\t\tfriend __move_iterator::access;\n\t\tusing box_t = detail::ebo_box<S, move_sentinel<S>>;\n\tpublic:\n\t\tconstexpr move_sentinel()\n\t\tnoexcept(std::is_nothrow_default_constructible<S>::value)\n\t\t: box_t{}\n\t\t{}\n\t\texplicit constexpr move_sentinel(S s)\n\t\tnoexcept(std::is_nothrow_move_constructible<S>::value)\n\t\t: box_t(std::move(s))\n\t\t{}\n\t\ttemplate<class T>\n\t\trequires convertible_to<const T&, S>\n\t\tconstexpr move_sentinel(const move_sentinel<T>& s)\n\t\tnoexcept(std::is_nothrow_constructible<S, const T&>::value)\n\t\t: box_t{__move_iterator::access::sentinel(s)}\n\t\t{}\n\n\t\ttemplate<class T>\n\t\trequires assignable_from<S&, const T&>\n\t\tconstexpr move_sentinel& operator=(const move_sentinel<T>& s) &\n\t\tnoexcept(std::is_nothrow_assignable<S&, const T&>::value)\n\t\t{\n\t\t\tbox_t::get() = __move_iterator::access::sentinel(s);\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr S base() const\n\t\tnoexcept(std::is_nothrow_copy_constructible<S>::value)\n\t\t{ return box_t::get(); }\n\t};\n\n\ttemplate<class S>\n\trequires semiregular<__f<S>>\n\tconstexpr auto make_move_sentinel(S&& s)\n\tSTL2_NOEXCEPT_RETURN(\n\t\tmove_sentinel<__f<S>>(std::forward<S>(s))\n\t)\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/operations.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-present\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_OPERATIONS_HPP\n#define STL2_DETAIL_ITERATOR_OPERATIONS_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// Iterator operations [range.iter.ops]\nSTL2_OPEN_NAMESPACE {\n\ttemplate<input_or_output_iterator> class counted_iterator;\n\n\tstruct __advance_fn : private __niebloid {\n\t\ttemplate<input_or_output_iterator I>\n\t\tconstexpr void operator()(I& i, iter_difference_t<I> n) const\n\t\t// [[expects: n >= 0 || bidirectional_iterator<I>]]\n\t\t{\n\t\t\tif constexpr (random_access_iterator<I>) {\n\t\t\t\ti += n;\n\t\t\t} else {\n\t\t\t\tif constexpr (bidirectional_iterator<I>) {\n\t\t\t\t\tfor (; n < 0; ++n) {\n\t\t\t\t\t\t--i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\t\tfor (; n > 0; --n) {\n\t\t\t\t\t++i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\t\tconstexpr void operator()(I& i, S bound) const\n\t\t// [[expects axiom: reachable(i, bound)]]\n\t\t{\n\t\t\tif constexpr (assignable_from<I&, S>) {\n\t\t\t\ti = std::move(bound);\n\t\t\t} else if constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\titer_difference_t<I> d = bound - i;\n\t\t\t\tSTL2_EXPECT(d >= 0);\n\t\t\t\t(*this)(i, d);\n\t\t\t} else while (i != bound) {\n\t\t\t\t++i;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\t\tconstexpr iter_difference_t<I>\n\t\toperator()(I& i, iter_difference_t<I> n, S bound) const\n\t\t// [[expects axiom: 0 == n ||\n\t\t//     (n > 0 && reachable(i, bound)) ||\n\t\t//     (n < 0 && same_as<I, S> && bidirectional_iterator<I> && reachable(bound, i))]]\n\t\t{\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\tconst auto d = bound - i;\n\t\t\t\tif constexpr (bidirectional_iterator<I> && same_as<I, S>) {\n\t\t\t\t\tSTL2_EXPECT(n >= 0 ? d >= 0 : d <= 0);\n\t\t\t\t\tif (n >= 0 ? n >= d : n <= d) {\n\t\t\t\t\t\ti = std::move(bound);\n\t\t\t\t\t\treturn n - d;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tSTL2_EXPECT(n >= 0 && d >= 0);\n\t\t\t\t\tif (n >= d) {\n\t\t\t\t\t\t(*this)(i, std::move(bound));\n\t\t\t\t\t\treturn n - d;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t(*this)(i, n);\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\tif constexpr (bidirectional_iterator<I> && same_as<I, S>) {\n\t\t\t\t\tif (n < 0) {\n\t\t\t\t\t\twhile (n != 0 && i != bound) {\n\t\t\t\t\t\t\t--i;\n\t\t\t\t\t\t\t++n;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn n;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\t\twhile (n != 0 && i != bound) {\n\t\t\t\t\t++i;\n\t\t\t\t\t--n;\n\t\t\t\t}\n\t\t\t\treturn n;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<input_or_output_iterator I>\n\t\tconstexpr void\n\t\toperator()(counted_iterator<I>& i, iter_difference_t<I> n) const;\n\t};\n\n\tinline constexpr __advance_fn advance{};\n\n\t// next\n\tstruct __next_fn : private __niebloid {\n\t\ttemplate<input_or_output_iterator I>\n\t\tconstexpr I operator()(I i) const {\n\t\t\treturn ++i;\n\t\t}\n\n\t\ttemplate<input_or_output_iterator I>\n\t\tconstexpr I operator()(I i, iter_difference_t<I> n) const {\n\t\t\tadvance(i, n);\n\t\t\treturn i;\n\t\t}\n\n\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\t\tconstexpr I operator()(I i, S bound) const {\n\t\t\tadvance(i, std::move(bound));\n\t\t\treturn i;\n\t\t}\n\n\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\t\tconstexpr I operator()(I i, iter_difference_t<I> n, S bound) const {\n\t\t\tadvance(i, n, std::move(bound));\n\t\t\treturn i;\n\t\t}\n\t};\n\n\tinline constexpr __next_fn next{};\n\n\t// prev\n\tstruct __prev_fn : private __niebloid {\n\t\ttemplate<bidirectional_iterator I>\n\t\tconstexpr I operator()(I i) const {\n\t\t\treturn --i;\n\t\t}\n\n\t\ttemplate<bidirectional_iterator I>\n\t\tconstexpr I operator()(I i, iter_difference_t<I> n) const {\n\t\t\tadvance(i, -n);\n\t\t\treturn i;\n\t\t}\n\n\t\ttemplate<bidirectional_iterator I>\n\t\tconstexpr I operator()(I i, iter_difference_t<I> n, I bound) const {\n\t\t\tadvance(i, -n, std::move(bound));\n\t\t\treturn i;\n\t\t}\n\t};\n\n\tinline constexpr __prev_fn prev{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/ostream_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_OSTREAM_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_OSTREAM_ITERATOR_HPP\n\n#include <iosfwd>\n#include <memory>\n#include <string>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iostream/concepts.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// ostream_iterator [ostream.iterator]\n\t// Extension: ostream_iterator<void> accepts any streamable type.\n\t//\n\ttemplate<class T = void, class charT = char, class traits = std::char_traits<charT>>\n\trequires\n\t\tsame_as<T, void> ||\n\t\tStreamInsertable<T, charT, traits>\n\tclass ostream_iterator {\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing char_type = charT;\n\t\tusing traits_type = traits;\n\t\tusing ostream_type = std::basic_ostream<charT, traits>;\n\n\t\tconstexpr ostream_iterator() noexcept = default;\n\n\t\tostream_iterator(\n\t\t\tostream_type& os, const charT* delimiter = nullptr) noexcept\n\t\t: out_stream_(std::addressof(os)), delim_(delimiter) {}\n\n\t\ttemplate<class U, class V = meta::if_c<STL2_IS_VOID(T), U, T>>\n\t\trequires\n\t\t\tconvertible_to<U, V const&> &&\n\t\t\tStreamInsertable<V, charT, traits>\n\t\tostream_iterator& operator=(U&& u) {\n\t\t\t*out_stream_ << static_cast<V const &>(std::forward<U>(u));\n\t\t\tif (delim_ != nullptr) {\n\t\t\t\t*out_stream_ << delim_;\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\n\t\tostream_iterator& operator*() noexcept {\n\t\t\treturn *this;\n\t\t}\n\t\tostream_iterator& operator++() noexcept {\n\t\t\treturn *this;\n\t\t}\n\t\tostream_iterator& operator++(int) noexcept {\n\t\t\treturn *this;\n\t\t}\n\tprivate:\n\t\tdetail::raw_ptr<std::basic_ostream<charT, traits>> out_stream_{nullptr};\n\t\tconst charT* delim_{nullptr};\n\t};\n\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/ostreambuf_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_OSTREAMBUF_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_OSTREAMBUF_ITERATOR_HPP\n\n#include <iosfwd>\n#include <string>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/concepts/fundamental.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t// Not to spec:\n\t// * Extension: satisfies equality_comparable and sentinel_for<default_sentinel_t>\n\ttemplate<class charT, class traits = std::char_traits<charT>>\n\tclass ostreambuf_iterator {\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing char_type = charT;\n\t\tusing traits_type = traits;\n\t\tusing ostream_type = std::basic_ostream<charT, traits>;\n\t\tusing streambuf_type = std::basic_streambuf<charT, traits>;\n\n\t\tconstexpr ostreambuf_iterator() noexcept = default;\n\t\tconstexpr ostreambuf_iterator(default_sentinel_t) noexcept\n\t\t: ostreambuf_iterator{}\n\t\t{}\n\t\tostreambuf_iterator(ostream_type& s) noexcept\n\t\t: sbuf_(s.rdbuf()) {}\n\t\tostreambuf_iterator(streambuf_type* s) noexcept\n\t\t: sbuf_(s) {}\n\t\tostreambuf_iterator& operator=(charT c) {\n\t\t\tif (sbuf_) {\n\t\t\t\tif (traits::eq_int_type(sbuf_->sputc(std::move(c)), traits::eof())) {\n\t\t\t\t\tsbuf_ = nullptr;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\t\tostreambuf_iterator& operator*() noexcept {\n\t\t\treturn *this;\n\t\t}\n\t\tostreambuf_iterator& operator++() noexcept {\n\t\t\treturn *this;\n\t\t}\n\t\tostreambuf_iterator& operator++(int) noexcept {\n\t\t\treturn *this;\n\t\t}\n\t\tbool failed() const noexcept {\n\t\t\treturn sbuf_ != nullptr;\n\t\t}\n\t\tfriend bool operator==(ostreambuf_iterator a, ostreambuf_iterator b) noexcept {\n\t\t\treturn a.sbuf_ == b.sbuf_;\n\t\t}\n\t\tfriend bool operator!=(ostreambuf_iterator a, ostreambuf_iterator b) noexcept {\n\t\t\treturn !(a == b);\n\t\t}\n\t\tfriend bool operator==(ostreambuf_iterator a, default_sentinel_t) noexcept {\n\t\t\treturn a.sbuf_ == nullptr;\n\t\t}\n\t\tfriend bool operator!=(ostreambuf_iterator a, default_sentinel_t b) noexcept {\n\t\t\treturn !(a == b);\n\t\t}\n\t\tfriend bool operator==(default_sentinel_t, ostreambuf_iterator b) noexcept {\n\t\t\treturn b.sbuf_ == nullptr;\n\t\t}\n\t\tfriend bool operator!=(default_sentinel_t a, ostreambuf_iterator b) noexcept {\n\t\t\treturn !(a == b);\n\t\t}\n\tprivate:\n\t\tdetail::raw_ptr<streambuf_type> sbuf_{nullptr};\n\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/reverse_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_REVERSE_ITERATOR_HPP\n#define STL2_DETAIL_ITERATOR_REVERSE_ITERATOR_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/operations.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// reverse_iterator [reverse.iterator]\n//\nSTL2_OPEN_NAMESPACE {\n\tnamespace __reverse_iterator {\n\t\ttemplate<bidirectional_iterator> class cursor;\n\n\t\tstruct access {\n\t\t\ttemplate<_SpecializationOf<cursor> C>\n\t\t\tstatic constexpr decltype(auto) current(C&& c) noexcept {\n\t\t\t\treturn (std::forward<C>(c).current_);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<bidirectional_iterator I>\n\t\tclass cursor {\n\t\t\tfriend access;\n\t\t\tI current_{};\n\n\t\tpublic:\n\t\t\tusing difference_type = iter_difference_t<I>;\n\t\t\tusing value_type = iter_value_t<I>;\n\n\t\t\tclass mixin : protected basic_mixin<cursor> {\n\t\t\t\tusing base_t = basic_mixin<cursor>;\n\t\t\tpublic:\n\t\t\t\tusing iterator_type = I;\n\t\t\t\tusing difference_type = cursor::difference_type;\n\t\t\t\tusing value_type = cursor::value_type;\n\t\t\t\tusing iterator_category = iterator_category_t<I>;\n\t\t\t\tusing reference = iter_reference_t<I>;\n\t\t\t\tusing pointer = I;\n\n\t\t\t\tconstexpr mixin() = default;\n\t\t\t\tconstexpr explicit mixin(I x)\n\t\t\t\tnoexcept(std::is_nothrow_move_constructible<I>::value)\n\t\t\t\t: base_t{cursor{std::move(x)}}\n\t\t\t\t{}\n\t\t\t\tusing base_t::base_t;\n\n\t\t\t\tconstexpr I base() const\n\t\t\t\tnoexcept(std::is_nothrow_copy_constructible<I>::value)\n\t\t\t\t{ return base_t::get().current_; }\n\t\t\t};\n\n\t\t\tconstexpr cursor() = default;\n\t\t\tconstexpr explicit cursor(I x)\n\t\t\tnoexcept(std::is_nothrow_move_constructible<I>::value)\n\t\t\t: current_{std::move(x)}\n\t\t\t{}\n\t\t\ttemplate<convertible_to<I> U>\n\t\t\tconstexpr cursor(const cursor<U>& u)\n\t\t\tnoexcept(std::is_nothrow_constructible<I, const U&>::value)\n\t\t\t: current_{access::current(u)}\n\t\t\t{}\n\n\t\t\tconstexpr iter_reference_t<I> read() const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t*__stl2::prev(current_)\n\t\t\t)\n\n\t\t\tconstexpr I arrow() const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t__stl2::prev(current_)\n\t\t\t)\n\n\t\t\tconstexpr void next()\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)--current_\n\t\t\t)\n\n\t\t\tconstexpr void prev()\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)++current_\n\t\t\t)\n\n\t\t\tconstexpr void advance(iter_difference_t<I> n)\n\t\t\tnoexcept(noexcept(current_ -= n))\n\t\t\trequires random_access_iterator<I>\n\t\t\t{\n\t\t\t\tcurrent_ -= n;\n\t\t\t}\n\n\t\t\ttemplate<equality_comparable_with<I> J>\n\t\t\tconstexpr bool equal(const cursor<J>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\tcurrent_ == access::current(that)\n\t\t\t)\n\n\t\t\ttemplate<sized_sentinel_for<I> J>\n\t\t\tconstexpr iter_difference_t<I> distance_to(const cursor<J>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t-(access::current(that) - current_)\n\t\t\t)\n\n\t\t\tconstexpr decltype(auto) indirect_move() const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\titer_move(__stl2::prev(current_))\n\t\t\t)\n\n\t\t\ttemplate<indirectly_swappable<I> J>\n\t\t\tconstexpr void indirect_swap(const cursor<J>& that) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\titer_swap(\n\t\t\t\t\t__stl2::prev(current_), __stl2::prev(access::current(that)))\n\t\t\t)\n\t\t};\n\t}\n\n\ttemplate<class I>\n\tusing reverse_iterator = basic_iterator<__reverse_iterator::cursor<I>>;\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool operator<(\n\t\tconst reverse_iterator<I1>& x, const reverse_iterator<I2>& y)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t__reverse_iterator::access::current(get_cursor(x)) >\n\t\t\t__reverse_iterator::access::current(get_cursor(y))\n\t)\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool operator>(\n\t\tconst reverse_iterator<I1>& x, const reverse_iterator<I2>& y)\n\tSTL2_NOEXCEPT_RETURN(\n\t\ty < x\n\t)\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool operator<=(\n\t\tconst reverse_iterator<I1>& x, const reverse_iterator<I2>& y)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t!(y < x)\n\t)\n\n\ttemplate<class I1, totally_ordered_with<I1> I2>\n\tconstexpr bool operator>=(\n\t\tconst reverse_iterator<I1>& x, const reverse_iterator<I2>& y)\n\tSTL2_NOEXCEPT_RETURN(\n\t\t!(x < y)\n\t)\n\n\ttemplate<class I>\n\trequires bidirectional_iterator<__f<I>>\n\tconstexpr auto make_reverse_iterator(I&& i)\n\tSTL2_NOEXCEPT_RETURN(\n\t\treverse_iterator<__f<I>>{std::forward<I>(i)}\n\t)\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/iterator/unreachable.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_ITERATOR_UNREACHABLE_HPP\n#define STL2_DETAIL_ITERATOR_UNREACHABLE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/iterator/increment.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// unreachable_sentinel_t [unreachable.sentinel]\n//\nSTL2_OPEN_NAMESPACE {\n\tstruct unreachable_sentinel_t {\n\t\ttemplate<weakly_incrementable WI>\n\t\tfriend constexpr bool operator==(unreachable_sentinel_t, const WI&) noexcept {\n\t\t\treturn false;\n\t\t}\n\t\ttemplate<weakly_incrementable WI>\n\t\tfriend constexpr bool operator==(const WI&, unreachable_sentinel_t) noexcept {\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate<weakly_incrementable WI>\n\t\tfriend constexpr bool operator!=(unreachable_sentinel_t, const WI&) noexcept {\n\t\t\treturn true;\n\t\t}\n\t\ttemplate<weakly_incrementable WI>\n\t\tfriend constexpr bool operator!=(const WI&, unreachable_sentinel_t) noexcept {\n\t\t\treturn true;\n\t\t}\n\t};\n\n\tinline constexpr unreachable_sentinel_t unreachable_sentinel{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/memory/concepts.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Christopher Di Bella 2016\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_CONCEPTS_HPP\n#define STL2_DETAIL_MEMORY_CONCEPTS_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// _NoThrowInputIterator [Exposition]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT _NoThrowInputIterator =\n\t\tinput_iterator<I> &&\n\t\tstd::is_lvalue_reference_v<iter_reference_t<I>> &&\n\t\tsame_as<__uncvref<iter_reference_t<I>>, iter_value_t<I>>;\n\t\t// Axiom: no exceptions are thrown from increment, copy, move, assignment,\n\t\t//        indirection through valid iterators.\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// _NoThrowSentinel [Exposition]\n\t//\n\ttemplate<class S, class I>\n\tMETA_CONCEPT _NoThrowSentinel =\n\t\tsentinel_for<S, I>;\n\t\t// Axiom: no exceptions are thrown from comparisons between objects of types\n\t\t//        I and S.\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// _NoThrowInputRange [Exposition]\n\t//\n\ttemplate<class Rng>\n\tMETA_CONCEPT _NoThrowInputRange =\n\t\trange<Rng> &&\n\t\t_NoThrowInputIterator<iterator_t<Rng>> &&\n\t\t_NoThrowSentinel<sentinel_t<Rng>, iterator_t<Rng>>;\n\t\t// Axiom: no exceptions are thrown from calls to begin and end on a Rng.\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// _NoThrowForwardIterator [Exposition]\n\t//\n\ttemplate<class I>\n\tMETA_CONCEPT _NoThrowForwardIterator =\n\t\t_NoThrowInputIterator<I> &&\n\t\tforward_iterator<I> &&\n\t\t_NoThrowSentinel<I, I>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// _NoThrowForwardRange [Exposition]\n\t//\n\ttemplate<class Rng>\n\tMETA_CONCEPT _NoThrowForwardRange =\n\t\t_NoThrowInputRange<Rng> &&\n\t\t_NoThrowForwardIterator<iterator_t<Rng>>;\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_CONCEPTS_HPP\n"
  },
  {
    "path": "include/stl2/detail/memory/construct_at.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_CONSTRUCT_AT_HPP\n#define STL2_DETAIL_MEMORY_CONSTRUCT_AT_HPP\n\n#include <memory>\n#include <new>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class T, class... Args>\n\trequires constructible_from<T, Args...>\n\tvoid __construct_at(T& t, Args&&... args) {\n\t\t::new(const_cast<void*>(static_cast<const volatile void*>(std::addressof(t))))\n\t\t\tT(std::forward<Args>(args)...);\n\t}\n\n\ttemplate<default_initializable T>\n\tvoid __default_construct_at(T& t)\n\t{\n\t\t::new(const_cast<void*>(static_cast<const volatile void*>(std::addressof(t))))\n\t\t\tT;\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_CONSTRUCT_AT_HPP\n"
  },
  {
    "path": "include/stl2/detail/memory/destroy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_DESTROY_HPP\n#define STL2_DETAIL_MEMORY_DESTROY_HPP\n\n#include <memory>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/memory/concepts.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// destroy_at [specialized.destroy]\n\t//\n\tstruct __destroy_at_fn : private __niebloid {\n\t\ttemplate<destructible T>\n\t\tvoid operator()(T* p) const noexcept;\n\t};\n\n\tinline constexpr __destroy_at_fn destroy_at{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// destroy [specialized.destroy]\n\t//\n\tstruct __destroy_fn : private __niebloid {\n\t\ttemplate<_NoThrowInputIterator I, _NoThrowSentinel<I> S>\n\t\trequires destructible<iter_value_t<I>>\n\t\tI operator()(I first, S last) const noexcept {\n\t\t\tif constexpr (std::is_trivially_destructible_v<iter_value_t<I>>) {\n\t\t\t\tadvance(first, last);\n\t\t\t} else {\n\t\t\t\tfor (; first != last; ++first) {\n\t\t\t\t\tdestroy_at(std::addressof(*first));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<_NoThrowInputRange R>\n\t\trequires destructible<iter_value_t<iterator_t<R>>>\n\t\tsafe_iterator_t<R> operator()(R&& r) const noexcept {\n\t\t\tif constexpr (std::is_trivially_destructible_v<iter_value_t<iterator_t<R>>> &&\n\t\t\t              same_as<dangling, safe_iterator_t<R>>) {\n\t\t\t\treturn {};\n\t\t\t} else {\n\t\t\t\treturn (*this)(begin(r), end(r));\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __destroy_fn destroy{};\n\n\ttemplate<destructible T>\n\tinline void __destroy_at_fn::operator()(T* p) const noexcept {\n\t\tif constexpr (!std::is_trivially_destructible_v<T>) {\n\t\t\tif constexpr (std::is_array_v<T>) {\n\t\t\t\tdestroy(begin(*p), end(*p));\n\t\t\t} else {\n\t\t\t\tp->~T();\n\t\t\t}\n\t\t}\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// destroy_n [specialized.destroy]\n\t//\n\tstruct __destroy_n_fn : private __niebloid {\n\t\ttemplate<_NoThrowInputIterator I>\n\t\trequires destructible<iter_value_t<I>>\n\t\tI operator()(I first, iter_difference_t<I> n) const noexcept {\n\t\t\tif constexpr (std::is_trivially_destructible_v<iter_value_t<I>>) {\n\t\t\t\treturn next(std::move(first), n);\n\t\t\t} else {\n\t\t\t\treturn destroy(counted_iterator{std::move(first), n},\n\t\t\t\t\tdefault_sentinel).base();\n\t\t\t}\n\t\t}\n\t};\n\n\tinline constexpr __destroy_n_fn destroy_n{};\n\n\tnamespace detail {\n\t\ttemplate<_NoThrowForwardIterator I>\n\t\trequires destructible<iter_value_t<I>>\n\t\tstruct destroy_guard {\n\t\t\t~destroy_guard() {\n\t\t\t\tif (last_) {\n\t\t\t\t\tdestroy(std::move(first_), *last_);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texplicit destroy_guard(I& it)\n\t\t\t: first_{it}, last_{std::addressof(it)} {}\n\n\t\t\tdestroy_guard(destroy_guard&& that)\n\t\t\t: first_{std::move(that.first_)}\n\t\t\t, last_{__stl2::exchange(that.last_, nullptr)} {}\n\n\t\t\tvoid release() noexcept { last_ = nullptr; }\n\t\tprivate:\n\t\t\tI first_;\n\t\t\tdetail::raw_ptr<I> last_;\n\t\t};\n\n\t\ttemplate<_NoThrowForwardIterator I>\n\t\trequires destructible<iter_value_t<I>> &&\n\t\t\tstd::is_trivially_destructible_v<iter_value_t<I>>\n\t\tstruct destroy_guard<I> {\n\t\t\tconstexpr explicit destroy_guard(I&) noexcept {}\n\t\t\tconstexpr void release() const noexcept {}\n\t\t};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_DESTROY_HPP\n"
  },
  {
    "path": "include/stl2/detail/memory/uninitialized_copy.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_UNINITIALIZED_COPY_HPP\n#define STL2_DETAIL_MEMORY_UNINITIALIZED_COPY_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/memory/concepts.hpp>\n#include <stl2/detail/memory/construct_at.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_copy [uninitialized.copy]\n\t//\n\ttemplate<class I, class O>\n\tusing uninitialized_copy_result = __in_out_result<I, O>;\n\n\tstruct __uninitialized_copy_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S1, _NoThrowForwardIterator O, _NoThrowSentinel<O> S2>\n\t\trequires constructible_from<iter_value_t<O>, iter_reference_t<I>>\n\t\tuninitialized_copy_result<I, O> operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const {\n\t\t\tauto guard = detail::destroy_guard{ofirst};\n\t\t\tfor (; ifirst != ilast && ofirst != olast; (void) ++ifirst, (void)++ofirst) {\n\t\t\t\t__stl2::__construct_at(*ofirst, *ifirst);\n\t\t\t}\n\t\t\tguard.release();\n\t\t\treturn {std::move(ifirst), std::move(ofirst)};\n\t\t}\n\n\t\ttemplate<input_range IR, _NoThrowForwardRange OR>\n\t\trequires constructible_from<iter_value_t<iterator_t<OR>>, iter_reference_t<iterator_t<IR>>>\n\t\tuninitialized_copy_result<safe_iterator_t<IR>, safe_iterator_t<OR>>\n\t\toperator()(IR&& in, OR&& out) const {\n\t\t\treturn (*this)(begin(in), end(in), begin(out), end(out));\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_copy_fn uninitialized_copy{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_copy_n [uninitialized.copy]\n\t//\n\ttemplate<class I, class O>\n\tusing uninitialized_copy_n_result = __in_out_result<I, O>;\n\n\tstruct __uninitialized_copy_n_fn : private __niebloid {\n\t\ttemplate<input_iterator I, _NoThrowForwardIterator O, _NoThrowSentinel<O> S>\n\t\trequires constructible_from<iter_value_t<O>, iter_reference_t<I>>\n\t\tuninitialized_copy_n_result<I, O>\n\t\toperator()(I first, iter_difference_t<I> n, O ofirst, S olast) const {\n\t\t\tauto [in, out] = uninitialized_copy(\n\t\t\t\tcounted_iterator{std::move(first), n}, default_sentinel,\n\t\t\t\tstd::move(ofirst), std::move(olast));\n\t\t\treturn {in.base(), std::move(out)};\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_UNINITIALIZED_COPY_HPP\n"
  },
  {
    "path": "include/stl2/detail/memory/uninitialized_default_construct.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_UNINITIALIZED_DEFAULT_CONSTRUCT_HPP\n#define STL2_DETAIL_MEMORY_UNINITIALIZED_DEFAULT_CONSTRUCT_HPP\n\n#include <stl2/iterator.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/memory/concepts.hpp>\n#include <stl2/detail/memory/construct_at.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_default_construct [uninitialized.construct.default]\n\t//\n\tstruct __uninitialized_default_construct_fn : private __niebloid {\n\t\ttemplate<_NoThrowForwardIterator I, _NoThrowSentinel<I> S>\n\t\trequires default_initializable<iter_value_t<I>>\n\t\tI operator()(I first, S last) const {\n\t\t\tauto guard = detail::destroy_guard{first};\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\t__stl2::__default_construct_at(*first);\n\t\t\t}\n\t\t\tguard.release();\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<_NoThrowForwardRange Rng>\n\t\trequires default_initializable<iter_value_t<iterator_t<Rng>>>\n\t\tsafe_iterator_t<Rng> operator()(Rng&& rng) const {\n\t\t\treturn (*this)(begin(rng), end(rng));\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_default_construct_fn uninitialized_default_construct{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_default_construct_n [Extension]\n\t//\n\tstruct __uninitialized_default_construct_n_fn : private __niebloid {\n\t\ttemplate<_NoThrowForwardIterator I>\n\t\trequires default_initializable<iter_value_t<I>>\n\t\tI operator()(I first, iter_difference_t<I> n) const {\n\t\t\treturn uninitialized_default_construct(\n\t\t\t\tcounted_iterator{std::move(first), n},\n\t\t\t\tdefault_sentinel).base();\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_default_construct_n_fn uninitialized_default_construct_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_UNINITIALIZED_DEFAULT_CONSTRUCT_HPP\n"
  },
  {
    "path": "include/stl2/detail/memory/uninitialized_fill.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_UNINITIALIZED_FILL_HPP\n#define STL2_DETAIL_MEMORY_UNINITIALIZED_FILL_HPP\n\n#include <stl2/iterator.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/memory/concepts.hpp>\n#include <stl2/detail/memory/construct_at.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_fill [uninitialized.fill]\n\t//\n\tstruct __uninitialized_fill_fn : private __niebloid {\n\t\ttemplate<_NoThrowForwardIterator I, _NoThrowSentinel<I> S, class T>\n\t\trequires constructible_from<iter_value_t<I>, const T&>\n\t\tI operator()(I first, S last, const T& x) const {\n\t\t\tauto guard = detail::destroy_guard{first};\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\t__stl2::__construct_at(*first, x);\n\t\t\t}\n\t\t\tguard.release();\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<_NoThrowForwardRange R, class T>\n\t\trequires constructible_from<iter_value_t<iterator_t<R>>, const T&>\n\t\tsafe_iterator_t<R> operator()(R&& r, const T& x) const {\n\t\t\treturn (*this)(begin(r), end(r), x);\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_fill_fn uninitialized_fill{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_fill_n [uninitialized.fill]\n\t//\n\tstruct __uninitialized_fill_n_fn : private __niebloid {\n\t\ttemplate<_NoThrowForwardIterator I, class T>\n\t\trequires constructible_from<iter_value_t<I>, const T&>\n\t\tI operator()(I first, const iter_difference_t<I> n, const T& x) const {\n\t\t\treturn uninitialized_fill(\n\t\t\t\tcounted_iterator{std::move(first), n},\n\t\t\t\tdefault_sentinel, x).base();\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_UNINITIALIZED_FILL_HPP\n"
  },
  {
    "path": "include/stl2/detail/memory/uninitialized_move.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_UNINITIALIZED_MOVE_HPP\n#define STL2_DETAIL_MEMORY_UNINITIALIZED_MOVE_HPP\n\n#include <stl2/iterator.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/memory/concepts.hpp>\n#include <stl2/detail/memory/construct_at.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_move [uninitialized.move]\n\t//\n\ttemplate<class I, class O>\n\tusing uninitialized_move_result = __in_out_result<I, O>;\n\n\tstruct __uninitialized_move_fn : private __niebloid {\n\t\ttemplate<input_iterator I, sentinel_for<I> S1,\n\t\t\t_NoThrowForwardIterator O, _NoThrowSentinel<O> S2>\n\t\trequires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>\n\t\tuninitialized_move_result<I, O>\n\t\toperator()(I ifirst, S1 ilast, O ofirst, S2 olast) const {\n\t\t\tauto guard = detail::destroy_guard{ofirst};\n\t\t\tfor (; ifirst != ilast && ofirst != olast; (void) ++ifirst, (void) ++ofirst) {\n\t\t\t\t__stl2::__construct_at(*ofirst, iter_move(ifirst));\n\t\t\t}\n\t\t\tguard.release();\n\t\t\treturn {std::move(ifirst), std::move(ofirst)};\n\t\t}\n\n\t\ttemplate<input_range IR, _NoThrowForwardRange OR>\n\t\trequires constructible_from<iter_value_t<iterator_t<OR>>,\n\t\t                       iter_rvalue_reference_t<iterator_t<IR>>>\n\t\tuninitialized_move_result<safe_iterator_t<IR>, safe_iterator_t<OR>>\n\t\toperator()(IR&& in, OR&& out) const {\n\t\t\treturn (*this)(begin(in), end(in), begin(out), end(out));\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_move_fn uninitialized_move{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_move_n [uninitialized.move]\n\t//\n\ttemplate<class I, class O>\n\tusing uninitialized_move_n_result = __in_out_result<I, O>;\n\n\tstruct __uninitialized_move_n_fn : private __niebloid {\n\t\ttemplate<input_iterator I, _NoThrowForwardIterator O, _NoThrowSentinel<O> S>\n\t\trequires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>>\n\t\tuninitialized_move_n_result<I, O>\n\t\toperator()(I ifirst, iter_difference_t<I> n, O ofirst, S olast) const {\n\t\t\tauto [in, out] = uninitialized_move(counted_iterator{std::move(ifirst), n},\n\t\t\t\tdefault_sentinel, std::move(ofirst), std::move(olast));\n\t\t\treturn {in.base(), std::move(out)};\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_move_n_fn uninitialized_move_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_UNINITIALIZED_MOVE_HPP\n"
  },
  {
    "path": "include/stl2/detail/memory/uninitialized_value_construct.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_MEMORY_UNINITIALIZED_VALUE_CONSTRUCT_HPP\n#define STL2_DETAIL_MEMORY_UNINITIALIZED_VALUE_CONSTRUCT_HPP\n\n#include <stl2/iterator.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/memory/concepts.hpp>\n#include <stl2/detail/memory/construct_at.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_value_construct [uninitialized.construct.value]\n\t//\n\tstruct __uninitialized_value_construct_fn : private __niebloid {\n\t\ttemplate<_NoThrowForwardIterator I, _NoThrowSentinel<I> S>\n\t\trequires default_initializable<iter_value_t<I>>\n\t\tI operator()(I first, S last) const {\n\t\t\tauto guard = detail::destroy_guard{first};\n\t\t\tfor (; first != last; ++first) {\n\t\t\t\t__stl2::__construct_at(*first);\n\t\t\t}\n\t\t\tguard.release();\n\t\t\treturn first;\n\t\t}\n\n\t\ttemplate<_NoThrowForwardRange Rng>\n\t\trequires default_initializable<iter_value_t<iterator_t<Rng>>>\n\t\tsafe_iterator_t<Rng> operator()(Rng&& rng) const {\n\t\t\treturn (*this)(begin(rng), end(rng));\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_value_construct_fn uninitialized_value_construct{};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// uninitialized_value_construct_n [uninitialized.construct.value]\n\t//\n\tstruct __uninitialized_value_construct_n_fn : private __niebloid {\n\t\ttemplate<_NoThrowForwardIterator I>\n\t\trequires default_initializable<iter_value_t<I>>\n\t\tI operator()(I first, iter_difference_t<I> n) const {\n\t\t\treturn uninitialized_value_construct(\n\t\t\t\tcounted_iterator{first, n},\n\t\t\t\tdefault_sentinel).base();\n\t\t}\n\t};\n\n\tinline constexpr __uninitialized_value_construct_n_fn uninitialized_value_construct_n{};\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_MEMORY_UNINITIALIZED_VALUE_CONSTRUCT_HPP\n"
  },
  {
    "path": "include/stl2/detail/meta.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_META_HPP\n#define STL2_DETAIL_META_HPP\n\n#include <type_traits>\n#include <meta/meta.hpp>\n\n#include <stl2/detail/fwd.hpp>\n\n// Define some portable type_trait intrinsics\n#if defined(__clang__)\n#define STL2_IS_CONVERTIBLE(From, To) __is_convertible(From, To)\n#elif defined(_MSC_VER)\n#define STL2_IS_CONVERTIBLE(From, To) __is_convertible_to(From, To)\n#else\n#define STL2_IS_CONVERTIBLE(From, To) std::is_convertible_v<From, To>\n#endif\n\n#if defined(__clang__)\n#define STL2_IS_VOID(T) __is_void(T)\n#else\n#define STL2_IS_VOID(T) std::is_void_v<T>\n#endif\n\n#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)\n#define STL2_IS_BASE(Base, Derived) __is_base_of(Base, Derived)\n#else\n#define STL2_IS_BASE(Base, Derived) std::is_base_of_v<Base, Derived>\n#endif\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class T>\n\tusing __uncvref = std::remove_cv_t<std::remove_reference_t<T>>;\n\n\ttemplate<bool IsConst, class T>\n\tusing __maybe_const = std::conditional_t<IsConst, T const, T>;\n\n\ttemplate<class From, class To>\n\tinline constexpr bool is_nothrow_convertible_v =\n\t\tSTL2_IS_VOID(From) && STL2_IS_VOID(To);\n\n\ttemplate<class T>\n\tvoid __nothrow_convertible_helper(T) noexcept; // not defined\n\n\ttemplate<class From, class To>\n\trequires META_CONCEPT_BARRIER(STL2_IS_CONVERTIBLE(From, To))\n\tinline constexpr bool is_nothrow_convertible_v<From, To> =\n\t\tnoexcept(__nothrow_convertible_helper<To>(std::declval<From>()));\n\n\ttemplate<class T, class D = std::decay_t<T>>\n\trequires META_CONCEPT_BARRIER(STL2_IS_CONVERTIBLE(T, D))\n\tD __decay_copy(T&& t)\n\tnoexcept(is_nothrow_convertible_v<T, D>)\n#if defined(__GNUC__) && !defined(__clang__)\n\t{\n\t\treturn static_cast<T&&>(t);\n\t}\n#else\n\t; // not defined\n#endif\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/non_propagating_cache.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n\n#ifndef STL2_DETAIL_NON_PROPAGATING_CACHE_HPP\n#define STL2_DETAIL_NON_PROPAGATING_CACHE_HPP\n\n#include <optional>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<ext::destructible_object T, class Tag = void, bool Enable = true>\n\t\tstruct non_propagating_cache : std::optional<T> {\n\t\t\tnon_propagating_cache() = default;\n\t\t\tconstexpr non_propagating_cache(std::nullopt_t) noexcept\n\t\t\t{}\n\t\t\tconstexpr non_propagating_cache(non_propagating_cache const &) noexcept\n\t\t\t: std::optional<T>{}\n\t\t\t{}\n\t\t\tconstexpr non_propagating_cache(non_propagating_cache &&that) noexcept\n\t\t\t: std::optional<T>{}\n\t\t\t{ that.std::optional<T>::reset(); }\n\t\t\tconstexpr non_propagating_cache &operator=(non_propagating_cache const &) noexcept {\n\t\t\t\tstd::optional<T>::reset();\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tconstexpr non_propagating_cache &operator=(non_propagating_cache &&that) noexcept {\n\t\t\t\tthat.std::optional<T>::reset();\n\t\t\t\tstd::optional<T>::reset();\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tusing std::optional<T>::operator=;\n\t\t};\n\n\t\ttemplate<ext::destructible_object T, class Tag>\n\t\tstruct non_propagating_cache<T, Tag, false> {};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/randutils.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n\n#ifndef STL2_DETAIL_RANDOM_HPP\n#define STL2_DETAIL_RANDOM_HPP\n\n#include <cstdint>\n#include <initializer_list>\n#include <random>\n#include <stl2/random.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/algorithm/generate.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tnamespace random {\n\t\t\tstruct seeder // Brutal SeedSequence hack\n\t\t\t{\n\t\t\t\tusing result_type = std::uint32_t;\n\n\t\t\t\tseeder() = default;\n\t\t\t\tseeder(std::initializer_list<result_type>) {}\n\t\t\t\ttemplate<input_iterator I, sentinel_for<I> S>\n\t\t\t\tseeder(I, S) {}\n\n\t\t\t\ttemplate<random_access_iterator I, sized_sentinel_for<I> S>\n\t\t\t\tvoid generate(I first, S last) const {\n\t\t\t\t\tstd::random_device rd{};\n\t\t\t\t\t__stl2::generate(first, last, __stl2::ref(rd));\n\t\t\t\t}\n\n\t\t\t\tstatic constexpr std::size_t size() noexcept { return ~std::size_t{0}; }\n\n\t\t\t\ttemplate<output_iterator<result_type> I>\n\t\t\t\tvoid param(I) noexcept {}\n\t\t\t};\n\t\t}\n\n\t\tusing default_random_engine =\n\t\t\tmeta::if_c<sizeof(void*) >= 8, std::mt19937_64, std::mt19937>;\n\t\ttemplate<class = void>\n\t\tinline default_random_engine& get_random_engine()\n\t\t{\n\t\t\tthread_local default_random_engine engine = []{\n\t\t\t\trandom::seeder seed;\n\t\t\t\treturn default_random_engine{seed};\n\t\t\t}();\n\t\t\treturn engine;\n\t\t}\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/range/access.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_RANGE_ACCESS_HPP\n#define STL2_DETAIL_RANGE_ACCESS_HPP\n\n#include <initializer_list>\n#include <memory>\n#include <string>\n#include <string_view>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/reverse_iterator.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// range access [range.access]\n//\nSTL2_OPEN_NAMESPACE {\n\tinline constexpr struct __as_const_fn {\n\t\ttemplate<class T>\n\t\tconstexpr const T& operator()(T& t) const noexcept {\n\t\t\treturn t;\n\t\t}\n\t\ttemplate<class T>\n\t\tconstexpr const T&& operator()(T&& t) const noexcept {\n\t\t\treturn (T&&)t;\n\t\t}\n\t} __as_const{};\n\n\t// begin\n\tnamespace __begin {\n\t\t// Poison pill for std::begin. (See the detailed discussion at\n\t\t// https://github.com/ericniebler/stl2/issues/139)\n\t\ttemplate<class T> void begin(T&&) = delete;\n\n\t\ttemplate<class T>\n\t\tvoid begin(std::initializer_list<T>) = delete; // See LWG 3258\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_member = std::is_lvalue_reference_v<R> &&\n\t\t\trequires(R& r) {\n\t\t\t\tr.begin();\n\t\t\t\t{ __decay_copy(r.begin()) } -> input_or_output_iterator;\n\t\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_non_member = requires(R&& r) {\n\t\t\tbegin(static_cast<R&&>(r));\n\t\t\t{ __decay_copy(begin(static_cast<R&&>(r))) } -> input_or_output_iterator;\n\t\t};\n\n\t\ttemplate<class>\n\t\tinline constexpr bool nothrow = false;\n\t\ttemplate<has_member R>\n\t\tinline constexpr bool nothrow<R> = noexcept(std::declval<R&>().begin());\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && has_non_member<R>)\n\t\tinline constexpr bool nothrow<R> = noexcept(begin(std::declval<R>()));\n\n\t\tstruct __fn {\n\t\t\t// Handle builtin arrays directly\n\t\t\ttemplate<class R, std::size_t N>\n\t\t\tvoid operator()(R (&&)[N]) const = delete;\n\n\t\t\ttemplate<class R, std::size_t N>\n\t\t\tconstexpr R* operator()(R (&array)[N]) const noexcept {\n\t\t\t\treturn array;\n\t\t\t}\n\n\t\t\t// Handle basic_string_view directly to implement P0970 non-intrusively\n\t\t\ttemplate<class CharT, class Traits>\n\t\t\tconstexpr auto operator()(\n\t\t\t\tstd::basic_string_view<CharT, Traits> sv) const noexcept {\n\t\t\t\treturn sv.begin();\n\t\t\t}\n\n\t\t\ttemplate<class R>\n\t\t\trequires has_member<R> || has_non_member<R>\n\t\t\tconstexpr auto operator()(R&& r) const noexcept(nothrow<R>) {\n\t\t\t\tif constexpr (has_member<R>) {\n\t\t\t\t\treturn r.begin();\n\t\t\t\t} else {\n\t\t\t\t\treturn begin(static_cast<R&&>(r));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __begin::__fn begin{};\n\t}\n\n\ttemplate<class R>\n\tusing __begin_t = decltype(begin(std::declval<R>()));\n\n\t// end\n\tnamespace __end {\n\t\t// Poison pill for std::end. (See the detailed discussion at\n\t\t// https://github.com/ericniebler/stl2/issues/139)\n\t\ttemplate<class T> void end(T&&) = delete;\n\n\t\ttemplate<class T>\n\t\tvoid end(std::initializer_list<T>) = delete; // See LWG 3258\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_member = std::is_lvalue_reference_v<R> &&\n\t\t\trequires(R& r) {\n\t\t\t\tr.end();\n\t\t\t\tbegin(r);\n\t\t\t\t{ __decay_copy(r.end()) } -> sentinel_for<__begin_t<R>>;\n\t\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_non_member = requires(R&& r) {\n\t\t\tend(static_cast<R&&>(r));\n\t\t\tbegin(static_cast<R&&>(r));\n\t\t\t{ __decay_copy(end(static_cast<R&&>(r))) } -> sentinel_for<__begin_t<R>>;\n\t\t};\n\n\t\ttemplate<class>\n\t\tinline constexpr bool nothrow = false;\n\t\ttemplate<has_member R>\n\t\tinline constexpr bool nothrow<R> = noexcept(std::declval<R&>().end());\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && has_non_member<R>)\n\t\tinline constexpr bool nothrow<R> = noexcept(end(std::declval<R>()));\n\n\t\tstruct __fn {\n\t\t\t// Handle builtin arrays directly\n\t\t\ttemplate<class R, std::size_t N>\n\t\t\tvoid operator()(R (&&)[N]) const = delete;\n\n\t\t\ttemplate<class R, std::size_t N>\n\t\t\tconstexpr R* operator()(R (&array)[N]) const noexcept {\n\t\t\t\treturn array + N;\n\t\t\t}\n\n\t\t\t// Handle basic_string_view directly to implement P0970 non-intrusively\n\t\t\ttemplate<class CharT, class Traits>\n\t\t\tconstexpr auto operator()(\n\t\t\t\tstd::basic_string_view<CharT, Traits> sv) const noexcept {\n\t\t\t\treturn sv.end();\n\t\t\t}\n\n\t\t\ttemplate<class R>\n\t\t\trequires has_member<R> || has_non_member<R>\n\t\t\tconstexpr auto operator()(R&& r) const noexcept(nothrow<R>) {\n\t\t\t\tif constexpr (has_member<R>)\n\t\t\t\t\treturn r.end();\n\t\t\t\telse\n\t\t\t\t\treturn end(static_cast<R&&>(r));\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __end::__fn end{};\n\t}\n\n\ttemplate<class R>\n\tusing __end_t = decltype(end(std::declval<R>()));\n\n\t// cbegin\n\tstruct __cbegin_fn {\n\t\ttemplate<class R>\n\t\tconstexpr auto operator()(R&& r) const\n\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\tbegin(__as_const(static_cast<R&&>(r)))\n\t\t)\n\t};\n\tinline namespace __cpos {\n\t\tinline constexpr __cbegin_fn cbegin{};\n\t}\n\n\t// cend\n\tstruct __cend_fn {\n\t\ttemplate<class R>\n\t\tconstexpr auto operator()(R&& r) const\n\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\tend(__as_const(static_cast<R&&>(r)))\n\t\t)\n\t};\n\tinline namespace __cpos {\n\t\tinline constexpr __cend_fn cend{};\n\t}\n\n\t// rbegin\n\tnamespace __rbegin {\n\t\t// Poison pill\n\t\ttemplate<class T> void rbegin(T&&) = delete;\n\n\t\t// Prefer member if it returns input_or_output_iterator\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_member = std::is_lvalue_reference_v<R> &&\n\t\t\trequires(R& r) {\n\t\t\t\tr.rbegin();\n\t\t\t\t{ __decay_copy(r.rbegin()) } -> input_or_output_iterator;\n\t\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_non_member = requires(R&& r) {\n\t\t\trbegin(static_cast<R&&>(r));\n\t\t\t{ __decay_copy(rbegin(static_cast<R&&>(r))) } -> input_or_output_iterator;\n\t\t};\n\n\t\t// Default to make_reverse_iterator(end(r)) for common_with ranges of\n\t\t// Bidirectional iterators.\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT can_make_reverse = requires(R&& r) {\n\t\t\t{ begin(static_cast<R&&>(r)) } -> bidirectional_iterator;\n\t\t\t{ end(static_cast<R&&>(r)) } -> same_as<__begin_t<R>>;\n\t\t};\n\n\t\ttemplate<class>\n\t\tinline constexpr bool nothrow = false;\n\t\ttemplate<has_member R>\n\t\tinline constexpr bool nothrow<R> = noexcept(std::declval<R&>().rbegin());\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && has_non_member<R>)\n\t\tinline constexpr bool nothrow<R> = noexcept(rbegin(std::declval<R>()));\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && !has_non_member<R> && can_make_reverse<R>)\n\t\tinline constexpr bool nothrow<R> =\n\t\t\tnoexcept(__stl2::make_reverse_iterator(end(std::declval<R>())));\n\n\t\tstruct __fn {\n\t\t\t// Consider the case of a hypothetical reverse_subrange whose\n\t\t\t// begin/end members pass its stored iterators through\n\t\t\t// make_reverse_iterator. Like subrange, it is only a pair of\n\t\t\t// iterators, and so rbegin/rend make sense on an rvalue\n\t\t\t// reverse_subrange.\n\t\t\ttemplate<class R>\n\t\t\trequires has_member<R> || has_non_member<R> || can_make_reverse<R>\n\t\t\tconstexpr auto operator()(R&& r) const noexcept(nothrow<R>) {\n\t\t\t\tif constexpr (has_member<R>)\n\t\t\t\t\treturn r.rbegin();\n\t\t\t\telse if constexpr (has_non_member<R>)\n\t\t\t\t\treturn rbegin(static_cast<R&&>(r));\n\t\t\t\telse\n\t\t\t\t\treturn __stl2::make_reverse_iterator(end(static_cast<R&&>(r)));\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __rbegin::__fn rbegin{};\n\t}\n\n\ttemplate<class T>\n\tusing __rbegin_t = decltype(rbegin(std::declval<T>()));\n\n\t// rend\n\tnamespace __rend {\n\t\t// Poison pill\n\t\ttemplate<class R> void rend(R&&) = delete;\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_member = std::is_lvalue_reference_v<R> &&\n\t\t\trequires(R& r) {\n\t\t\t\trbegin(r);\n\t\t\t\tr.rend();\n\t\t\t\t{ __decay_copy(r.rend()) } -> sentinel_for<__rbegin_t<R>>;\n\t\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_non_member = requires(R&& r) {\n\t\t\trbegin(static_cast<R&&>(r));\n\t\t\trend(static_cast<R&&>(r));\n\t\t\t{ __decay_copy(rend(static_cast<R&&>(r))) } ->\n\t\t\t\tsentinel_for<__rbegin_t<R>>;\n\t\t};\n\n\t\tusing __stl2::__rbegin::can_make_reverse;\n\n\t\ttemplate<class>\n\t\tinline constexpr bool nothrow = false;\n\t\ttemplate<has_member R>\n\t\tinline constexpr bool nothrow<R> = noexcept(std::declval<R&>().rend());\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && has_non_member<R>)\n\t\tinline constexpr bool nothrow<R> = noexcept(rend(std::declval<R>()));\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && !has_non_member<R> && can_make_reverse<R>)\n\t\tinline constexpr bool nothrow<R> =\n\t\t\tnoexcept(__stl2::make_reverse_iterator(begin(std::declval<R>())));\n\n\t\tstruct __fn {\n\t\t\ttemplate<class R>\n\t\t\trequires has_member<R> || has_non_member<R> || can_make_reverse<R>\n\t\t\tconstexpr auto operator()(R&& r) const noexcept(nothrow<R>) {\n\t\t\t\tif constexpr (has_member<R>)\n\t\t\t\t\treturn r.rend();\n\t\t\t\telse if constexpr (has_non_member<R>)\n\t\t\t\t\treturn rend(static_cast<R&&>(r));\n\t\t\t\telse\n\t\t\t\t\treturn __stl2::make_reverse_iterator(begin(static_cast<R&&>(r)));\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __rend::__fn rend{};\n\t}\n\n\ttemplate<class T>\n\tusing __rend_t = decltype(rend(std::declval<T>()));\n\n\t// crbegin\n\tstruct __crbegin_fn {\n\t\ttemplate<class R>\n\t\tconstexpr auto operator()(R&& r) const\n\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\trbegin(__as_const(static_cast<R&&>(r)))\n\t\t)\n\t};\n\tinline namespace __cpos {\n\t\tinline constexpr __crbegin_fn crbegin{};\n\t}\n\n\t// crend\n\tstruct __crend_fn {\n\t\ttemplate<class R>\n\t\tconstexpr auto operator()(R&& r) const\n\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\trend(__as_const(static_cast<R&&>(r)))\n\t\t)\n\t};\n\tinline namespace __cpos {\n\t\tinline constexpr __crend_fn crend{};\n\t}\n\n\t// disable_sized_range [range.sized]\n\ttemplate<class>\n\tinline constexpr bool disable_sized_range = false;\n\n\t// size [range.prim.size]\n\t// Not to spec: lvalue treatment\n\t// TODO: LWG issue\n\tnamespace __size {\n\t\t// Poison pill for std::size. (See the detailed discussion at\n\t\t// https://github.com/ericniebler/stl2/issues/139)\n\t\ttemplate<class T> void size(T&&) = delete;\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_member = !disable_sized_range<std::remove_cv_t<R>> &&\n\t\t\trequires(R& r) {\n\t\t\t\tr.size();\n\t\t\t\t{ __decay_copy(r.size()) } -> integral;\n\t\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_non_member = !disable_sized_range<std::remove_cv_t<R>> &&\n\t\t\trequires(R& r) {\n\t\t\t\tsize(r);\n\t\t\t\t{ __decay_copy(size(r)) } -> integral;\n\t\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_difference = requires(R& r) {\n\t\t\t{ begin(r) } -> forward_iterator;\n\t\t\t{ end(r) } -> sized_sentinel_for<__begin_t<R&>>;\n\t\t};\n\n\t\tstruct __fn {\n\t\tprivate:\n\t\t\ttemplate<class T>\n\t\t\tstatic constexpr /* consteval */ int __choose() noexcept {\n\t\t\t\tif constexpr (std::is_array_v<T>) {\n\t\t\t\t\treturn 0 | true;\n\t\t\t\t} else if constexpr (has_member<T>) {\n\t\t\t\t\treturn 2 | noexcept(std::declval<T&>().size());\n\t\t\t\t} else if constexpr (has_non_member<T>) {\n\t\t\t\t\treturn 4 | noexcept(size(std::declval<T&>()));\n\t\t\t\t} else if constexpr (has_difference<T>) {\n\t\t\t\t\treturn 6 | noexcept(end(std::declval<T&>()) - begin(std::declval<T&>()));\n\t\t\t\t} else {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<class T>\n\t\t\tstatic constexpr int __strategy = __choose<T>();\n\t\tpublic:\n\t\t\ttemplate<class R, class T = std::remove_reference_t<R>,\n\t\t\t\tint Choice = __strategy<T>>\n\t\t\trequires (Choice >= 0)\n\t\t\tconstexpr auto operator()(R&& r) const noexcept(Choice & 1) {\n\t\t\t\tconstexpr int Strategy = Choice / 2;\n\t\t\t\tif constexpr (Strategy == 0) {\n\t\t\t\t\treturn std::extent_v<T>;\n\t\t\t\t} else if constexpr (Strategy == 1) {\n\t\t\t\t\treturn r.size();\n\t\t\t\t} else if constexpr (Strategy == 2) {\n\t\t\t\t\treturn size(r);\n\t\t\t\t} else {\n\t\t\t\t\tstatic_assert(Strategy == 3);\n\t\t\t\t\treturn end(r) - begin(r);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __size::__fn size{};\n\t}\n\n\t// empty\n\t// Not to spec: lvalue treatment\n\t// TODO: LWG issue\n\tnamespace __empty {\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_member = requires(R& r) {\n\t\t\tr.empty();\n\t\t\tbool(r.empty());\n\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_size = requires(R& r) {\n\t\t\tsize(r);\n\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_begin_end = requires(R& r) {\n\t\t\t{ begin(r) } -> forward_iterator;\n\t\t\tend(r);\n\t\t};\n\n\t\ttemplate<class R>\n\t\tinline constexpr bool nothrow = false;\n\t\ttemplate<has_member R>\n\t\tinline constexpr bool nothrow<R> =\n\t\t\tnoexcept(bool(std::declval<R&>().empty()));\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && has_size<R>)\n\t\tinline constexpr bool nothrow<R> =\n\t\t\tnoexcept(size(std::declval<R&>()) == 0);\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && !has_size<R> && has_begin_end<R>)\n\t\tinline constexpr bool nothrow<R> =\n\t\t\tnoexcept(begin(std::declval<R&>()) == end(std::declval<R&>()));\n\n\t\tstruct __fn {\n\t\t\ttemplate<class R>\n\t\t\trequires has_member<R&> || has_size<R&> || has_begin_end<R&>\n\t\t\tconstexpr bool operator()(R&& r) const noexcept(nothrow<R&>) {\n\t\t\t\tif constexpr (has_member<R&>)\n\t\t\t\t\treturn bool(r.empty());\n\t\t\t\telse if constexpr (has_size<R&>)\n\t\t\t\t\treturn size(r) == 0;\n\t\t\t\telse // has_begin_end<R&>\n\t\t\t\t\treturn begin(r) == end(r);\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __empty::__fn empty{};\n\t}\n\n\t// data\n\t// Not to spec:\n\t// * lvalue treatment\n\t// * calls member data() for rvalue forwarding-ranges\n\t// TODO: Needs LWG issue\n\tnamespace __data {\n\t\ttemplate<class>\n\t\tinline constexpr bool is_object_ptr = false;\n\t\ttemplate<class T>\n\t\trequires std::is_object_v<T>\n\t\tinline constexpr bool is_object_ptr<T*> = true;\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT forwarding_range_hack = requires(R&& r) {\n\t\t\tend(static_cast<R&&>(r));\n\t\t};\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_member =\n\t\t\trequires(R& r) {\n\t\t\t\tr.data();\n\t\t\t\t__decay_copy(r.data());\n\t\t\t\trequires is_object_ptr<decltype(__decay_copy(r.data()))>;\n\t\t\t} &&\n\t\t\t(std::is_lvalue_reference_v<R> || forwarding_range_hack<R>);\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT has_contiguous_iterator = requires(R&& r) {\n\t\t\t{ begin(static_cast<R&&>(r)) } -> contiguous_iterator;\n\t\t\tend(static_cast<R&&>(r));\n\t\t};\n\n\t\ttemplate<class I>\n\t\tI& __idref(I) noexcept; // not defined\n\n\t\ttemplate<class>\n\t\tinline constexpr bool nothrow = false;\n\t\ttemplate<has_member R>\n\t\tinline constexpr bool nothrow<R> = noexcept(std::declval<R&>().data());\n\t\ttemplate<class R>\n\t\trequires (!has_member<R> && has_contiguous_iterator<R>)\n\t\tinline constexpr bool nothrow<R> = noexcept(\n\t\t\t*((__idref)(begin(std::declval<R&>())) == end(std::declval<R&>())\n\t\t\t\t? nullptr : (__idref)(begin(std::declval<R&>()))));\n\n\t\tstruct __fn {\n\t\t\ttemplate<class R>\n\t\t\trequires has_member<R> || has_contiguous_iterator<R>\n\t\t\tconstexpr auto operator()(R&& r) const noexcept(nothrow<R>) {\n\t\t\t\tif constexpr (has_member<R>)\n\t\t\t\t\treturn r.data();\n\t\t\t\telse { // has_contiguous_iterator<R>\n\t\t\t\t\tauto first = begin(r);\n\t\t\t\t\treturn first == end(r) ? nullptr : std::addressof(*first);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Extension: return pointer-to-mutable for string even before C++17.\n\t\t\ttemplate<class CharT, class Traits>\n\t\t\tCharT* operator()(std::basic_string<CharT, Traits>& str) const noexcept {\n\t\t\t\treturn const_cast<CharT*>(str.data());\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __data::__fn data{};\n\t}\n\n\t// cdata\n\tstruct __cdata_fn {\n\t\ttemplate<class R>\n\t\tconstexpr auto operator()(R&& r) const\n\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\tdata(__as_const(static_cast<R&&>(r)))\n\t\t)\n\t};\n\tinline namespace __cpos {\n\t\tinline constexpr __cdata_fn cdata{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/range/concepts.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_RANGE_CONCEPTS_HPP\n#define STL2_DETAIL_RANGE_CONCEPTS_HPP\n\n#include <initializer_list>\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/access.hpp>\n\nnamespace std {\n#if !defined(__GLIBCXX__) && !defined(_MSVC_STL_VERSION)\n#pragma message \"These forward declarations will only work with standard \" \\\n\t\"libraries that don't use inline namespaces for versioning.\"\n#endif\n\ttemplate<class, class, class> class set;\n\ttemplate<class, class, class> class multiset;\n\ttemplate<class, class, class, class> class unordered_set;\n\ttemplate<class, class, class, class> class unordered_multiset;\n}\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// range [ranges.range]\n\t//\n\ttemplate<class T>\n\tusing iterator_t = __begin_t<T&>;\n\n\ttemplate<class T>\n\tusing sentinel_t = __end_t<T&>;\n\n\ttemplate<class T>\n\tMETA_CONCEPT _RangeImpl =\n\t\trequires(T&& t) {\n\t\t\tbegin(static_cast<T&&>(t)); // not necessarily equality-preserving\n\t\t\tend(static_cast<T&&>(t));\n\t\t};\n\n\ttemplate<class T>\n\tMETA_CONCEPT range = _RangeImpl<T&>;\n\n\ttemplate<class T>\n\tMETA_CONCEPT _ForwardingRange = range<T> && _RangeImpl<T>;\n\n\ttemplate<class R>\n\tMETA_CONCEPT sized_range =\n\t\trange<R> &&\n#if 0 // implement PR of LWG 3264\n\t\t!disable_sized_range<__uncvref<R>> &&\n#endif\n\t\trequires(R& r) { size(r); };\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// view [ranges.view]\n\t//\n\tstruct view_base {};\n\n\ttemplate<class T>\n\tMETA_CONCEPT _ContainerLike =\n\t\trange<T> && range<const T> &&\n\t\t!same_as<iter_reference_t<iterator_t<T>>, iter_reference_t<iterator_t<const T>>>;\n\n\ttemplate<class T>\n\tMETA_CONCEPT __enable_view_default = derived_from<T, view_base> || !_ContainerLike<T>;\n\n\ttemplate<class T>\n\tinline constexpr bool enable_view = __enable_view_default<T>;\n\n\ttemplate<class T>\n\tinline constexpr bool enable_view<std::initializer_list<T>> = false;\n\ttemplate<class Key, class Compare, class Alloc>\n\tinline constexpr bool enable_view<std::set<Key, Compare, Alloc>> = false;\n\ttemplate<class Key, class Compare, class Alloc>\n\tinline constexpr bool enable_view<std::multiset<Key, Compare, Alloc>> = false;\n\ttemplate<class Key, class Hash, class Pred, class Alloc>\n\tinline constexpr bool enable_view<std::unordered_set<Key, Hash, Pred, Alloc>> = false;\n\ttemplate<class Key, class Hash, class Pred, class Alloc>\n\tinline constexpr bool enable_view<std::unordered_multiset<Key, Hash, Pred, Alloc>> = false;\n\n\ttemplate<class T>\n\tMETA_CONCEPT view =\n\t\trange<T> &&\n\t\tsemiregular<T> &&\n\t\tenable_view<__uncvref<T>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// common_range\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT common_range =\n\t\trange<T> && same_as<iterator_t<T>, sentinel_t<T>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// output_range [ranges.output]\n\t//\n\ttemplate<class R, class T>\n\tMETA_CONCEPT output_range =\n\t\trange<R> && output_iterator<iterator_t<R>, T>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// input_range [ranges.input]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT input_range =\n\t\trange<T> && input_iterator<iterator_t<T>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// forward_range [ranges.forward]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT forward_range =\n\t\tinput_range<T> && forward_iterator<iterator_t<T>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// bidirectional_range [ranges.bidirectional]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT bidirectional_range =\n\t\tforward_range<T> && bidirectional_iterator<iterator_t<T>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// random_access_range [ranges.random.access]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT random_access_range =\n\t\tbidirectional_range<T> && random_access_iterator<iterator_t<T>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// contiguous_range [ranges.contiguous]\n\t//\n\ttemplate<class R>\n\tMETA_CONCEPT contiguous_range =\n\t\trandom_access_range<R> && contiguous_iterator<iterator_t<R>> &&\n\t\trequires(R& r) {\n\t\t\t{ data(r) } -> same_as<std::add_pointer_t<iter_reference_t<iterator_t<R>>>>;\n\t\t};\n\n\tnamespace ext {\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT simple_view =\n\t\t\tview<R> && range<const R> &&\n\t\t\tsame_as<iterator_t<R>, iterator_t<const R>> &&\n\t\t\tsame_as<sentinel_t<R>, sentinel_t<const R>>;\n\t}\n\n\ttemplate<class Rng>\n\tMETA_CONCEPT viewable_range =\n#if 1 // This is the PR of https://github.com/ericniebler/stl2/issues/623\n\t\tview<__uncvref<Rng>> || _ForwardingRange<Rng>;\n#else\n\t\trange<Rng> &&\n\t\t(_RangeImpl<Rng> || view<std::decay_t<Rng>>);\n#endif\n\n\ttemplate<range R>\n\tusing range_value_t = iter_value_t<iterator_t<R>>;\n\n\ttemplate<range R>\n\tusing range_difference_t = iter_difference_t<iterator_t<R>>;\n\n\ttemplate<range R>\n\tusing range_reference_t = iter_reference_t<iterator_t<R>>;\n\n\ttemplate<range R>\n\tusing range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/range/dangling.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_RANGE_DANGLING_HPP\n#define STL2_DETAIL_RANGE_DANGLING_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t////////////////////////////////////////////////////////////////////////////\n\t// dangling [P1252]\n\t//\n\tstruct dangling {\n\t\tconstexpr dangling() noexcept = default;\n\t\ttemplate<class Arg>\n\t\tconstexpr dangling(Arg&&) noexcept {}\n\t};\n\n\ttemplate<range R>\n\tinline constexpr bool __is_forwarding_range = _ForwardingRange<R>;\n\n\ttemplate<range R, class U>\n\tusing __maybe_dangling = std::conditional_t<__is_forwarding_range<R>, U, dangling>;\n\n\ttemplate<range R>\n\tusing safe_iterator_t = __maybe_dangling<R, iterator_t<R>>;\n\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/range/nth_iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_RANGE_NTH_ITERATOR_HPP\n#define STL2_DETAIL_RANGE_NTH_ITERATOR_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/iterator/operations.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/primitives.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\tstruct __nth_iterator {\n\t\t\ttemplate<range R>\n\t\t\tconstexpr auto operator()(R&& r, iter_difference_t<iterator_t<R>> n) const\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\t\tauto const size = distance(r);\n\t\t\t\t\tconstexpr bool CommonNonRandom = common_range<R> && !random_access_range<R>;\n\t\t\t\t\tif (n >= size) {\n\t\t\t\t\t\tif constexpr (CommonNonRandom && !bidirectional_range<R>) {\n\t\t\t\t\t\t\t// If the range is RandomAccess or Bidirectional, this is just extra codegen\n\t\t\t\t\t\t\t// with no performance improvement over the following cases.\n\t\t\t\t\t\t\treturn end(r);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tn = size;\n\t\t\t\t\t}\n\t\t\t\t\tif constexpr (CommonNonRandom && bidirectional_range<R>) {\n\t\t\t\t\t\t// Again, this would not be an improvement for RandomAccess ranges.\n\t\t\t\t\t\tif (n > size / 2) {\n\t\t\t\t\t\t\treturn prev(end(r), size - n);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn next(begin(r), n);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn next(begin(r), n, end(r));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __nth_iterator nth_iterator{};\n\t} // namespace ext\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_DETAIL_RANGE_NTH_ITERATOR_HPP\n"
  },
  {
    "path": "include/stl2/detail/range/primitives.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_RANGE_PRIMITIVES_HPP\n#define STL2_DETAIL_RANGE_PRIMITIVES_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/iterator/operations.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// range primitives [range.primitives]\n//\nSTL2_OPEN_NAMESPACE {\n\t// enumerate\n\tnamespace ext {\n\t\ttemplate<class I, class C>\n\t\tstruct enumerate_result {\n\t\t\tI end;\n\t\t\tC count;\n\n\t\t\ttemplate<class I2, class C2>\n\t\t\trequires convertible_to<const I&, I2> && convertible_to<const C&, C2>\n\t\t\toperator enumerate_result<I2, C2>() const& {\n\t\t\t\treturn {end, count};\n\t\t\t}\n\t\t\ttemplate<class I2, class C2>\n\t\t\trequires convertible_to<I, I2> && convertible_to<C, C2>\n\t\t\toperator enumerate_result<I2, C2>() && {\n\t\t\t\treturn {std::move(end), std::move(count)};\n\t\t\t}\n\t\t};\n\n\t\tstruct __enumerate_fn {\n\t\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\t\t\tconstexpr enumerate_result<I, iter_difference_t<I>>\n\t\t\toperator()(I first, S last) const {\n\t\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\t\tauto d = last - first;\n\t\t\t\t\tSTL2_EXPECT(same_as<I, S> || d >= 0);\n\t\t\t\t\treturn {next(std::move(first), std::move(last)), d};\n\t\t\t\t} else if constexpr (sized_sentinel_for<I, I>) {\n\t\t\t\t\tauto end = next(first, std::move(last));\n\t\t\t\t\tauto n = end - first;\n\t\t\t\t\treturn {std::move(end), n};\n\t\t\t\t} else {\n\t\t\t\t\titer_difference_t<I> n = 0;\n\t\t\t\t\twhile (first != last) {\n\t\t\t\t\t\t++n;\n\t\t\t\t\t\t++first;\n\t\t\t\t\t}\n\t\t\t\t\treturn {std::move(first), n};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemplate<_ForwardingRange R>\n\t\t\tconstexpr enumerate_result<iterator_t<R>,\n\t\t\t\titer_difference_t<iterator_t<R>>>\n\t\t\toperator()(R&& r) const {\n\t\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\t\tusing D = iter_difference_t<iterator_t<R>>;\n\t\t\t\t\tauto n = static_cast<D>(size(r));\n\t\t\t\t\treturn {next(begin(r), end(r)), n};\n\t\t\t\t} else {\n\t\t\t\t\treturn (*this)(begin(r), end(r));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __enumerate_fn enumerate{};\n\t}\n\n\tstruct __distance_fn : private __niebloid {\n\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S>\n\t\tconstexpr iter_difference_t<I> operator()(I first, S last) const {\n\t\t\titer_difference_t<I> n = 0;\n\t\t\tif constexpr (sized_sentinel_for<S, I>) {\n\t\t\t\tn = last - first;\n\t\t\t\tSTL2_EXPECT(same_as<I, S> || n >= 0);\n\t\t\t} else if constexpr (sized_sentinel_for<I, I>) {\n\t\t\t\tauto end = next(first, std::move(last));\n\t\t\t\tn = end - first;\n\t\t\t} else {\n\t\t\t\tfor (; first != last; ++first) {\n\t\t\t\t\t++n;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n;\n\t\t}\n\n\t\ttemplate<range R>\n\t\tconstexpr iter_difference_t<iterator_t<R>> operator()(R&& r) const {\n\t\t\titer_difference_t<iterator_t<R>> n = 0;\n\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\tn = static_cast<iter_difference_t<iterator_t<R>>>(size(r));\n\t\t\t} else {\n\t\t\t\tn = (*this)(begin(r), end(r));\n\t\t\t}\n\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\treturn n;\n\t\t}\n\t};\n\n\tinline constexpr __distance_fn distance{};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/raw_ptr.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_RAW_PTR_HPP\n#define STL2_DETAIL_RAW_PTR_HPP\n\n#include <stl2/detail/fwd.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<class T>\n\t\tclass raw_ptr {\n\t\tpublic:\n#ifdef NDEBUG\n\t\t\traw_ptr() = default;\n#else\n\t\t\tconstexpr raw_ptr() noexcept\n\t\t\t: raw_ptr(nullptr) {}\n#endif\n\n\t\t\tconstexpr raw_ptr(T* ptr) noexcept\n\t\t\t: ptr_{ptr} {}\n\n\t\t\tconstexpr raw_ptr& operator=(T* ptr) & noexcept {\n\t\t\t\tptr_ = ptr;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr operator T*() const noexcept {\n\t\t\t\treturn ptr_;\n\t\t\t}\n\n\t\t\tconstexpr T& operator*() const noexcept {\n\t\t\t\tSTL2_EXPECT(ptr_);\n\t\t\t\treturn *ptr_;\n\t\t\t}\n\n\t\t\tconstexpr T* operator->() const noexcept {\n\t\t\t\tSTL2_EXPECT(ptr_);\n\t\t\t\treturn ptr_;\n\t\t\t}\n\t\tprivate:\n\t\t\tT* ptr_;\n\t\t};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/semiregular_box.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_SEMIREGULAR_BOX_HPP\n#define STL2_DETAIL_SEMIREGULAR_BOX_HPP\n\n#include <optional>\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\t// If T models move_constructible, semiregular_box<T> models movable &&\n\t\t// default_initializable (so-called \"move_semiregular\"). If T models\n\t\t// copy_constructible, semiregular_box<T> models semiregular.\n\t\ttemplate<ext::move_constructible_object T>\n\t\tstruct semiregular_box {\n#if STL2_WORKAROUND_MSVC_106654\n\t\t\t// Not a proper workaround since semiregular_box<T> should be\n\t\t\t// trivially default constructible when T is.\n\t\t\tconstexpr semiregular_box()\n\t\t\tnoexcept(!constructible_from<T> || std::is_nothrow_default_constructible_v<T>) {\n\t\t\t\tif constexpr (constructible_from<T>) {\n\t\t\t\t\to_.emplace();\n\t\t\t\t}\n\t\t\t}\n#else // ^^^ workaround / no workaround vvv\n\t\t\tsemiregular_box() = default;\n\t\t\tconstexpr semiregular_box()\n\t\t\tnoexcept(std::is_nothrow_default_constructible_v<T>)\n\t\t\trequires constructible_from<T>\n\t\t\t: o_{std::in_place} {}\n#endif // STL2_WORKAROUND_MSVC_106654\n\n\t\t\ttemplate<_NotSameAs<semiregular_box> U>\n\t\t\trequires convertible_to<U, T>\n\t\t\tconstexpr semiregular_box(U&& u)\n\t\t\tnoexcept(std::is_nothrow_constructible_v<T, U>)\n\t\t\t: o_{std::in_place, static_cast<U&&>(u)} {}\n\n\t\t\ttemplate<class... Args>\n\t\t\trequires constructible_from<T, Args...>\n\t\t\tconstexpr semiregular_box(std::in_place_t, Args&&... args)\n\t\t\tnoexcept(std::is_nothrow_constructible_v<T, Args...>)\n\t\t\t: o_{std::in_place, static_cast<Args&&>(args)...} {}\n\n\t\t\tsemiregular_box(const semiregular_box&) requires copy_constructible<T> = default;\n\t\t\tsemiregular_box(semiregular_box&&) = default;\n\n#if STL2_WORKAROUND_MSVC_106654\n\t\t\t// Not a proper workaround since semiregular_box<T> should be\n\t\t\t// trivially copy assignable when T is.\n\t\t\tconstexpr semiregular_box& operator=(const semiregular_box& that) &\n\t\t\tnoexcept(std::is_nothrow_copy_constructible_v<T> &&\n\t\t\t\t(std::is_nothrow_copy_assignable_v<T> || !copyable<T>))\n\t\t\trequires copy_constructible<T> {\n\t\t\t\tif constexpr (copyable<T>) {\n\t\t\t\t\to_ = that.o_;\n\t\t\t\t} else {\n\t\t\t\t\to_.reset();\n\t\t\t\t\tif (that.o_) {\n\t\t\t\t\t\to_.emplace(*that.o_);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n#else // ^^^ workaround / no workaround vvv\n\t\t\tconstexpr semiregular_box& operator=(const semiregular_box& that) &\n\t\t\tnoexcept(std::is_nothrow_copy_constructible_v<T>)\n\t\t\trequires copy_constructible<T> {\n\t\t\t\to_.reset();\n\t\t\t\tif (that.o_) {\n\t\t\t\t\to_.emplace(*that.o_);\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tsemiregular_box& operator=(const semiregular_box&) & requires copyable<T> = default;\n#endif // STL2_WORKAROUND_MSVC_106654\n\n#if STL2_WORKAROUND_MSVC_106654\n\t\t\t// Not a proper workaround since semiregular_box<T> should be\n\t\t\t// trivially move assignable when T is.\n\t\t\tconstexpr semiregular_box& operator=(semiregular_box&& that) &\n\t\t\tnoexcept(std::is_nothrow_move_constructible_v<T> &&\n\t\t\t\t(std::is_nothrow_move_assignable_v<T> || !movable<T>))\n\t\t\trequires move_constructible<T> {\n\t\t\t\tif constexpr (movable<T>) {\n\t\t\t\t\to_ = std::move(that.o_);\n\t\t\t\t} else {\n\t\t\t\t\to_.reset();\n\t\t\t\t\tif (that.o_) {\n\t\t\t\t\t\to_.emplace(std::move(*that.o_));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n#else // ^^^ workaround / no workaround vvv\n\t\t\tconstexpr semiregular_box& operator=(semiregular_box&& that) &\n\t\t\tnoexcept(std::is_nothrow_move_constructible_v<T>) {\n\t\t\t\to_.reset();\n\t\t\t\tif (that.o_) {\n\t\t\t\t\to_.emplace(static_cast<T&&>(*that.o_));\n\t\t\t\t}\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tsemiregular_box& operator=(semiregular_box&&) & requires movable<T> = default;\n#endif // STL2_WORKAROUND_MSVC_106654\n\n\t\t\tconstexpr semiregular_box& operator=(T&& t) &\n\t\t\tnoexcept(std::is_nothrow_move_constructible_v<T>) {\n\t\t\t\to_.emplace(static_cast<T&&>(t));\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tconstexpr semiregular_box& operator=(T&& t) &\n\t\t\tnoexcept(std::is_nothrow_move_constructible_v<T> &&\n\t\t\t\tstd::is_nothrow_move_assignable_v<T>)\n\t\t\trequires movable<T> {\n\t\t\t\to_ = static_cast<T&&>(t);\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr semiregular_box& operator=(const T& t) &\n\t\t\tnoexcept(std::is_nothrow_copy_constructible_v<T>)\n\t\t\trequires copy_constructible<T> {\n\t\t\t\to_.emplace(t);\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tconstexpr semiregular_box& operator=(const T& t) &\n\t\t\tnoexcept(std::is_nothrow_copy_constructible_v<T> &&\n\t\t\t\tstd::is_nothrow_copy_assignable_v<T>)\n\t\t\trequires copyable<T> {\n\t\t\t\to_ = t;\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\tconstexpr T& get() & noexcept {\n\t\t\t\tSTL2_EXPECT(o_);\n\t\t\t\treturn *o_;\n\t\t\t}\n\t\t\tconstexpr const T& get() const& noexcept {\n\t\t\t\tSTL2_EXPECT(o_);\n\t\t\t\treturn *o_;\n\t\t\t}\n\t\t\tconstexpr T&& get() && noexcept {\n\t\t\t\tSTL2_EXPECT(o_);\n\t\t\t\treturn static_cast<T&&>(*o_);\n\t\t\t}\n\t\t\tconstexpr const T&& get() const&& noexcept {\n\t\t\t\tSTL2_EXPECT(o_);\n\t\t\t\treturn static_cast<const T&&>(*o_);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tstd::optional<T> o_;\n\t\t};\n\n\t\ttemplate<semiregular T>\n\t\trequires ext::object<T>\n\t\tstruct semiregular_box<T> : ebo_box<T, semiregular_box<T>> {\n\t\t\tusing semiregular_box::ebo_box::ebo_box;\n\n\t\t\ttemplate<class... Args>\n\t\t\trequires constructible_from<T, Args...>\n\t\t\tconstexpr semiregular_box(std::in_place_t, Args&&... args)\n\t\t\tnoexcept(std::is_nothrow_constructible_v<T, Args...>)\n\t\t\t: semiregular_box::ebo_box{static_cast<Args&&>(args)...} {}\n\t\t};\n\n\t\ttemplate<class T>\n\t\tsemiregular_box(T) -> semiregular_box<T>;\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/span.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_SPAN_HPP\n#define STL2_DETAIL_SPAN_HPP\n\n#include <cstddef>\n#include <array>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/algorithm/equal.hpp>\n#include <stl2/detail/algorithm/lexicographical_compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/iterator/reverse_iterator.hpp>\n\n///////////////////////////////////////////////////////////////////////////\n// Implementation of P0122 span\n// Not to spec: many things (hence the extension namespace). This is a\n// \"How should span better fit into the Ranges design\" experiment.\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<class T>\n\t\tusing data_pointer_t = decltype(data(std::declval<T&>()));\n\n\t\ttemplate<class range>\n\t\tMETA_CONCEPT SizedContiguousRange =\n\t\t\tcontiguous_range<range> && sized_range<range>;\n\n\t\tnamespace __span {\n\t\t\tusing index_t = std::ptrdiff_t;\n\t\t}\n\n\t\tinline constexpr auto dynamic_extent = static_cast<__span::index_t>(-1);\n\n\t\ttemplate<ext::object ElementType, __span::index_t Extent = dynamic_extent>\n\t\trequires (Extent >= dynamic_extent)\n\t\tstruct span;\n\n\t\tnamespace __span {\n\t\t\ttemplate<index_t Extent>\n\t\t\trequires (Extent >= dynamic_extent)\n\t\t\tstruct extent {\n\t\t\t\tconstexpr extent() noexcept = default;\n\t\t\t\tconstexpr extent(index_t size) noexcept\n\t\t\t\t{\n\t\t\t\t\tSTL2_EXPECT(size == Extent);\n\t\t\t\t}\n\t\t\t\tconstexpr index_t size() const noexcept { return Extent; }\n\t\t\t};\n\t\t\ttemplate<>\n\t\t\tstruct extent<dynamic_extent> {\n\t\t\t\tconstexpr extent() noexcept = default;\n\t\t\t\tconstexpr extent(index_t size) noexcept\n\t\t\t\t: size_{size}\n\t\t\t\t{\n\t\t\t\t\tSTL2_EXPECT(size >= 0);\n\t\t\t\t}\n\t\t\t\tconstexpr index_t size() const noexcept { return size_; }\n\t\t\tprivate:\n\t\t\t\tindex_t size_ = 0;\n\t\t\t};\n\n\t\t\ttemplate<class> struct static_extent_ {};\n\t\t\ttemplate<class T, std::size_t Extent>\n\t\t\tstruct static_extent_<T[Extent]>\n\t\t\t: std::integral_constant<index_t, static_cast<index_t>(Extent)>\n\t\t\t{};\n\t\t\ttemplate<class T, std::size_t Extent>\n\t\t\tstruct static_extent_<std::array<T, Extent>>\n\t\t\t: std::integral_constant<index_t, static_cast<index_t>(Extent)>\n\t\t\t{};\n\t\t\ttemplate<class T, index_t Extent>\n\t\t\tstruct static_extent_<span<T, Extent>>\n\t\t\t: std::integral_constant<index_t, Extent>\n\t\t\t{};\n\t\t\ttemplate<class T>\n\t\t\tstruct static_extent_<span<T>>\n\t\t\t{};\n\t\t\ttemplate<class T>\n\t\t\tusing static_extent = static_extent_<__uncvref<T>>;\n\n\t\t\ttemplate<class>\n\t\t\tconstexpr bool has_static_extent = false;\n\t\t\ttemplate<class T>\n\t\t\trequires requires { static_extent<T>::value; }\n\t\t\tconstexpr bool has_static_extent<T> = true;\n\n\t\t\ttemplate<class range>\n\t\t\tMETA_CONCEPT StaticSizedContiguousRange =\n\t\t\t\tSizedContiguousRange<range> && has_static_extent<range>;\n\n\t\t\ttemplate<class range, class ElementType>\n\t\t\tMETA_CONCEPT compatible = SizedContiguousRange<range> &&\n\t\t\t\tconvertible_to<\n\t\t\t\t\tstd::remove_pointer_t<data_pointer_t<range>>(*)[],\n\t\t\t\t\tElementType(*)[]>;\n\n\t\t\ttemplate<integral To, integral From>\n\t\t\tconstexpr To narrow_cast(From from) noexcept {\n\t\t\t\tusing C = common_type_t<To, From>;\n\t\t\t\tauto to = static_cast<To>(from);\n\t\t\t\tSTL2_EXPECT((from > 0) == (to > 0));\n\t\t\t\tSTL2_EXPECT(static_cast<C>(from) == static_cast<C>(to));\n\t\t\t\treturn to;\n\t\t\t}\n\n\t\t\ttemplate<class T>\n\t\t\tconstexpr index_t byte_extent(index_t count) noexcept\n\t\t\t{\n\t\t\t\tif (count < 0) {\n\t\t\t\t\treturn dynamic_extent;\n\t\t\t\t}\n\t\t\t\tSTL2_EXPECT(__span::narrow_cast<std::size_t>(count) <= PTRDIFF_MAX / sizeof(T));\n\t\t\t\treturn count * __span::narrow_cast<index_t>(sizeof(T));\n\t\t\t}\n\t\t} // namespace __span\n\n\t\t// [span], class template span\n\t\ttemplate<ext::object ElementType, __span::index_t Extent>\n\t\trequires (Extent >= dynamic_extent)\n\t\tstruct span : private __span::extent<Extent> {\n\t\t\t// constants and types\n\t\t\tusing element_type = ElementType;\n\t\t\tusing value_type = std::remove_cv_t<ElementType>;\n\t\t\tusing difference_type = __span::index_t;\n\t\t\tusing index_type = difference_type;\n\t\t\tusing pointer = element_type*;\n\t\t\tusing reference = element_type&;\n\t\t\tusing iterator = pointer;\n\t\t\tusing reverse_iterator = __stl2::reverse_iterator<iterator>;\n\n\t\t\tstatic constexpr index_type extent = Extent;\n\n\t\t\t// [span.cons], span constructors\n\t\t\tconstexpr span() noexcept = default;\n\t\t\tconstexpr span(pointer ptr, index_type count) noexcept\n\t\t\t: __span::extent<Extent>{count}, data_{ptr}\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(count == 0 || ptr != nullptr);\n\t\t\t}\n\t\t\tconstexpr span(pointer first, pointer last) noexcept\n\t\t\t: span{first, last - first}\n\t\t\t{}\n\n\t\t\t// FIXME: accept forwarding-range?\n\t\t\ttemplate<__span::compatible<ElementType> range>\n\t\t\trequires (Extent == __span::static_extent<range>::value)\n\t\t\tconstexpr span(range&& rng)\n\t\t\tnoexcept(noexcept(__stl2::data(rng)))\n\t\t\t: span{__stl2::data(rng), Extent}\n\t\t\t{}\n\n\t\t\t// FIXME: accept forwarding-range?\n\t\t\ttemplate<__span::compatible<ElementType> range>\n\t\t\trequires (Extent == dynamic_extent || !__span::has_static_extent<range>)\n\t\t\tconstexpr span(range&& rng)\n\t\t\tnoexcept(noexcept(__stl2::data(rng), __stl2::size(rng)))\n\t\t\t: span{__stl2::data(rng), __span::narrow_cast<index_type>(__stl2::size(rng))}\n\t\t\t{}\n\n\t\t\t// [span.sub], span subviews\n\t\t\ttemplate<index_type Count>\n\t\t\tconstexpr span<element_type, Count> first() const noexcept\n\t\t\t{\n\t\t\t\tstatic_assert(Count >= 0,\n\t\t\t\t\t\"Count of elements to extract cannot be negative.\");\n\t\t\t\tstatic_assert(Extent == dynamic_extent || Count <= Extent,\n\t\t\t\t\t\"Count of elements to extract must be less than the static span extent.\");\n\t\t\t\tSTL2_EXPECT(size() >= Count);\n\t\t\t\tSTL2_EXPECT(Count == 0 || data_ != nullptr);\n\t\t\t\treturn {data_, Count};\n\t\t\t}\n\t\t\tconstexpr span<element_type> first(index_type count) const noexcept\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(count >= 0);\n\t\t\t\tSTL2_EXPECT(size() >= count);\n\t\t\t\tSTL2_EXPECT(count == 0 || data_ != nullptr);\n\t\t\t\treturn {data_, count};\n\t\t\t}\n\n\t\t\ttemplate<index_type Count>\n\t\t\tconstexpr span<element_type, Count> last() const noexcept\n\t\t\t{\n\t\t\t\tstatic_assert(Count >= 0,\n\t\t\t\t\t\"Count of elements to extract cannot be negative.\");\n\t\t\t\tstatic_assert(Extent == dynamic_extent || Count <= Extent,\n\t\t\t\t\t\"Count of elements to extract must be less than the static span extent.\");\n\t\t\t\tSTL2_EXPECT(size() >= Count);\n\t\t\t\tSTL2_EXPECT((Count == 0 && size() == 0) || data_ != nullptr);\n\t\t\t\treturn {data_ + size() - Count, Count};\n\t\t\t}\n\t\t\tconstexpr span<element_type> last(index_type count) const noexcept\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(count >= 0);\n\t\t\t\tSTL2_EXPECT(size() >= count);\n\t\t\t\tSTL2_EXPECT((count == 0 && size() == 0) || data_ != nullptr);\n\t\t\t\treturn {data_ + size() - count, count};\n\t\t\t}\n\n\t\t\ttemplate<index_type Offset, index_type Count>\n\t\t\tconstexpr span<element_type, Count> subspan() const noexcept\n\t\t\t{\n\t\t\t\tstatic_assert(Offset >= 0,\n\t\t\t\t\t\"Offset of first element to extract cannot be negative.\");\n\t\t\t\tstatic_assert(Count >= 0,\n\t\t\t\t\t\"Count of elements to extract cannot be negative.\");\n\t\t\t\tstatic_assert(Extent == dynamic_extent || Extent >= Offset + Count,\n\t\t\t\t\t\"Sequence of elements to extract must be within the static span extent.\");\n\t\t\t\tSTL2_EXPECT(size() >= Offset + Count);\n\t\t\t\tSTL2_EXPECT((Offset == 0 && Count == 0) || data_ != nullptr);\n\t\t\t\treturn {data_ + Offset, Count};\n\t\t\t}\n\t\t\ttemplate<index_type Offset>\n\t\t\trequires (Offset >= 0 && (Extent == dynamic_extent || Extent >= Offset))\n\t\t\tconstexpr span<element_type, Extent >= Offset ? Extent - Offset : dynamic_extent> subspan() const noexcept\n\t\t\t{\n\t\t\t\tstatic_assert(Offset >= 0,\n\t\t\t\t\t\"Offset of first element to extract cannot be negative.\");\n\t\t\t\tstatic_assert(Extent == dynamic_extent || Offset <= Extent,\n\t\t\t\t\t\"Offset of first element to extract must be less than the static span extent.\");\n\t\t\t\tSTL2_EXPECT(size() >= Offset);\n\t\t\t\tSTL2_EXPECT((Offset == 0 && size() == 0) || data_ != nullptr);\n\t\t\t\treturn {data_ + Offset, size() - Offset};\n\t\t\t}\n\t\t\tconstexpr span<element_type, dynamic_extent> subspan(index_type offset) const noexcept\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(offset >= 0);\n\t\t\t\tSTL2_EXPECT(size() >= offset);\n\t\t\t\tSTL2_EXPECT((offset == 0 && size() == 0) || data_ != nullptr);\n\t\t\t\treturn {data_ + offset, size() - offset};\n\t\t\t}\n\t\t\tconstexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count) const noexcept\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(offset >= 0);\n\t\t\t\tSTL2_EXPECT(count >= 0);\n\t\t\t\tSTL2_EXPECT(size() >= offset + count);\n\t\t\t\tSTL2_EXPECT((offset == 0 && count == 0) || data_ != nullptr);\n\t\t\t\treturn {data_ + offset, count};\n\t\t\t}\n\n\t\t\t// [span.obs], span observers\n\t\t\tusing __span::extent<Extent>::size;\n\t\t\tconstexpr index_type size_bytes() const noexcept\n\t\t\t{\n\t\t\t\treturn __span::byte_extent<ElementType>(size());\n\t\t\t}\n\t\t\tconstexpr bool empty() const noexcept { return size() == 0; }\n\n\t\t\t// [span.elem], span element access\n\t\t\tconstexpr reference operator[](index_type idx) const noexcept\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(idx >= 0);\n\t\t\t\tSTL2_EXPECT(idx < size());\n\t\t\t\tSTL2_EXPECT(data_);\n\t\t\t\treturn data_[idx];\n\t\t\t}\n\t\t\tconstexpr pointer data() const noexcept { return data_; }\n\n\t\t\t// [span.iter], span iterator support\n\t\t\tconstexpr iterator begin() const noexcept { return data_; }\n\t\t\tconstexpr iterator end() const noexcept {\n\t\t\t\tSTL2_EXPECT(!size() || data_);\n\t\t\t\treturn data_ + size();\n\t\t\t}\n\t\t\tconstexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; }\n\t\t\tconstexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; }\n\n\t\t\t// Extension for P0970\n\t\t\tfriend constexpr iterator begin(span s) noexcept { return s.begin(); }\n\t\t\tfriend constexpr iterator end(span s) noexcept { return s.end(); }\n\n\t\t\t// [span.comparison], span comparison operators\n\t\t\ttemplate<equality_comparable_with<ElementType> U, index_type UExtent>\n\t\t\tbool operator==(span<U, UExtent> that) const\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(!size() || data());\n\t\t\t\tSTL2_EXPECT(!that.size() || that.data());\n\t\t\t\treturn equal(*this, that);\n\t\t\t}\n\t\t\ttemplate<equality_comparable_with<ElementType> U, index_type UExtent>\n\t\t\tbool operator!=(span<U, UExtent> that) const\n\t\t\t{\n\t\t\t\treturn !(*this == that);\n\t\t\t}\n\t\t\ttemplate<totally_ordered_with<ElementType> U, index_type UExtent>\n\t\t\tbool operator<(span<U, UExtent> that) const\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(!size() || data());\n\t\t\t\tSTL2_EXPECT(!that.size() || that.data());\n\t\t\t\treturn lexicographical_compare(*this, that);\n\t\t\t}\n\t\t\ttemplate<totally_ordered_with<ElementType> U, index_type UExtent>\n\t\t\tbool operator>(span<U, UExtent> that)\n\t\t\t{\n\t\t\t\treturn that < *this;\n\t\t\t}\n\t\t\ttemplate<totally_ordered_with<ElementType> U, index_type UExtent>\n\t\t\tbool operator<=(span<U, UExtent> that)\n\t\t\t{\n\t\t\t\treturn !(that < *this);\n\t\t\t}\n\t\t\ttemplate<totally_ordered_with<ElementType> U, index_type UExtent>\n\t\t\tbool operator>=(span<U, UExtent> that)\n\t\t\t{\n\t\t\t\treturn !(*this < that);\n\t\t\t}\n\n\t\tprivate:\n\t\t\tElementType* data_ = nullptr;\n\t\t};\n\n#ifdef __cpp_deduction_guides\n\t\ttemplate<SizedContiguousRange Rng>\n\t\tspan(Rng&& rng) -> span<std::remove_pointer_t<data_pointer_t<Rng>>>;\n\n\t\ttemplate<__span::StaticSizedContiguousRange Rng>\n\t\tspan(Rng&& rng) -> span<std::remove_pointer_t<data_pointer_t<Rng>>,\n\t\t\t__span::static_extent<Rng>::value>;\n#endif\n\n\t\t// [span.objectrep], views of object representation\n\t\ttemplate<class ElementType, __span::index_t Extent>\n\t\tspan<const unsigned char, __span::byte_extent<ElementType>(Extent)>\n\t\tas_bytes(span<ElementType, Extent> s) noexcept\n\t\t{\n\t\t\treturn {reinterpret_cast<const unsigned char*>(s.data()), s.size_bytes()};\n\t\t}\n\t\ttemplate<class ElementType, __span::index_t Extent>\n\t\tspan<unsigned char, __span::byte_extent<ElementType>(Extent)>\n\t\tas_writeable_bytes(span<ElementType, Extent> s) noexcept\n\t\t{\n\t\t\treturn {reinterpret_cast<unsigned char*>(s.data()), s.size_bytes()};\n\t\t}\n\n\t\ttemplate<class ElementType>\n\t\tconstexpr auto make_span(ElementType* ptr, __span::index_t count) noexcept\n\t\t{\n\t\t\treturn span<ElementType>{ptr, count};\n\t\t}\n\t\ttemplate<class ElementType>\n\t\tconstexpr auto make_span(ElementType* first, ElementType* last) noexcept\n\t\t{\n\t\t\treturn span<ElementType>{first, last};\n\t\t}\n\t\t// FIXME: accept forwarding-range?\n\t\ttemplate<SizedContiguousRange Rng>\n\t\tconstexpr auto make_span(Rng&& rng)\n\t\tnoexcept(noexcept(data(rng), size(rng)))\n\t\t{\n\t\t\tusing S = span<std::remove_pointer_t<data_pointer_t<Rng>>>;\n\t\t\treturn S{data(rng), __span::narrow_cast<__span::index_t>(size(rng))};\n\t\t}\n\t\t// FIXME: accept forwarding-range?\n\t\ttemplate<__span::StaticSizedContiguousRange Rng>\n\t\tconstexpr auto make_span(Rng&& rng)\n\t\tnoexcept(noexcept(data(rng)))\n\t\t{\n\t\t\tusing S = span<std::remove_pointer_t<data_pointer_t<Rng>>,\n\t\t\t\t__span::static_extent<Rng>::value>;\n\t\t\treturn S{data(rng), __span::static_extent<Rng>::value};\n\t\t}\n\t} // namespace ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/swap.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_SWAP_HPP\n#define STL2_DETAIL_SWAP_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object/assignable.hpp>\n#include <stl2/detail/concepts/object/move_constructible.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// exchange [utility.exchange]\n\t// Not to spec: this wasn't proposed for C++20, but I'm keeping it around\n\t// until the libraries we want to support implement constexpr std::exchange.\n\ttemplate<class T, class U = T>\n\trequires move_constructible<T> && assignable_from<T&, U>\n\tconstexpr T exchange(T& t, U&& u)\n\tnoexcept(std::is_nothrow_move_constructible<T>::value &&\n\t\tstd::is_nothrow_assignable<T&, U>::value)\n\t{\n\t\tT tmp(std::move(t));\n\t\tt = std::forward<U>(u);\n\t\treturn tmp;\n\t}\n\n\tnamespace detail {\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT has_class_or_enum_type =\n#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)\n\t\t\t__is_class(__uncvref<T>) ||\n\t\t\t__is_enum(__uncvref<T>) ||\n\t\t\t__is_union(__uncvref<T>);\n#else // ^^^ Use intrinsics / use type traits vvv\n\t\t\tstd::is_class_v<__uncvref<T>> ||\n\t\t\tstd::is_enum_v<__uncvref<T>> ||\n\t\t\tstd::is_union_v<__uncvref<T>>;\n#endif // intrinsics vs. traits\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// swap [utility.swap]\n\t//\n\tnamespace __swap {\n\t\t// https://wg21.link/lwg2152\n\t\t// https://wg21.link/lwg2171\n\n\t\t// Poison pill for std::swap. If ADL for \"swap\" finds std::swap and\n\t\t// unqualified name lookup finds this overload, the ambiguity causes\n\t\t// overload resolution to fail. If ADL doesn't find any declarations\n\t\t// of \"swap\", this deleted overload directly prevents unqualified\n\t\t// name lookup from searching further up the namespace hierarchy and\n\t\t// finding std::swap. (See the detailed discussion at\n\t\t// https://github.com/ericniebler/stl2/issues/139)\n\t\ttemplate<class T> void swap(T&, T&) = delete;\n\n#if STL2_WORKAROUND_MSVC_895622\n\t\tvoid swap();\n#endif // STL2_WORKAROUND_MSVC_895622\n\n\t\ttemplate<class T, class U>\n\t\tMETA_CONCEPT has_customization =\n\t\t\t(detail::has_class_or_enum_type<T> ||\n\t\t\t detail::has_class_or_enum_type<U>) &&\n\t\t\trequires(T&& t, U&& u) {\n\t\t\t\tswap(static_cast<T&&>(t), static_cast<U&&>(u));\n\t\t\t};\n\n\t\ttemplate<class F, class T, class U>\n\t\tMETA_CONCEPT has_operator = requires(const F& f, T& t, U& u) {\n\t\t\tf(t, u);\n\t\t};\n\n\t\tstruct fn {\n\t\t\ttemplate<class T, class U>\n\t\t\trequires has_customization<T, U>\n\t\t\tconstexpr void operator()(T&& t, U&& u) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)swap(std::forward<T>(t), std::forward<U>(u))\n\t\t\t)\n\t\t\ttemplate<class T>\n\t\t\trequires (!has_customization<T&, T&> && move_constructible<T>\n\t\t\t\t&& assignable_from<T&, T&&>)\n\t\t\tconstexpr void operator()(T& a, T& b) const\n\t\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t\t(void)(b = __stl2::exchange(a, std::move(b)))\n\t\t\t)\n\t\t\ttemplate<class T, class U, std::size_t N, class F = fn>\n\t\t\trequires has_operator<F, T, U>\n\t\t\tconstexpr void operator()(T (&t)[N], U (&u)[N]) const\n\t\t\tnoexcept(noexcept(std::declval<const F&>()(t[0], u[0]))) {\n\t\t\t\tfor (std::size_t i = 0; i < N; ++i) {\n\t\t\t\t\t(*this)(t[i], u[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\tinline namespace __cpos {\n\t\tinline constexpr __swap::fn swap{};\n\t}\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// swappable [concepts.lib.corelang.swappable]\n\t//\n\ttemplate<class T>\n\tMETA_CONCEPT swappable =\n\t\trequires(T& a, T& b) {\n\t\t\t__stl2::swap(a, b);\n\t\t};\n\n\ttemplate<class T, class U>\n\tMETA_CONCEPT swappable_with =\n#if 1 // P/R of LWG 3175\n\t\tcommon_reference_with<T, U> &&\n#else\n\t\tcommon_reference_with<\n\t\t\tconst remove_reference_t<T>&,\n\t\t\tconst remove_reference_t<U>&> &&\n#endif\n\t\trequires(T&& t, U&& u) {\n\t\t\t__stl2::swap((T&&)t, (T&&)t);\n\t\t\t__stl2::swap((U&&)u, (U&&)u);\n\t\t\t__stl2::swap((T&&)t, (U&&)u);\n\t\t\t__stl2::swap((U&&)u, (T&&)t);\n\t\t};\n\n\tnamespace ext {\n\t\ttemplate<class T, class U>\n\t\tinline constexpr bool is_nothrow_swappable_v = false;\n\n\t\ttemplate<class T, swappable_with<T> U>\n\t\tinline constexpr bool is_nothrow_swappable_v<T, U> =\n\t\t\tnoexcept(__stl2::swap(std::declval<T>(), std::declval<U>())) &&\n\t\t\tnoexcept(__stl2::swap(std::declval<U>(), std::declval<T>()));\n\n\t\ttemplate<class T, class U>\n\t\tstruct is_nothrow_swappable :\n\t\t\tmeta::bool_<is_nothrow_swappable_v<T, U>> {};\n\t}\n\n\tnamespace detail {\n\t\ttemplate<class Derived>\n\t\trequires std::is_class_v<Derived>\n\t\tstruct __member_swap {\n\t\tprivate:\n\t\t\tconstexpr Derived& derived() noexcept {\n\t\t\t\treturn static_cast<Derived&>(*this);\n\t\t\t}\n\t\tpublic:\n\t\t\tfriend constexpr void swap(__member_swap& x, __member_swap& y)\n\t\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\t\t(void) x.derived().swap(y.derived())\n\t\t\t)\n\t\t};\n\t}\n\tusing detail::__member_swap;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/temporary_vector.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_TEMPORARY_VECTOR_HPP\n#define STL2_DETAIL_TEMPORARY_VECTOR_HPP\n\n#include <memory>\n#include <stl2/type_traits.hpp>\n#include <stl2/utility.hpp>\n#include <stl2/detail/construct_destruct.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/algorithm/for_each.hpp>\n#include <stl2/detail/concepts/object.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct temporary_buffer_deleter {\n\t\t\ttemplate<class T>\n\t\t\tvoid operator()(T* ptr) const {\n\t\t\t\tstd::return_temporary_buffer(ptr);\n\t\t\t}\n\t\t};\n\n\t\ttemplate<class T>\n\t\tclass temporary_buffer {\n\t\t\tstd::unique_ptr<T, temporary_buffer_deleter> alloc_;\n\t\t\tstd::ptrdiff_t size_ = 0;\n\n\t\t\ttemporary_buffer(std::pair<T*, std::ptrdiff_t> buf)\n\t\t\t: alloc_{buf.first}, size_{buf.second} {}\n\n\t\tpublic:\n\t\t\ttemporary_buffer() = default;\n\t\t\ttemporary_buffer(std::ptrdiff_t n)\n\t\t\t: temporary_buffer(std::get_temporary_buffer<T>(n)) {}\n\n\t\t\tT* data() const {\n\t\t\t\treturn alloc_.get();\n\t\t\t}\n\n\t\t\tstd::ptrdiff_t size() const {\n\t\t\t\treturn size_;\n\t\t\t}\n\t\t};\n\n\t\ttemplate<class T>\n\t\trequires (alignof(T) > alignof(std::max_align_t))\n\t\tclass temporary_buffer<T> {\n\t\t\tstd::unique_ptr<unsigned char, temporary_buffer_deleter> alloc_;\n\t\t\tT* aligned_ = nullptr;\n\t\t\tstd::ptrdiff_t size_ = 0;\n\n\t\t\tstatic_assert((alignof(T) & (alignof(T) - 1)) == 0,\n\t\t\t\t\"Alignment must be a power of two.\");\n\n\t\t\ttemporary_buffer(std::pair<unsigned char*, std::ptrdiff_t> buf)\n\t\t\t: alloc_{buf.first}\n\t\t\t{\n\t\t\t\tif (buf.second > 0 && static_cast<std::size_t>(buf.second) >= sizeof(T)) {\n\t\t\t\t\tvoid* ptr = buf.first;\n\t\t\t\t\tstd::size_t n = buf.second;\n\t\t\t\t\taligned_ = static_cast<T*>(std::align(alignof(T), sizeof(T), ptr, n));\n\t\t\t\t\tif (aligned_) {\n\t\t\t\t\t\tsize_ = n / sizeof(T);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tpublic:\n\t\t\ttemporary_buffer() = default;\n\t\t\ttemporary_buffer(std::ptrdiff_t n)\n\t\t\t: temporary_buffer(std::get_temporary_buffer<unsigned char>(\n\t\t\t\tn * sizeof(T) + alignof(T) - 1))\n\t\t\t{}\n\n\t\t\tT* data() const {\n\t\t\t\treturn aligned_;\n\t\t\t}\n\n\t\t\tstd::ptrdiff_t size() const {\n\t\t\t\treturn size_;\n\t\t\t}\n\t\t};\n\n\t\ttemplate<ext::destructible_object T>\n\t\tclass temporary_vector {\n\t\t\tT* begin_ = nullptr;\n\t\t\tT* end_ = nullptr;\n\t\t\tT* alloc_ = nullptr;\n\n\t\t\tvoid destroy() noexcept {\n\t\t\t\tfor_each(begin_, end_, destruct);\n\t\t\t}\n\n\t\tpublic:\n\t\t\tusing value_type = T;\n\n\t\t\t~temporary_vector() {\n\t\t\t\tdestroy();\n\t\t\t}\n\n\t\t\ttemporary_vector() = default;\n\t\t\ttemporary_vector(temporary_buffer<T>& buf)\n\t\t\t: begin_{buf.data()}, end_{begin_}\n\t\t\t, alloc_{begin_ + buf.size()}\n\t\t\t{}\n\t\t\ttemporary_vector(temporary_vector&&) = delete;\n\t\t\ttemporary_vector& operator=(temporary_vector&& that) = delete;\n\n\t\t\tvoid clear() noexcept {\n\t\t\t\tdestroy();\n\t\t\t\tend_ = begin_;\n\t\t\t}\n\n\t\t\tconstexpr bool empty() const noexcept {\n\t\t\t\treturn begin_ == end_;\n\t\t\t}\n\n\t\t\tconstexpr std::ptrdiff_t capacity() const noexcept {\n\t\t\t\treturn alloc_ - begin_;\n\t\t\t}\n\t\t\tconstexpr std::ptrdiff_t size() const noexcept {\n\t\t\t\treturn end_ - begin_;\n\t\t\t}\n\n\t\t\tconstexpr T* begin() noexcept { return begin_; }\n\t\t\tconstexpr T* end() noexcept { return end_; }\n\t\t\tconstexpr const T* begin() const noexcept { return begin_; }\n\t\t\tconstexpr const T* end() const noexcept { return end_; }\n\n\t\t\tconstexpr T& operator[](std::ptrdiff_t i) noexcept {\n\t\t\t\tSTL2_EXPECT(0 <= i);\n\t\t\t\tSTL2_EXPECT(i < end_ - begin_);\n\t\t\t\treturn begin_[i];\n\t\t\t}\n\n\t\t\ttemplate<class... Args>\n\t\t\trequires constructible_from<T, Args...>\n\t\t\tvoid emplace_back(Args&&... args)\n\t\t\tnoexcept(std::is_nothrow_constructible<T, Args...>::value)\n\t\t\t{\n\t\t\t\tSTL2_EXPECT(end_ < alloc_);\n\t\t\t\tdetail::construct(*end_, std::forward<Args>(args)...);\n\t\t\t\t++end_;\n\t\t\t}\n\t\t\tvoid push_back(const T& t)\n\t\t\tnoexcept(std::is_nothrow_copy_constructible<T>::value)\n\t\t\trequires copy_constructible<T>\n\t\t\t{ emplace_back(t); }\n\t\t\tvoid push_back(T&& t)\n\t\t\tnoexcept(std::is_nothrow_move_constructible<T>::value)\n\t\t\trequires move_constructible<T>\n\t\t\t{ emplace_back(std::move(t)); }\n\t\t};\n\n\t\ttemplate<ext::destructible_object T>\n\t\ttemporary_vector<T> make_temporary_vector(temporary_buffer<T>& buf) {\n\t\t\treturn {buf};\n\t\t}\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/tuple_like.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_TUPLE_LIKE_HPP\n#define STL2_DETAIL_TUPLE_LIKE_HPP\n\n#include <tuple>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tnamespace adl {\n\t\t\tusing std::get;\n\n\t\t\ttemplate<std::size_t I, class T>\n\t\t\tconstexpr auto adl_get(T&& t)\n\t\t\tnoexcept(noexcept(get<I>(static_cast<T&&>(t))))\n\t\t\t-> decltype(get<I>(static_cast<T&&>(t)))\n\t\t\t{\n\t\t\t\treturn get<I>(static_cast<T&&>(t));\n\t\t\t}\n\t\t} // namespace adl\n\t\tusing adl::adl_get;\n\t} // namespace detail\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/variant.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015, 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_VARIANT_HPP\n#define STL2_DETAIL_VARIANT_HPP\n\n#include <cstddef>\n#include <variant>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n\n// TODO: conditional noexcept for __unchecked_visit?\n\n///////////////////////////////////////////////////////////////////////////\n// variant utiilities\n//\nSTL2_OPEN_NAMESPACE {\n\t// Obtain the index of T in TypeList; substitution failure if T\n\t// does not appear exactly once.\n\ttemplate<class T, class TypeList,\n\t\tstd::size_t I = meta::_v<meta::find_index<TypeList, T>>>\n\trequires\n\t\t(I != meta::_v<meta::npos> &&\n\t\tsame_as<meta::find_index<meta::drop_c<TypeList, I + 1>, T>, meta::npos>)\n\tconstexpr std::size_t __index_of_type = I;\n\n\t// Like std::get<I>(v), but with a precondition that v.index() == I\n\ttemplate<std::size_t I, _SpecializationOf<std::variant> Variant>\n\trequires (I < std::variant_size_v<__uncvref<Variant>>)\n\tconstexpr decltype(auto) __unchecked_get(Variant&& v) noexcept {\n\t\tSTL2_EXPECT(v.index() == I);\n\t\treturn std::get<I>(static_cast<Variant&&>(v));\n\t}\n\n\t// Like std::get<T>(v), but with a precondition that holds_alternative<T>(v)\n\ttemplate<class T, _SpecializationOf<std::variant> Variant>\n\trequires requires { __index_of_type<T, meta::as_list<__uncvref<Variant>>>; }\n\tconstexpr decltype(auto) __unchecked_get(Variant&& v) noexcept {\n\t\tSTL2_EXPECT(std::holds_alternative<T>(v));\n\t\treturn std::get<T>(static_cast<Variant&&>(v));\n\t}\n\n\ttemplate<class F, class... Vs>\n\trequires (_SpecializationOf<Vs, std::variant> && ...)\n\tconstexpr decltype(auto) __unchecked_visit(F&& f, Vs&&... vs) {\n\t\t(STL2_EXPECT(!vs.valueless_by_exception()), ...);\n\t\treturn std::visit(static_cast<F&&>(f), static_cast<Vs&&>(vs)...);\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/detail/view/view_closure.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_DETAIL_VIEW_CLOSURE_HPP\n#define STL2_DETAIL_VIEW_CLOSURE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\tstruct __pipeable_base;\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT Pipeable =\n\t\t\tderived_from<T, __pipeable_base> && ext::copy_constructible_object<T>;\n\n\t\ttemplate<Pipeable, Pipeable>\n\t\tstruct __view_pipeline;\n\n\t\tstruct __pipeable_base {\n\t\t\ttemplate<Pipeable A, Pipeable B>\n\t\t\trequires constructible_from<__uncvref<A>, A> &&\n\t\t\t\tconstructible_from<__uncvref<B>, B>\n\t\t\tfriend constexpr auto operator|(A&& left, B&& right)\n\t\t\t{ return __view_pipeline{static_cast<A&&>(left), static_cast<B&&>(right)}; }\n\t\t};\n\n\t\ttemplate<class Derived>\n\t\tstruct __pipeable : __pipeable_base {\n\t\t\ttemplate<class Rng>\n\t\t\tfriend constexpr auto operator|(Rng&& rng, Derived& c)\n\t\t\t\t// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68093\n\t\t\t\t-> decltype(c(std::forward<Rng>(rng)))\n\t\t\t{ return c(std::forward<Rng>(rng)); }\n\n\t\t\ttemplate<class Rng>\n\t\t\tfriend constexpr auto operator|(Rng&& rng, const Derived& c)\n\t\t\t\t// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68093\n\t\t\t\t-> decltype(c(std::forward<Rng>(rng)))\n\t\t\t{ return c(std::forward<Rng>(rng)); }\n\n\t\t\ttemplate<class Rng>\n\t\t\tfriend constexpr auto operator|(Rng&& rng, Derived&& c)\n\t\t\t\t// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68093\n\t\t\t\t-> decltype(std::move(c)(std::forward<Rng>(rng)))\n\t\t\t{ return std::move(c)(std::forward<Rng>(rng)); }\n\n#if STL2_WORKAROUND_CLANG_40150\n\t\t\ttemplate<class Rng>\n\t\t\tfriend constexpr auto operator|(Rng&& rng, const Derived&& c)\n\t\t\t\t// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68093\n\t\t\t\t-> decltype(std::move(c)(std::forward<Rng>(rng)))\n\t\t\t{ return std::move(c)(std::forward<Rng>(rng)); }\n#else\n\t\t\ttemplate<class Rng>\n\t\t\tfriend void operator|(Rng&& rng, const Derived&& c) = delete;\n#endif\n\t\t};\n\n\t\ttemplate<class Indices, class Fn, class... Ts>\n\t\tstruct __view_closure;\n\n\t\ttemplate<std::size_t, class T>\n\t\tstruct __box {\n\t\t\tT value_;\n\t\t};\n\n\t\ttemplate<std::size_t... Is, class Fn, class... Ts>\n\t\tstruct STL2_EMPTY_BASES __view_closure<std::index_sequence<Is...>, Fn, Ts...>\n\t\t: private __box<Is, Ts>... {\n\t\t\t__view_closure() = default;\n\t\t\tconstexpr explicit __view_closure(Fn, Ts&&... ts)\n\t\t\t: __box<Is, Ts>{std::forward<Ts>(ts)}... {}\n\n\t\t\ttemplate<input_range Rng>\n\t\t\trequires viewable_range<Rng> && invocable<Fn, Rng, Ts...> &&\n\t\t\t\tview<invoke_result_t<Fn, Rng, Ts...>>\n\t\t\tconstexpr auto operator()(Rng&& rng) && {\n\t\t\t\treturn Fn{}(std::forward<Rng>(rng),\n\t\t\t\t\tstatic_cast<__box<Is, Ts>&&>(*this).value_...);\n\t\t\t}\n\t\t\ttemplate<input_range Rng>\n\t\t\trequires viewable_range<Rng> && invocable<Fn, Rng, Ts &...> &&\n\t\t\t\tview<invoke_result_t<Fn, Rng, Ts &...>>\n\t\t\tconstexpr auto operator()(Rng&& rng) & {\n\t\t\t\treturn Fn{}(std::forward<Rng>(rng),\n\t\t\t\t\tstatic_cast<__box<Is, Ts>&>(*this).value_...);\n\t\t\t}\n\t\t\ttemplate<input_range Rng>\n\t\t\trequires viewable_range<Rng> && invocable<Fn, Rng, const Ts &...> &&\n\t\t\t\tview<invoke_result_t<Fn, Rng, const Ts &...>>\n\t\t\tconstexpr auto operator()(Rng&& rng) const & {\n\t\t\t\treturn Fn{}(std::forward<Rng>(rng),\n\t\t\t\t\tstatic_cast<const __box<Is, Ts>&>(*this).value_...);\n\t\t\t}\n\t\t\ttemplate<input_range Rng>\n\t\t\trequires viewable_range<Rng> && invocable<Fn, Rng, const Ts &...> &&\n\t\t\t\tview<invoke_result_t<Fn, Rng, const Ts &...>>\n\t\t\tvoid operator()(Rng&& rng) const && = delete;\n\t\t};\n\n\t\ttemplate<semiregular Fn, copy_constructible... Ts>\n\t\tstruct STL2_EMPTY_BASES view_closure\n\t\t: __pipeable<view_closure<Fn, Ts...>>\n\t\t, __view_closure<std::index_sequence_for<Ts...>, Fn, Ts...> {\n#if STL2_WORKAROUND_MSVC_846967\n\t\t\tusing base = __view_closure<std::index_sequence_for<Ts...>, Fn, Ts...>;\n\t\t\tview_closure() = default;\n\t\t\tconstexpr explicit view_closure(Fn fn, Ts&&... ts) : base{ fn, std::forward<Ts>(ts)... } {}\n#else // ^^^ workaround / no workaround vvv\n\t\t\tusing __view_closure<std::index_sequence_for<Ts...>, Fn, Ts...>::__view_closure;\n#endif // STL2_WORKAROUND_MSVC_846967\n\t\t};\n\n\t\ttemplate<semiregular Fn, copy_constructible... Ts>\n\t\tview_closure(Fn, Ts&&...) -> view_closure<Fn, Ts...>;\n\n\t\ttemplate<Pipeable A, Pipeable B>\n\t\tstruct __view_pipeline : __pipeable<__view_pipeline<A, B>> {\n\t\tprivate:\n\t\t\tA left_;\n\t\t\tB right_;\n\t\tpublic:\n\t\t\t__view_pipeline() = default;\n\t\t\tconstexpr __view_pipeline(A&& left, B&& right)\n\t\t\t: left_(std::move(left)), right_(std::move(right)) {}\n\n\t\t\ttemplate<viewable_range R>\n\t\t\trequires invocable<A, R> && invocable<B, invoke_result_t<A, R>>\n\t\t\tconstexpr decltype(auto) operator()(R&& r) &&\n\t\t\t{ return std::move(right_)(std::move(left_)(std::forward<R>(r))); }\n\n\t\t\ttemplate<viewable_range R>\n\t\t\trequires invocable<A&, R> && invocable<B&, invoke_result_t<A&, R>>\n\t\t\tconstexpr decltype(auto) operator()(R&& r) &\n\t\t\t{ return right_(left_(std::forward<R>(r))); }\n\n\t\t\ttemplate<viewable_range R>\n\t\t\trequires invocable<const A&, R> &&\n\t\t\t\tinvocable<const B&, invoke_result_t<const A&, R>>\n\t\t\tconstexpr decltype(auto) operator()(R&& r) const &\n\t\t\t{ return right_(left_(std::forward<R>(r))); }\n\t\t};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/functional.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_FUNCTIONAL_HPP\n#define STL2_FUNCTIONAL_HPP\n\n#include <functional>\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/functional/comparisons.hpp>\n#include <stl2/detail/functional/invoke.hpp>\n#include <stl2/detail/functional/not_fn.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t///////////////////////////////////////////////////////////////////////////\n\t// identity [func.identity]\n\t//\n\tstruct identity {\n\t\ttemplate<class T>\n\t\tconstexpr T&& operator()(T&& t) const noexcept {\n\t\t\treturn std::forward<T>(t);\n\t\t}\n\n\t\tusing is_transparent = std::true_type;\n\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/iterator.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_ITERATOR_HPP\n#define STL2_ITERATOR_HPP\n\n#include <initializer_list>\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/any_iterator.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/common_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <stl2/detail/iterator/istream_iterator.hpp>\n#include <stl2/detail/iterator/istreambuf_iterator.hpp>\n#include <stl2/detail/iterator/ostreambuf_iterator.hpp>\n#include <stl2/detail/iterator/move_iterator.hpp>\n#include <stl2/detail/iterator/operations.hpp>\n#include <stl2/detail/iterator/ostream_iterator.hpp>\n#include <stl2/detail/iterator/reverse_iterator.hpp>\n#include <stl2/detail/iterator/unreachable.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/primitives.hpp>\n#include <stl2/view/subrange.hpp>\n\n#endif\n"
  },
  {
    "path": "include/stl2/memory.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_MEMORY_HPP\n#define STL2_MEMORY_HPP\n\n#include <memory>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/memory/construct_at.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n#include <stl2/detail/memory/uninitialized_copy.hpp>\n#include <stl2/detail/memory/uninitialized_default_construct.hpp>\n#include <stl2/detail/memory/uninitialized_fill.hpp>\n#include <stl2/detail/memory/uninitialized_move.hpp>\n#include <stl2/detail/memory/uninitialized_value_construct.hpp>\n\n#endif\n"
  },
  {
    "path": "include/stl2/random.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_RANDOM_HPP\n#define STL2_RANDOM_HPP\n\n#include <random>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/urng.hpp>\n\n#endif\n"
  },
  {
    "path": "include/stl2/ranges.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_RANGES_HPP\n#define STL2_RANGES_HPP\n\n#include <initializer_list>\n#include <stl2/iterator.hpp>\n\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/nth_iterator.hpp>\n#include <stl2/detail/range/primitives.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/common.hpp>\n#include <stl2/view/counted.hpp>\n#include <stl2/view/drop.hpp>\n#include <stl2/view/drop_while.hpp>\n#include <stl2/view/empty.hpp>\n#include <stl2/view/filter.hpp>\n#include <stl2/view/generate.hpp>\n#include <stl2/view/indirect.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/istream.hpp>\n#include <stl2/view/join.hpp>\n#include <stl2/view/move.hpp>\n#include <stl2/view/ref.hpp>\n#include <stl2/view/repeat_n.hpp>\n#include <stl2/view/repeat.hpp>\n#include <stl2/view/reverse.hpp>\n#include <stl2/view/single.hpp>\n#include <stl2/view/split.hpp>\n#include <stl2/view/subrange.hpp>\n#include <stl2/view/take.hpp>\n#include <stl2/view/take_exactly.hpp>\n#include <stl2/view/take_while.hpp>\n#include <stl2/view/transform.hpp>\n#include <stl2/view/view_interface.hpp>\n\n#endif\n"
  },
  {
    "path": "include/stl2/type_traits.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_TYPE_TRAITS\n#define STL2_TYPE_TRAITS\n\n#include <type_traits>\n\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/core.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t////////////////////////////////////////////////////////////////////////////\n\t// common_type [meta.trans.other]\n\t//\n\n\t// COND_RES [meta.trans.other]/2.4\n\ttemplate<class T, class U>\n\tusing __cond_res =\n\t\tdecltype(false ? std::declval<T(&)()>()() : std::declval<U(&)()>()());\n\n\ttemplate<class...>\n\tstruct common_type {};\n\n\ttemplate<class... Ts>\n\tusing common_type_t = meta::_t<common_type<Ts...>>;\n\n\t// [meta.trans.other]/3.2\n\ttemplate<class T>\n\tstruct common_type<T> : common_type<T, T> {};\n\n\t// [meta.trans.other]/3.3: \"Otherwise, there shall be no member type.\"\n\ttemplate<class, class> // NB: The arguments have been decayed by the time they get here.\n\tstruct __common_type3 {};\n\n\t// [meta.trans.other]/3.3.4\n\t// I'm 99% certain that [meta.trans.other]/3.3.4 never produces a useful\n\t// common type when T or U is void - proper cases for void would be handled\n\t// earlier in 3.3.3 - so const X& is equivalent to CREF(X) here.\n\ttemplate<class T, class U> // NB: Ditto decayed.\n\trequires requires { typename __cond_res<const T&, const U&>; }\n\tstruct __common_type3<T, U> {\n\t\tusing type = std::decay_t<__cond_res<const T&, const U&>>;\n\t};\n\n\ttemplate<class T, class U> // NB: Ditto decayed.\n\tstruct __common_type2 : __common_type3<T, U> {};\n\n\t// Note: std::common_type handles [meta.trans.other]/3.3.3\n\ttemplate<class T, class U> // NB: Ditto decayed.\n\trequires requires { typename std::common_type_t<T, U>; }\n\tstruct __common_type2<T, U> {\n\t\tusing type = std::common_type_t<T, U>;\n\t};\n\n\ttemplate<class T, class U>\n\tstruct common_type<T, U> : __common_type2<T, U> {};\n\n\ttemplate<class T, class U>\n\trequires (!_Decayed<T> || !_Decayed<U>)\n\tstruct common_type<T, U> : common_type<std::decay_t<T>, std::decay_t<U>> {};\n\n\ttemplate<class T, class U, class V, class...  W>\n\trequires requires { typename common_type_t<T, U>; }\n\tstruct common_type<T, U, V, W...>\n\t: common_type<common_type_t<T, U>, V, W...> {};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// basic_common_reference [meta.trans.other]\n\t//\n\ttemplate<class, class, template<class> class, template<class> class>\n\tstruct basic_common_reference {};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// common_reference [meta.trans.other]\n\t//\n\ttemplate<class From>\n\tstruct __copy_cv_ {\n\t\tstatic_assert(!std::is_reference_v<From>);\n\t\ttemplate<class To> using invoke = To;\n\t};\n\ttemplate<class From>\n\tstruct __copy_cv_<const From> {\n\t\ttemplate<class To> using invoke = const To;\n\t};\n\ttemplate<class From>\n\tstruct __copy_cv_<volatile From> {\n\t\ttemplate<class To> using invoke = volatile To;\n\t};\n\ttemplate<class From>\n\tstruct __copy_cv_<const volatile From> {\n\t\ttemplate<class To> using invoke = const volatile To;\n\t};\n\ttemplate<class From, class To>\n\tusing __copy_cv = meta::invoke<__copy_cv_<From>, To>;\n\n\t// CREF [meta.trans.other]/2.1\n\ttemplate<class T>\n\tusing __cref = std::add_lvalue_reference_t<const std::remove_reference_t<T>>;\n\n\t// COMMON_REF [meta.trans.other]/2\n\ttemplate<class T, class U>\n\tstruct __common_ref_ {\n\t\tstatic_assert(std::is_reference_v<T>);\n\t\tstatic_assert(std::is_reference_v<U>);\n\t};\n\n\ttemplate<class T, class U>\n\tusing __common_ref = meta::_t<__common_ref_<T, U>>;\n\n\t// [meta.trans.other]/2.5\n\ttemplate<class T, class U>\n\tusing __lref_res = __cond_res<__copy_cv<T, U> &, __copy_cv<U, T> &>;\n\n\ttemplate<class T, class U>\n\trequires requires { typename __lref_res<T, U>; } &&\n\t\tstd::is_reference_v<__lref_res<T, U>>\n\tstruct __common_ref_<T&, U&> {\n\t\tusing type = __lref_res<T, U>;\n\t};\n\n\t// [meta.trans.other]/2.6\n\ttemplate<class T, class U, class R = __common_ref<T&, U&>>\n\tusing __rref_res = std::remove_reference_t<R>&&;\n\n\ttemplate<class T, class U>\n\trequires meta::Valid<__common_ref, T&, U&> &&\n\t\tconvertible_to<T&&, __rref_res<T, U>> &&\n\t\tconvertible_to<U&&, __rref_res<T, U>>\n\tstruct __common_ref_<T&&, U&&> {\n\t\tusing type = __rref_res<T, U>;\n\t};\n\n\t// [meta.trans.other]/2.7\n\ttemplate<class T, class U>\n\trequires requires { typename __common_ref<const T&, U&>; } &&\n\t\tconvertible_to<T&&, __common_ref<const T&, U&>>\n\tstruct __common_ref_<T&&, U&> {\n\t\tusing type = __common_ref<const T&, U&>;\n\t};\n\n\t// [meta.trans.other]/2.8\n\ttemplate<class T, class U>\n\trequires requires { typename __common_ref<T&, const U&>; } &&\n\t\tconvertible_to<U&&, __common_ref<T&, const U&>>\n\tstruct __common_ref_<T&, U&&> {\n\t\tusing type = __common_ref<T&, const U&>;\n\t};\n\n\ttemplate<class>\n\tstruct __xref {\n\t\ttemplate<class U> using invoke = U;\n\t};\n\ttemplate<class T>\n\tstruct __xref<const T> {\n\t\ttemplate<class U> using invoke = const U;\n\t};\n\ttemplate<class T>\n\tstruct __xref<volatile T> {\n\t\ttemplate<class U> using invoke = volatile U;\n\t};\n\ttemplate<class T>\n\tstruct __xref<const volatile T> {\n\t\ttemplate<class U> using invoke = const volatile U;\n\t};\n\ttemplate<class T>\n\tstruct __xref<T&> {\n\t\ttemplate<class U> using invoke =\n\t\t\tstd::add_lvalue_reference_t<meta::invoke<__xref<T>, U>>;\n\t};\n\ttemplate<class T>\n\tstruct __xref<T&&> {\n\t\ttemplate<class U> using invoke =\n\t\t\tstd::add_rvalue_reference_t<meta::invoke<__xref<T>, U>>;\n\t};\n\n\ttemplate<class T, class U>\n\tusing __basic_common_reference_t =\n\t\tmeta::_t<basic_common_reference<__uncvref<T>, __uncvref<U>,\n\t\t\t__xref<T>::template invoke, __xref<U>::template invoke>>;\n\n\ttemplate<class...>\n\tstruct common_reference {};\n\n\ttemplate<class... Ts>\n\tusing common_reference_t = meta::_t<common_reference<Ts...>>;\n\n\t// [meta.trans.other]/5.2\n\ttemplate<class T>\n\tstruct common_reference<T> {\n\t\tusing type = T;\n\t};\n\n\t// [meta.trans.other]/5.3.4\n\ttemplate<class T, class U>\n\tstruct __common_reference3 : common_type<T, U> {};\n\n\t// [meta.trans.other]/5.3.3\n\ttemplate<class T, class U>\n\trequires requires { typename __cond_res<T, U>; }\n\tstruct __common_reference3<T, U> {\n\t\tusing type = __cond_res<T, U>;\n\t};\n\n\ttemplate<class T, class U>\n\tstruct __common_reference2 : __common_reference3<T, U> {};\n\n\t// [meta.trans.other]/5.3.2\n\ttemplate<class T, class U>\n\trequires requires { typename __basic_common_reference_t<T, U>; }\n\tstruct __common_reference2<T, U> {\n\t\tusing type = __basic_common_reference_t<T, U>;\n\t};\n\n\ttemplate<class T, class U>\n\tstruct common_reference<T, U> : __common_reference2<T, U> {};\n\n\t// [meta.trans.other]/5.3.1\n\ttemplate<class T, class U>\n\trequires std::is_reference_v<T> && std::is_reference_v<U> &&\n\t\trequires { typename __common_ref<T, U>; }\n\tstruct common_reference<T, U> {\n\t\tusing type = __common_ref<T, U>;\n\t};\n\n\t// [meta.trans.other]/5.4\n\ttemplate<class T, class U, class V, class... W>\n\trequires requires { typename common_reference_t<T, U>; }\n\tstruct common_reference<T, U, V, W...>\n\t: common_reference<common_reference_t<T, U>, V, W...> {};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// common_reference_with [concept.commonref]\n\t//\n\ttemplate<class T, class U>\n\tMETA_CONCEPT common_reference_with =\n\t\trequires {\n\t\t\ttypename common_reference_t<T, U>;\n\t\t\ttypename common_reference_t<U, T>;\n\t\t} &&\n\t\tsame_as<common_reference_t<T, U>, common_reference_t<U, T>> &&\n\t\tconvertible_to<T, common_reference_t<T, U>> &&\n\t\tconvertible_to<U, common_reference_t<T, U>>;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// common_with [concept.common]\n\t//\n\ttemplate<class T, class U>\n\tMETA_CONCEPT common_with =\n\t\trequires {\n\t\t\ttypename common_type_t<T, U>;\n\t\t\ttypename common_type_t<U, T>;\n\t\t\trequires same_as<common_type_t<T, U>, common_type_t<U, T>>;\n\t\t\tstatic_cast<common_type_t<T, U>>(std::declval<T>());\n\t\t\tstatic_cast<common_type_t<T, U>>(std::declval<U>());\n\t\t} &&\n\t\tcommon_reference_with<\n\t\t\tstd::add_lvalue_reference_t<const T>,\n\t\t\tstd::add_lvalue_reference_t<const U>> &&\n\t\tcommon_reference_with<\n\t\t\tstd::add_lvalue_reference_t<common_type_t<T, U>>,\n\t\t\tcommon_reference_t<\n\t\t\t\tstd::add_lvalue_reference_t<const T>,\n\t\t\t\tstd::add_lvalue_reference_t<const U>>>;\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/utility.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_UTILITY_HPP\n#define STL2_UTILITY_HPP\n\n#include <utility>\n\n#include <stl2/functional.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/swap.hpp>\n#include <stl2/detail/tuple_like.hpp>\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/all.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_ALL_HPP\n#define STL2_VIEW_ALL_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/ref.hpp>\n#include <stl2/view/subrange.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace views {\n\t\tstruct __all_fn : detail::__pipeable<__all_fn> {\n\t\tprivate:\n\t\t\tenum : unsigned { __throws = 1, __decay = 2, __ref = 4, __subrange = 6 };\n\n\t\t\ttemplate<viewable_range _Range>\n\t\t\tstatic constexpr unsigned __choose() noexcept {\n\t\t\t\tif constexpr (view<__uncvref<_Range>>) {\n\t\t\t\t\treturn __decay | unsigned{std::is_nothrow_constructible_v<__uncvref<_Range>, _Range>};\n\t\t\t\t} else if constexpr (std::is_lvalue_reference_v<_Range>) {\n\t\t\t\t\treturn __ref | unsigned{noexcept(ref_view{std::declval<_Range>()})};\n\t\t\t\t} else {\n\t\t\t\t\treturn __subrange | unsigned{noexcept(subrange{std::declval<_Range>()})};\n\t\t\t\t}\n\t\t\t}\n\t\tpublic:\n\t\t\ttemplate<viewable_range _Range, unsigned _Choice = __choose<_Range>()>\n\t\t\tconstexpr auto operator()(_Range&& __r) const noexcept(_Choice & __throws) {\n\t\t\t\tconstexpr auto __strategy = _Choice & ~__throws;\n\t\t\t\tif constexpr (__strategy == __decay) {\n\t\t\t\t\treturn static_cast<_Range&&>(__r);\n\t\t\t\t} else if constexpr (__strategy == __ref) {\n\t\t\t\t\treturn ref_view{__r};\n\t\t\t\t} else {\n\t\t\t\t\tstatic_assert(__strategy == __subrange);\n\t\t\t\t\treturn subrange{static_cast<_Range&&>(__r)};\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __all_fn all{};\n\t} // namespace views\n\n\ttemplate<viewable_range R>\n\tusing all_view = decltype(views::all(std::declval<R>()));\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/common.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_COMMON_HPP\n#define STL2_VIEW_COMMON_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/iterator/common_iterator.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t// common_view [range.common.view]\n\ttemplate<view V>\n\trequires (!common_range<V>)\n\tstruct common_view : view_interface<common_view<V>> {\n\t\tcommon_view() = default;\n\n\t\tconstexpr explicit common_view(V v) : base_(std::move(v)) {}\n\n\t\tconstexpr V base() const { return base_; }\n\n\t\tconstexpr auto size() requires (!ext::simple_view<V> && sized_range<V>) {\n\t\t\treturn __stl2::size(base_);\n\t\t}\n\t\tconstexpr auto size() const requires sized_range<const V> {\n\t\t\treturn __stl2::size(base_);\n\t\t}\n\n\t\tconstexpr auto begin() requires (!ext::simple_view<V>) {\n\t\t\tif constexpr (random_access_range<V> && sized_range<V>)\n\t\t\t\treturn __stl2::begin(base_);\n\t\t\telse\n\t\t\t\treturn CI<false>{__stl2::begin(base_)};\n\t\t}\n\t\tconstexpr auto begin() const requires range<const V> {\n\t\t\tif constexpr (random_access_range<const V> && sized_range<const V>)\n\t\t\t\treturn __stl2::begin(base_);\n\t\t\telse\n\t\t\t\treturn CI<true>{__stl2::begin(base_)};\n\t\t}\n\n\t\tconstexpr auto end() requires (!ext::simple_view<V>) {\n\t\t\tif constexpr (random_access_range<V> && sized_range<V>)\n\t\t\t\treturn __stl2::begin(base_) + __stl2::size(base_);\n\t\t\telse\n\t\t\t\treturn CI<false>{__stl2::end(base_)};\n\t\t}\n\t\tconstexpr auto end() const requires range<const V> {\n\t\t\tif constexpr (random_access_range<const V> && sized_range<const V>)\n\t\t\t\treturn __stl2::begin(base_) + __stl2::size(base_);\n\t\t\telse\n\t\t\t\treturn CI<true>{__stl2::end(base_)};\n\t\t}\n\n\tprivate:\n\t\ttemplate<bool IsConst> using CI = common_iterator<\n\t\t\titerator_t<__maybe_const<IsConst, V>>,\n\t\t\tsentinel_t<__maybe_const<IsConst, V>>>;\n\n\t\tV base_ = V();\n\t};\n\n\ttemplate<class R>\n\tcommon_view(R&&) -> common_view<all_view<R>>;\n\n\tnamespace views {\n\t\tstruct __common_fn : detail::__pipeable<__common_fn> {\n\t\t\ttemplate<viewable_range R>\n\t\t\tconstexpr auto operator()(R&& r) const {\n\t\t\t\tif constexpr (common_range<R>)\n\t\t\t\t\treturn views::all(std::forward<R>(r));\n\t\t\t\telse\n\t\t\t\t\treturn common_view{std::forward<R>(r)};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __common_fn common{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/counted.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_COUNTED_VIEW_HPP\n#define STL2_VIEW_COUNTED_VIEW_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/view/subrange.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace views {\n\t\tstruct __counted_fn {\n\t\t\ttemplate<input_or_output_iterator I>\n\t\t\tconstexpr auto operator()(I i, iter_difference_t<I> d) const {\n\t\t\t\tif constexpr (random_access_iterator<I>) {\n\t\t\t\t\treturn subrange{i, i + d};\n\t\t\t\t} else {\n\t\t\t\t\treturn subrange{counted_iterator{i, d}, default_sentinel};\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __counted_fn counted{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/drop.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//  Copyright Christopher Di Bella\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_DROP_HPP\n#define STL2_VIEW_DROP_HPP\n\n#include <stl2/detail/cached_position.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/nth_iterator.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<view R>\n\tclass STL2_EMPTY_BASES drop_view\n\t: public view_interface<drop_view<R>>\n\t, private detail::cached_position<R, drop_view<R>, !random_access_range<const R>> {\n\t\tusing D = iter_difference_t<iterator_t<R>>;\n\tpublic:\n\t\tdrop_view() = default;\n\n\t\tconstexpr drop_view(R base, D count)\n\t\t: base_(std::move(base)), count_(count)\n\t\t{}\n\n\t\tconstexpr R base() const { return base_; }\n\n\t\tconstexpr auto begin() requires (!ext::simple_view<R> || !random_access_range<R>)\n\t\t{ return begin_impl(*this); }\n\t\tconstexpr auto begin() const requires range<const R> && random_access_range<const R>\n\t\t{ return begin_impl(*this); }\n\n\t\tconstexpr auto end() requires (!ext::simple_view<R>)\n\t\t{ return end_impl(*this); }\n\t\tconstexpr auto end() const requires range<const R>\n\t\t{ return end_impl(*this); }\n\n\t\tconstexpr auto size() requires (!ext::simple_view<R> && sized_range<R>) { return size_impl(*this); }\n\t\tconstexpr auto size() const requires sized_range<const R> { return size_impl(*this); }\n\tprivate:\n\t\tR base_{};\n\t\tD count_ = 0;\n\n\t\ttemplate<class X>\n\t\tstatic constexpr auto begin_impl(X& x) {\n\t\t\tif constexpr (random_access_range<__maybe_const<std::is_const_v<X>, R>>) {\n\t\t\t\treturn __stl2::ext::nth_iterator(x.base_, x.count_);\n\t\t\t} else {\n\t\t\t\tusing cache_t = typename drop_view::cached_position;\n\t\t\t\tauto& cache = static_cast<cache_t&>(x);\n\t\t\t\tif (cache) {\n\t\t\t\t\treturn cache.get(x.base_);\n\t\t\t\t}\n\n\t\t\t\tauto iter = __stl2::ext::nth_iterator(x.base_, x.count_);\n\t\t\t\tcache.set(x.base_, iter);\n\t\t\t\treturn iter;\n\t\t\t}\n\t\t}\n\n\t\ttemplate<class X>\n\t\tstatic constexpr auto end_impl(X& x) { return __stl2::end(x.base_); }\n\n\t\ttemplate<class X>\n\t\tstatic constexpr auto size_impl(X& x) {\n\t\t\tauto const size = __stl2::size(x.base_);\n\t\t\tauto const count = static_cast<decltype(size)>(x.count_);\n\t\t\treturn size < count ? 0 : size - count;\n\t\t}\n\t};\n\n\ttemplate<range R>\n\tdrop_view(R&&, iter_difference_t<iterator_t<R>>) -> drop_view<all_view<R>>;\n\n\tnamespace views {\n\t\tstruct __drop_fn : detail::__pipeable<__drop_fn> {\n\t\t\ttemplate<range Rng>\n\t\t\tconstexpr auto operator()(Rng&& rng, iter_difference_t<iterator_t<Rng>> count) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\tdrop_view(all(std::forward<Rng>(rng)), count)\n\t\t\t)\n\n\t\t\ttemplate<integral D>\n\t\t\tconstexpr auto operator()(D count) const\n\t\t\t{\n\t\t\t\treturn detail::view_closure(*this, static_cast<D>(count));\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __drop_fn drop{};\n\t} // mamespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_VIEW_DROP_HPP\n"
  },
  {
    "path": "include/stl2/view/drop_while.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//  Copyright Christopher Di Bella\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_DROP_WHILE_HPP\n#define STL2_VIEW_DROP_WHILE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/algorithm/find_if_not.hpp>\n#include <stl2/detail/non_propagating_cache.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <utility>\n\nSTL2_OPEN_NAMESPACE {\n\t\ttemplate<view R, indirect_unary_predicate<iterator_t<R>> Pred>\n\t\trequires input_range<R> && std::is_object_v<Pred>\n\t\tclass STL2_EMPTY_BASES drop_while_view\n\t\t: public view_interface<drop_while_view<R, Pred>>\n\t\t, private detail::semiregular_box<Pred>\n\t\t, private detail::non_propagating_cache<iterator_t<R>, drop_while_view<R, Pred>> {\n\t\t\tusing storage_t = detail::semiregular_box<Pred>;\n\t\t\tusing storage_t::get;\n\t\tpublic:\n\t\t\tdrop_while_view() = default;\n\n\t\t\tconstexpr drop_while_view(R base, Pred pred)\n\t\t\t: storage_t{std::move(pred)}, base_(std::move(base)) {}\n\n\t\t\tconstexpr R base() const { return base_; }\n\t\t\tconstexpr const Pred& pred() const noexcept { return get(); }\n\n\t\t\tconstexpr auto begin() {\n\t\t\t\tusing cache_t = typename drop_while_view::non_propagating_cache;\n\t\t\t\tauto& iterator_self = static_cast<cache_t&>(*this);\n\t\t\t\tif (!iterator_self) {\n\t\t\t\t\titerator_self = find_if_not(base_, [this](auto&& i) mutable {\n\t\t\t\t\t\t// A predicate must be equality-preserving. While it's not possible to generally\n\t\t\t\t\t\t// check that te predicate isn't equality-preserving, we can trap\n\t\t\t\t\t\t// non-equality-preserving invocables on-the-spot by calling them multiple times\n\t\t\t\t\t\t// and compare the results.\n\t\t\t\t\t\t// This is only enabled in debug-mode, since it's potentially an expensive check.\n\t\t\t\t\t\tauto result = get()(i);\n\t\t\t\t\t\tSTL2_ASSERT(result == get()(i));\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn *iterator_self;\n\t\t\t}\n\n\t\t\tconstexpr auto end() { return __stl2::end(base_); }\n\t\tprivate:\n\t\t\tR base_{};\n\t\t};\n\n\t\ttemplate<class R, class Pred>\n\t\tdrop_while_view(R&&, Pred) -> drop_while_view<all_view<R>, Pred>;\n\n\tnamespace views {\n\t\tstruct __drop_while_fn : detail::__pipeable<__drop_while_fn> {\n\t\t\ttemplate<class Rng, class Pred>\n\t\t\tconstexpr auto operator()(Rng&& rng, Pred&& pred) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\tdrop_while_view{\n\t\t\t\t\tviews::all(static_cast<Rng&&>(rng)), std::forward<Pred>(pred)}\n\t\t\t)\n\n\t\t\ttemplate<__stl2::ext::copy_constructible_object Pred>\n\t\t\tconstexpr auto operator()(Pred pred) const\n\t\t\t{ return detail::view_closure{*this, std::move(pred)}; }\n\t\t};\n\n\t\tinline constexpr __drop_while_fn drop_while{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_VIEW_DROP_WHILE_HPP\n"
  },
  {
    "path": "include/stl2/view/empty.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_EMPTY_HPP\n#define STL2_VIEW_EMPTY_HPP\n\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class T>\n\trequires std::is_object_v<T>\n\tstruct empty_view : view_interface<empty_view<T>> {\n\t\tstatic constexpr T* begin() noexcept { return nullptr; }\n\t\tstatic constexpr T* end() noexcept { return nullptr; }\n\t\tstatic constexpr T* data() noexcept { return nullptr; }\n\t\tstatic constexpr std::ptrdiff_t size() noexcept { return 0; }\n\t\tstatic constexpr bool empty() noexcept { return true; }\n\n\t\tfriend constexpr T* begin(empty_view) noexcept { return nullptr; }\n\t\tfriend constexpr T* end(empty_view) noexcept { return nullptr; }\n\t};\n\n\tnamespace views {\n\t\ttemplate<class T>\n\t\tinline constexpr empty_view<T> empty{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/filter.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_FILTER_HPP\n#define STL2_VIEW_FILTER_HPP\n\n#include <stl2/detail/cached_position.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/functional/invoke.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>\n\trequires view<V>\n\tclass filter_view : public view_interface<filter_view<V, Pred>> {\n\tprivate:\n\t\tclass __iterator;\n\t\tclass __sentinel;\n\n\t\tV base_;\n\t\tdetail::semiregular_box<Pred> pred_;\n\t\tdetail::cached_position<V> begin_;\n\n\tpublic:\n\t\tfilter_view() = default;\n\n\t\tconstexpr filter_view(V base, Pred pred)\n\t\t: base_(std::move(base)), pred_(std::move(pred)) {}\n\n\t\tconstexpr V base() const\n\t\t{ return base_; }\n\n\t\tconstexpr __iterator begin()\n\t\t{\n\t\t\tauto cached = static_cast<bool>(begin_);\n\t\t\titerator_t<V> first = cached\n\t\t\t\t? begin_.get(base_)\n\t\t\t\t: find_if(base_, __stl2::ref(pred_.get()));\n\t\t\tif(!cached)\n\t\t\t\tbegin_.set(base_, first);\n\t\t\treturn __iterator{*this, std::move(first)};\n\t\t}\n\n\t\tconstexpr __sentinel end()\n\t\t{ return __sentinel{*this}; }\n\n\t\tconstexpr __iterator end() requires common_range<V>\n\t\t{ return __iterator{*this, __stl2::end(base_)}; }\n\t};\n\n\ttemplate<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>\n\trequires view<V>\n\tclass filter_view<V, Pred>::__iterator {\n\tprivate:\n\t\titerator_t<V> current_{};\n\t\tfilter_view* parent_ = nullptr;\n\t\tfriend __sentinel;\n\tpublic:\n\t\tusing iterator_category =\n\t\t\tmeta::if_c<bidirectional_iterator<iterator_t<V>>,\n\t\t\t\t__stl2::bidirectional_iterator_tag,\n\t\t\tmeta::if_c<forward_iterator<iterator_t<V>>,\n\t\t\t\t__stl2::forward_iterator_tag,\n\t\t\t\t__stl2::input_iterator_tag>>;\n\t\tusing value_type = iter_value_t<iterator_t<V>>;\n\t\tusing difference_type = iter_difference_t<iterator_t<V>>;\n\n\t\t__iterator() = default;\n\n\t\tconstexpr __iterator(filter_view& parent, iterator_t<V> current)\n\t\t: current_(current), parent_(&parent) {}\n\n\t\tconstexpr iterator_t<V> base() const\n\t\t{ return current_; }\n\n\t\tconstexpr iter_reference_t<iterator_t<V>> operator*() const\n\t\t{ return *current_; }\n\n\t\t// Workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\ttemplate<class II = iterator_t<V>>\n\t\tconstexpr iterator_t<V> operator->() const\n\t\trequires std::is_pointer_v<iterator_t<V>> ||\n\t\t\trequires(II i) { i.operator->(); }\n\t\t{\n\t\t\treturn current_;\n\t\t}\n\n\t\tconstexpr __iterator& operator++()\n\t\t{\n\t\t\tconst auto last = __stl2::end(parent_->base_);\n\t\t\tSTL2_ASSERT(current_ != last);\n\t\t\tcurrent_ = find_if(++current_, last, __stl2::ref(parent_->pred_.get()));\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr void operator++(int)\n\t\t{ (void)++*this; }\n\n\t\tconstexpr __iterator operator++(int) requires forward_range<V>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr __iterator& operator--() requires bidirectional_range<V>\n\t\t{\n\t\t\tdo\n\t\t\t\t--current_;\n\t\t\twhile(!__stl2::invoke(parent_->pred_.get(), *current_));\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr __iterator operator--(int) requires bidirectional_range<V>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t--*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tfriend constexpr bool operator==(const __iterator& x, const __iterator& y)\n\t\trequires equality_comparable<iterator_t<V>>\n\t\t{ return x.current_ == y.current_; }\n\n\t\tfriend constexpr bool operator!=(const __iterator& x, const __iterator& y)\n\t\trequires equality_comparable<iterator_t<V>>\n\t\t{ return !(x == y); }\n\n\t\tfriend constexpr iter_rvalue_reference_t<iterator_t<V>>\n\t\titer_move(const __iterator& i)\n\t\tnoexcept(noexcept(__stl2::iter_move(i.current_)))\n\t\t{ return __stl2::iter_move(i.current_); }\n\n\t\tfriend constexpr void iter_swap(const __iterator& x, const __iterator& y)\n\t\tnoexcept(noexcept(__stl2::iter_swap(x.current_, y.current_)))\n\t\t{ __stl2::iter_swap(x.current_, y.current_); }\n\t};\n\n\ttemplate<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>\n\trequires view<V>\n\tclass filter_view<V, Pred>::__sentinel {\n\tprivate:\n\t\tsentinel_t<V> end_;\n\n\t\tconstexpr bool equal(const __iterator& i) const {\n\t\t\treturn i.current_ == end_;\n\t\t}\n\tpublic:\n\t\t__sentinel() = default;\n\t\texplicit constexpr __sentinel(filter_view& parent)\n\t\t: end_(__stl2::end(parent.base_)) {}\n\n\t\tconstexpr sentinel_t<V> base() const\n\t\t{ return end_; }\n\n\t\tfriend constexpr bool operator==(const __iterator& x, const __sentinel& y)\n\t\t{ return y.equal(x); }\n\t\tfriend constexpr bool operator==(const __sentinel& x, const __iterator& y)\n\t\t{ return x.equal(y); }\n\t\tfriend constexpr bool operator!=(const __iterator& x, const __sentinel& y)\n\t\t{ return !y.equal(x); }\n\t\tfriend constexpr bool operator!=(const __sentinel& x, const __iterator& y)\n\t\t{ return !x.equal(y); }\n\t};\n\n\ttemplate<class R, class Pred>\n\tfilter_view(R&&, Pred) -> filter_view<all_view<R>, Pred>;\n\n\tnamespace views {\n\t\tstruct __filter_fn {\n\t\t\ttemplate<input_range R, indirect_unary_predicate<iterator_t<R>> Pred>\n\t\t\trequires viewable_range<R>\n\t\t\tconstexpr auto operator()(R&& rng, Pred pred) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\tfilter_view<all_view<R>, Pred>{std::forward<R>(rng), std::move(pred)}\n\t\t\t)\n\n\t\t\ttemplate<copy_constructible Pred>\n\t\t\tconstexpr auto operator()(Pred pred) const {\n\t\t\t\treturn detail::view_closure{*this, std::move(pred)};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __filter_fn filter{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/generate.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Christopher Di Bella\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_GENERATE_HPP\n#define STL2_VIEW_GENERATE_HPP\n\n#include <utility>\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/concepts/function.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/iterator/unreachable.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/non_propagating_cache.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<class F>\n\t\tMETA_CONCEPT __ConstInvocable =\n\t\t\tinvocable<F&> &&\n\t\t\tinvocable<const F&> &&\n\t\t\tsame_as<invoke_result_t<F&>, invoke_result_t<const F&>>;\n\n\t\ttemplate<copy_constructible_object F>\n\t\trequires invocable<F&>\n\t\tstruct STL2_EMPTY_BASES generate_view\n\t\t: view_interface<generate_view<F>>\n\t\t, private detail::semiregular_box<F>\n\t\t, private detail::non_propagating_cache<invoke_result_t<F&>> {\n\t\tprivate:\n\t\t\tusing generator_base = detail::semiregular_box<F>;\n\t\t\tusing result_t = invoke_result_t<F&>;\n\t\t\tusing cache_base = detail::non_propagating_cache<result_t>;\n\n\t\t\tstruct __iterator;\n\n\t\t\tconstexpr cache_base& as_cache() noexcept\n\t\t\t{ return static_cast<cache_base&>(*this); }\n\t\tpublic:\n\t\t\tgenerate_view() = default;\n\n\t\t\texplicit constexpr generate_view(F f) noexcept(std::is_nothrow_move_constructible_v<F>)\n\t\t\t\t: generator_base(std::move(f))\n\t\t\t{}\n\n\t\t\tconstexpr __iterator begin()\n\t\t\t{ return __iterator{*this}; }\n\n\t\t\tconstexpr unreachable_sentinel_t end() const noexcept\n\t\t\t{ return {}; }\n\t\t};\n\n\t\ttemplate<copy_constructible_object F>\n\t\trequires invocable<F&>\n\t\tstruct generate_view<F>::__iterator {\n\t\t\tusing value_type = result_t;\n\t\t\tusing difference_type = std::intmax_t;\n\t\t\tusing iterator_category = std::input_iterator_tag;\n\n\t\t\t__iterator() = default;\n\n\t\t\texplicit __iterator(generate_view& view) : view_{std::addressof(view)} {}\n\n\t\t\tauto&& operator*()\n\t\t\trequires (!__ConstInvocable<F>)\n\t\t\t{ return deref_impl(*this); }\n\n\t\t\tauto&& operator*() const\n\t\t\trequires __ConstInvocable<F>\n\t\t\t{ return deref_impl(*this); }\n\n\t\t\t__iterator& operator++()\n\t\t\t{\n\t\t\t\tview_->as_cache().reset();\n\t\t\t\treturn *this;\n\t\t\t}\n\n\t\t\t__iterator& operator++(int)\n\t\t\t{ return ++(*this); }\n\t\tprivate:\n\t\t\tgenerate_view* view_{};\n\n\t\t\ttemplate<class Self>\n\t\t\tstatic auto&& deref_impl(Self&& self)\n\t\t\t{\n\t\t\t\tauto& view = *self.view_;\n\t\t\t\tif (!view.as_cache()) {\n\t\t\t\t\tview.as_cache().emplace(view.get()());\n\t\t\t\t}\n\t\t\t\tusing reference_t = std::conditional_t<\n\t\t\t\t\tstd::is_lvalue_reference_v<result_t>,\n\t\t\t\t\tresult_t,\n\t\t\t\t\t__uncvref<result_t>&&>;\n\t\t\t\treturn static_cast<reference_t>(*view.as_cache());\n\t\t\t}\n\t\t};\n\t} // namespace ext\n\n\tnamespace views::ext {\n\t\tstruct __generate_fn : detail::__pipeable<__generate_fn> {\n\t\t\ttemplate<class F>\n\t\t\tconstexpr auto operator()(F&& f) const\n\t\t\tSTL2_NOEXCEPT_REQUIRES_RETURN(\n\t\t\t\t__stl2::ext::generate_view{std::forward<F>(f)}\n\t\t\t)\n\t\t};\n\n\t\tinline constexpr __generate_fn generate{};\n\t} // namespace views::ext\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_VIEW_GENERATE_HPP\n"
  },
  {
    "path": "include/stl2/view/indirect.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_INDIRECT_HPP\n#define STL2_VIEW_INDIRECT_HPP\n\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<view Rng>\n\t\trequires\n\t\t\tinput_range<Rng> &&\n\t\t\treadable<std::remove_reference_t<iter_reference_t<iterator_t<Rng>>>>\n\t\tclass STL2_EMPTY_BASES indirect_view\n\t\t: public view_interface<indirect_view<Rng>>\n\t\t, private detail::ebo_box<Rng, indirect_view<Rng>> {\n\t\t\tusing base_t = detail::ebo_box<Rng, indirect_view<Rng>>;\n\t\t\tusing base_t::get;\n\n\t\t\ttemplate<bool IsConst>\n\t\t\tusing sentinel_t = __stl2::sentinel_t<__maybe_const<IsConst, Rng>>;\n\t\t\ttemplate<bool IsConst>\n\t\t\tusing iterator_t = __stl2::iterator_t<__maybe_const<IsConst, Rng>>;\n\n\t\t\ttemplate<bool IsConst>\n\t\t\tstruct sentinel {\n\t\t\t\tsentinel_t<IsConst> s_;\n\t\t\t};\n\t\t\ttemplate<bool IsConst>\n\t\t\tstruct cursor {\n\t\t\t\titerator_t<IsConst> it_;\n\n\t\t\t\tdecltype(auto) read() const { return **it_; }\n\t\t\t\tvoid next() { ++it_; }\n\t\t\t\tvoid prev()\n\t\t\t\trequires bidirectional_iterator<iterator_t<IsConst>>\n\t\t\t\t{ --it_; }\n\n\t\t\t\tbool equal(const cursor& that) const\n\t\t\t\trequires sentinel_for<iterator_t<IsConst>, iterator_t<IsConst>>\n\t\t\t\t{ return it_ == that.it_; }\n\t\t\t\tbool equal(const sentinel<IsConst>& s) const\n\t\t\t\t{ return it_ == s.s_; }\n\n\t\t\t\titer_difference_t<iterator_t<IsConst>> distance_to(const cursor& that) const\n\t\t\t\trequires sized_sentinel_for<iterator_t<IsConst>, iterator_t<IsConst>>\n\t\t\t\t{ return that.it_ - it_; }\n\t\t\t\titer_difference_t<iterator_t<IsConst>>\n\t\t\t\tdistance_to(const sentinel<IsConst>& that) const\n\t\t\t\trequires sized_sentinel_for<sentinel_t<IsConst>, iterator_t<IsConst>>\n\t\t\t\t{ return that.s_ - it_; }\n\n\t\t\t\tvoid advance(iter_difference_t<iterator_t<IsConst>> n)\n\t\t\t\trequires random_access_iterator<iterator_t<IsConst>>\n\t\t\t\t{ it_ += n; }\n\t\t\t};\n\t\tpublic:\n\t\t\tindirect_view() requires default_initializable<Rng> = default;\n\t\t\tindirect_view(Rng rng) : base_t{std::move(rng)} {}\n\n\t\t\tbasic_iterator<cursor<false>> begin()\n\t\t\trequires (!range<Rng const>)\n\t\t\t{ return basic_iterator<cursor<false>>{cursor<false>{__stl2::begin(get())}}; }\n\n\t\t\tsentinel<false> end()\n\t\t\trequires (!range<Rng const>)\n\t\t\t{ return sentinel<false>{__stl2::end(get())}; }\n\n\t\t\tbasic_iterator<cursor<false>> end()\n\t\t\trequires (!range<Rng const> && common_range<Rng>)\n\t\t\t{ return basic_iterator<cursor<false>>{cursor<false>{__stl2::end(get())}}; }\n\n\t\t\tauto size()\n\t\t\trequires (!range<Rng const> && sized_range<Rng>)\n\t\t\t{ return __stl2::size(get()); }\n\n\t\t\tbasic_iterator<cursor<true>> begin() const\n\t\t\trequires range<Rng const>\n\t\t\t{ return basic_iterator<cursor<true>>{cursor<true>{__stl2::begin(get())}}; }\n\n\t\t\tsentinel<true> end() const\n\t\t\trequires range<Rng const>\n\t\t\t{ return sentinel<true>{__stl2::end(get())}; }\n\n\t\t\tbasic_iterator<cursor<true>> end() const\n\t\t\trequires common_range<Rng const>\n\t\t\t{ return basic_iterator<cursor<true>>{cursor<true>{__stl2::end(get())}}; }\n\n\t\t\tauto size() const\n\t\t\trequires sized_range<Rng const>\n\t\t\t{ return __stl2::size(get()); }\n\t\t};\n\n\t\ttemplate<class Rng>\n\t\tindirect_view(Rng&&) -> indirect_view<all_view<Rng>>;\n\t} // namespace ext\n\n\ttemplate<class V>\n\tinline constexpr bool enable_view<ext::indirect_view<V>> = true;\n\n\tnamespace views::ext {\n\t\tstruct __indirect_fn : detail::__pipeable<__indirect_fn> {\n\t\t\ttemplate<class Rng>\n\t\t\tconstexpr auto operator()(Rng&& rng) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\t__stl2::ext::indirect_view{all(std::forward<Rng>(rng))}\n\t\t\t)\n\t\t};\n\n\t\tinline constexpr __indirect_fn indirect{};\n\t} // namespace views::ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/iota.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2016\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_IOTA_HPP\n#define STL2_VIEW_IOTA_HPP\n\n#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/compare.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<weakly_incrementable I>\n\t\tstruct iota_view_iterator_base {\n\t\t\tusing iterator_category = __stl2::input_iterator_tag;\n\t\t};\n\t\ttemplate<incrementable I>\n\t\tstruct iota_view_iterator_base<I> {\n\t\t\tusing iterator_category = __stl2::forward_iterator_tag;\n\t\t};\n\t\ttemplate<ext::Decrementable I>\n\t\tstruct iota_view_iterator_base<I> {\n\t\t\tusing iterator_category = __stl2::bidirectional_iterator_tag;\n\t\t};\n\t\ttemplate<ext::RandomAccessIncrementable I>\n\t\tstruct iota_view_iterator_base<I> {\n\t\t\tusing iterator_category = __stl2::random_access_iterator_tag;\n\t\t};\n\t}\n\n\ttemplate<weakly_incrementable I, semiregular Bound = unreachable_sentinel_t>\n\trequires WeaklyEqualityComparable<I, Bound>\n\tstruct iota_view;\n\n\tnamespace __iota_view_detail {\n\t\tstruct __adl_hook {};\n\n\t\t// Extension: iota_view models forwarding-range, as suggested by\n\t\t// https://github.com/ericniebler/stl2/issues/575\n\t\ttemplate<class I, class S>\n\t\tconstexpr iterator_t<iota_view<I, S>> begin(iota_view<I, S> r) {\n\t\t\treturn r.begin();\n\t\t}\n\t\ttemplate<class I, class S>\n\t\tconstexpr sentinel_t<iota_view<I, S>> end(iota_view<I, S> r) {\n\t\t\treturn r.end();\n\t\t}\n\t}\n\n\ttemplate<weakly_incrementable I, semiregular Bound>\n\trequires WeaklyEqualityComparable<I, Bound>\n\tstruct STL2_EMPTY_BASES iota_view\n\t: private __iota_view_detail::__adl_hook\n\t, view_interface<iota_view<I, Bound>> {\n\tprivate:\n\t\tstruct __iterator;\n\t\tstruct __sentinel;\n\n\t\tI value_{};\n\t\tBound bound_{};\n\tpublic:\n\t\tiota_view() = default;\n\t\t/// \\pre: `Bound{}` is reachable from `value`\n\t\tconstexpr explicit iota_view(I value)\n\t\t: value_(value), bound_{} {}\n\t\ttemplate<class II = I, class BB = Bound>\n\t\tconstexpr iota_view(meta::id_t<II> value, meta::id_t<BB> bound)\n\t\t: value_(value), bound_(bound) {}\n\n\t\tconstexpr __iterator begin() const\n\t\t{ return __iterator{value_}; }\n\t\tconstexpr __sentinel end() const\n\t\t{ return __sentinel{bound_}; }\n\t\tconstexpr __iterator end() const requires same_as<I, Bound>\n\t\t{ return __iterator{bound_}; }\n\n\t\ttemplate<class II = I, class BB = Bound> // gcc_bugs_bugs_bugs\n\t\tconstexpr auto size() const\n\t\trequires (same_as<II, BB> && ext::RandomAccessIncrementable<II>) ||\n\t\t\t(integral<II> && integral<BB>) ||\n\t\t\tsized_sentinel_for<BB, II>\n\t\t{ return bound_ - value_; }\n\t};\n\n\ttemplate<weakly_incrementable I, semiregular Bound>\n\trequires WeaklyEqualityComparable<I, Bound> &&\n\t\t(!integral<I> || !integral<Bound> || std::is_signed_v<I> == std::is_signed_v<Bound>)\n\tiota_view(I, Bound) -> iota_view<I, Bound>;\n\n\ttemplate<weakly_incrementable I, semiregular Bound>\n\trequires WeaklyEqualityComparable<I, Bound>\n\tstruct iota_view<I, Bound>::__iterator\n\t: detail::iota_view_iterator_base<I> {\n\t\tfriend __sentinel;\n\n\t\tusing value_type = I;\n\t\tusing difference_type = iter_difference_t<I>;\n\n\t\t__iterator() = default;\n\t\tconstexpr explicit __iterator(I value)\n\t\t: value_(value) {}\n\n\t\tconstexpr I operator*() const noexcept(std::is_nothrow_copy_constructible_v<I>)\n\t\t{ return value_; }\n\n\t\tconstexpr __iterator& operator++()\n\t\t{\n\t\t\t++value_;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr void operator++(int)\n\t\t{ ++*this; }\n\t\tconstexpr __iterator operator++(int) requires incrementable<I>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr __iterator& operator--() requires ext::Decrementable<I>\n\t\t{\n\t\t\t--value_;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr __iterator operator--(int) requires ext::Decrementable<I>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t--*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr __iterator& operator+=(difference_type n)\n\t\trequires ext::RandomAccessIncrementable<I>\n\t\t{\n\t\t\tvalue_ += n;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr __iterator& operator-=(difference_type n)\n\t\trequires ext::RandomAccessIncrementable<I>\n\t\t{\n\t\t\tvalue_ -= n;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr I operator[](difference_type n) const\n\t\trequires ext::RandomAccessIncrementable<I>\n\t\t{ return value_ + n; }\n\n\t\tfriend constexpr bool operator==(const __iterator& x, const __iterator& y)\n\t\trequires equality_comparable<I>\n\t\t{ return x.value_ == y.value_; }\n\t\tfriend constexpr bool operator!=(const __iterator& x, const __iterator& y)\n\t\trequires equality_comparable<I>\n\t\t{ return !(x == y); }\n\n\t\tfriend constexpr bool operator<(const __iterator& x, const __iterator& y)\n\t\trequires totally_ordered<I>\n\t\t{ return x.value_ < y.value_; }\n\t\tfriend constexpr bool operator>(const __iterator& x, const __iterator& y)\n\t\trequires totally_ordered<I>\n\t\t{ return y < x; }\n\t\tfriend constexpr bool operator<=(const __iterator& x, const __iterator& y)\n\t\trequires totally_ordered<I>\n\t\t{ return !(y < x); }\n\t\tfriend constexpr bool operator>=(const __iterator& x, const __iterator& y)\n\t\trequires totally_ordered<I>\n\t\t{ return !(x < y); }\n\n\t\tfriend constexpr __iterator operator+(__iterator i, difference_type n)\n\t\trequires ext::RandomAccessIncrementable<I>\n\t\t{ return __iterator{*i + n}; }\n\t\tfriend constexpr __iterator operator+(difference_type n, __iterator i)\n\t\trequires ext::RandomAccessIncrementable<I>\n\t\t{ return i + n; }\n\n\t\tfriend constexpr __iterator operator-(__iterator i, difference_type n)\n\t\trequires ext::RandomAccessIncrementable<I>\n\t\t{ return i + -n; }\n\t\tfriend constexpr difference_type operator-(const __iterator& x, const __iterator& y)\n\t\trequires ext::RandomAccessIncrementable<I>\n\t\t{ return *x - *y; }\n\n\tprivate:\n\t\tI value_{};\n\t};\n\n\ttemplate<weakly_incrementable I, semiregular Bound>\n\trequires WeaklyEqualityComparable<I, Bound>\n\tstruct iota_view<I, Bound>::__sentinel {\n\t\t__sentinel() = default;\n\t\tconstexpr explicit __sentinel(Bound bound)\n\t\t: bound_(bound) {}\n\n\t\tfriend constexpr bool operator==(const __iterator& x, const __sentinel& y)\n\t\t{ return y.equal(x); }\n\t\tfriend constexpr bool operator==(const __sentinel& x, const __iterator& y)\n\t\t{ return x.equal(y); }\n\t\tfriend constexpr bool operator!=(const __iterator& x, const __sentinel& y)\n\t\t{ return !y.equal(x); }\n\t\tfriend constexpr bool operator!=(const __sentinel& x, const __iterator& y)\n\t\t{ return !x.equal(y); }\n\n\tprivate:\n\t\tconstexpr bool equal(const __iterator& i) const {\n\t\t\treturn i.value_ == bound_;\n\t\t}\n\n\t\tBound bound_;\n\t};\n\n\tnamespace views {\n\t\tstruct __iota_fn {\n\t\t\ttemplate<weakly_incrementable I>\n\t\t\tconstexpr auto operator()(I value) const {\n\t\t\t\treturn iota_view{value};\n\t\t\t}\n\n\t\t\ttemplate<weakly_incrementable I, semiregular Bound>\n\t\t\trequires WeaklyEqualityComparable<I, Bound> &&\n\t\t\t\t(!integral<I> || !integral<Bound> ||\n\t\t\t\t\tstd::is_signed_v<I> == std::is_signed_v<Bound>)\n\t\t\tconstexpr auto operator()(I value, Bound bound) const {\n\t\t\t\treturn iota_view{value, bound};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __iota_fn iota{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/istream.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2013-present\n//  Copyright Casey Carter 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_ISTREAM_HPP\n#define STL2_VIEW_ISTREAM_HPP\n\n#include <istream>\n#include <memory>\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/iostream/concepts.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<movable Val>\n\t\trequires default_initializable<Val> && StreamExtractable<Val>\n\t\tstruct STL2_EMPTY_BASES istream_view\n\t\t: view_interface<istream_view<Val>>\n\t\t, detail::semiregular_box<Val> {\n\t\tprivate:\n\t\t\tstruct __iterator;\n\n\t\t\tdetail::raw_ptr<std::istream> sin_ = nullptr;\n\n\t\t\tvoid next_() { *sin_ >> this->get(); }\n\t\tpublic:\n\t\t\tistream_view() = default;\n\t\t\texplicit constexpr istream_view(std::istream& sin)\n\t\t\tnoexcept(std::is_nothrow_default_constructible_v<Val>)\n\t\t\t: sin_{std::addressof(sin)} {}\n\n\t\t\t__iterator begin() {\n\t\t\t\tnext_(); // prime the pump\n\t\t\t\treturn __iterator{*this};\n\t\t\t}\n\n\t\t\tconstexpr default_sentinel_t end() const noexcept { return {}; }\n\t\t};\n\n\t\ttemplate<movable Val>\n\t\trequires default_initializable<Val> && StreamExtractable<Val>\n\t\tstruct istream_view<Val>::__iterator {\n\t\t\tusing iterator_category = input_iterator_tag;\n\t\t\tusing difference_type = std::ptrdiff_t;\n\t\t\tusing value_type = Val;\n\n\t\t\t__iterator() = default;\n\t\t\texplicit constexpr __iterator(istream_view<Val>& parent) noexcept\n\t\t\t: parent_{std::addressof(parent)} {}\n\n\t\t\t__iterator& operator++() {\n\t\t\t\tparent_->next_();\n\t\t\t\treturn *this;\n\t\t\t}\n\t\t\tvoid operator++(int) { ++*this; }\n\n\t\t\tVal& operator*() const { return parent_->get(); }\n\t\t\tVal* operator->() const { return std::addressof(parent_->get()); }\n\n\t\t\tfriend bool operator==(__iterator x, default_sentinel_t) {\n\t\t\t\treturn x.at_end();\n\t\t\t}\n\t\t\tfriend bool operator==(default_sentinel_t, __iterator x) {\n\t\t\t\treturn x.at_end();\n\t\t\t}\n\t\t\tfriend bool operator!=(__iterator x, default_sentinel_t) {\n\t\t\t\treturn !x.at_end();\n\t\t\t}\n\t\t\tfriend bool operator!=(default_sentinel_t, __iterator x) {\n\t\t\t\treturn !x.at_end();\n\t\t\t}\n\t\tprivate:\n\t\t\tbool at_end() const { return !*parent_->sin_; }\n\t\t\tdetail::raw_ptr<istream_view<Val>> parent_ = nullptr;\n\t\t};\n\t} // namespace ext\n\n\tnamespace views {\n\t\ttemplate<class Val>\n\t\trequires requires { typename __stl2::ext::istream_view<Val>; }\n\t\tstruct __istream_fn {\n\t\t\tconstexpr auto operator()(std::istream& sin) const noexcept\n\t\t\t{ return __stl2::ext::istream_view<Val>{sin}; }\n\t\t};\n\n\t\ttemplate<class Val>\n\t\tinline constexpr __istream_fn<Val> istream{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/join.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_JOIN_HPP\n#define STL2_VIEW_JOIN_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT _GLvalueRange = range<R> &&\n\t\t\tstd::is_reference_v<iter_reference_t<iterator_t<R>>>;\n\n\t\ttemplate<input_range Base>\n\t\tstruct join_view_iterator_base {\n\t\t\tusing iterator_category = __stl2::input_iterator_tag;\n\t\t};\n\t\ttemplate<forward_range Base>\n\t\trequires _GLvalueRange<Base> &&\n\t\t\tforward_range<iter_reference_t<iterator_t<Base>>>\n\t\tstruct join_view_iterator_base<Base> {\n\t\t\tusing iterator_category = __stl2::forward_iterator_tag;\n\t\t};\n\t\ttemplate<bidirectional_range Base>\n\t\trequires _GLvalueRange<Base> &&\n\t\t\tbidirectional_range<iter_reference_t<iterator_t<Base>>>\n\t\tstruct join_view_iterator_base<Base> {\n\t\t\tusing iterator_category = __stl2::bidirectional_iterator_tag;\n\t\t};\n\n\t\ttemplate<input_range InnerRng>\n\t\tstruct join_view_base {\n\t\t\t// Implements the PR for https://github.com/ericniebler/stl2#604\n\t\t\tmutable all_view<InnerRng> inner_ = all_view<InnerRng>();\n\t\t};\n\t\ttemplate<input_range InnerRng>\n\t\trequires std::is_reference_v<InnerRng>\n\t\tstruct join_view_base<InnerRng> {};\n\t}\n\n\ttemplate<input_range V>\n\trequires view<V> && input_range<iter_reference_t<iterator_t<V>>> &&\n\t\t(detail::_GLvalueRange<V> || view<iter_value_t<iterator_t<V>>>) // TODO: file LWG issue\n\tclass STL2_EMPTY_BASES join_view\n\t: public view_interface<join_view<V>>\n\t, detail::join_view_base<iter_reference_t<iterator_t<V>>> {\n\tprivate:\n\t\tusing InnerRng = iter_reference_t<iterator_t<V>>;\n\t\ttemplate<bool> struct __iterator;\n\t\ttemplate<bool> struct __sentinel;\n\n\t\tV base_ = V();\n\n\tpublic:\n\t\tjoin_view() = default;\n\t\tconstexpr explicit join_view(V base)\n\t\t: base_(std::move(base)) {}\n\n\t\tconstexpr auto begin() {\n\t\t\treturn __iterator<ext::simple_view<V>>{*this, __stl2::begin(base_)};\n\t\t}\n\n\t\t// Template to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\ttemplate<class ConstV = const V>\n\t\tconstexpr auto begin() const\n\t\trequires input_range<ConstV> && detail::_GLvalueRange<ConstV>\n\t\t{ return __iterator<true>{*this, __stl2::begin(base_)}; }\n\n\t\tconstexpr auto end() {\n\t\t\tif constexpr (forward_range<V> && detail::_GLvalueRange<V> &&\n\t\t\t              forward_range<InnerRng> && common_range<V> &&\n\t\t\t              common_range<InnerRng>) {\n\t\t\t\treturn __iterator<ext::simple_view<V>>{*this, __stl2::end(base_)};\n\t\t\t} else {\n\t\t\t\treturn __sentinel<ext::simple_view<V>>{*this};\n\t\t\t}\n\t\t}\n\n\t\t// Template to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\ttemplate<class ConstV = const V>\n\t\tconstexpr auto end() const\n\t\trequires input_range<ConstV> &&\n\t\t\tstd::is_reference_v<iter_reference_t<iterator_t<ConstV>>>\n\t\t{\n\t\t\tif constexpr (forward_range<ConstV> &&\n\t\t\t              // std::is_reference_v<iter_reference_t<iterator_t<ConstV>>> && // TODO: file LWG issue\n\t\t\t              forward_range<iter_reference_t<iterator_t<ConstV>>> &&\n\t\t\t              common_range<ConstV> &&\n\t\t\t              common_range<iter_reference_t<iterator_t<ConstV>>>) {\n\t\t\t\treturn __iterator<true>{*this, __stl2::end(base_)};\n\t\t\t} else {\n\t\t\t\treturn __sentinel<true>{*this};\n\t\t\t}\n\t\t}\n\t};\n\n\ttemplate<class R>\n\texplicit join_view(R&&) -> join_view<all_view<R>>;\n\n\ttemplate<input_range V> // TODO: file LWG issue\n\trequires view<V> && input_range<iter_reference_t<iterator_t<V>>> &&\n\t\t(detail::_GLvalueRange<V> || view<iter_value_t<iterator_t<V>>>)\n\ttemplate<bool Const>\n\tstruct join_view<V>::__iterator\n\t: detail::join_view_iterator_base<__maybe_const<Const, V>> {\n\tprivate:\n\t\tusing Base = __maybe_const<Const, V>;\n\t\tusing Parent = __maybe_const<Const, join_view>;\n\n\t\tstatic constexpr bool ref_is_glvalue = detail::_GLvalueRange<Base>;\n\n\t\titerator_t<Base> outer_ = iterator_t<Base>();\n\t\titerator_t<iter_reference_t<iterator_t<Base>>> inner_ =\n\t\t\titerator_t<iter_reference_t<iterator_t<Base>>>();\n\t\tParent* parent_ = nullptr;\n\n\t\tfriend __iterator<true>;\n\t\tfriend __sentinel<Const>;\n\n\t\tconstexpr void satisfy_() {\n\t\t\tauto update_inner_range =\n\t\t\t\t[this](iter_reference_t<iterator_t<Base>> x) -> auto& {\n\t\t\t\tif constexpr (ref_is_glvalue) return (x);\n\t\t\t\telse return (parent_->inner_ = views::all(std::move(x)));\n\t\t\t};\n\n\t\t\tfor (; outer_ != __stl2::end(parent_->base_); ++outer_) {\n\t\t\t\tauto& inner_range = update_inner_range(*outer_);\n\t\t\t\tinner_ = __stl2::begin(inner_range);\n\t\t\t\tif (inner_ != __stl2::end(inner_range)) return;\n\t\t\t}\n\t\t\t// needed for symmetric iterator comparison:\n\t\t\tif constexpr (ref_is_glvalue) {\n\t\t\t\tinner_ = iterator_t<iter_reference_t<iterator_t<Base>>>();\n\t\t\t}\n\t\t}\n\tpublic:\n\t\tusing value_type =\n\t\t\titer_value_t<iterator_t<iter_reference_t<iterator_t<Base>>>>;\n\t\tusing difference_type = common_type_t<\n\t\t\titer_difference_t<iterator_t<Base>>,\n\t\t\titer_difference_t<iterator_t<iter_reference_t<iterator_t<Base>>>>>;\n\n\t\t__iterator() = default;\n\n\t\tconstexpr __iterator(Parent& parent, iterator_t<V> outer)\n\t\t: outer_(std::move(outer)), parent_(std::addressof(parent)) {\n\t\t\tsatisfy_();\n\t\t}\n\n\t\tconstexpr __iterator(__iterator<!Const> i) requires Const &&\n\t\t\tconvertible_to<iterator_t<V>, iterator_t<Base>> &&\n\t\t\tconvertible_to<\n\t\t\t\titerator_t<InnerRng>,\n\t\t\t\titerator_t<iter_reference_t<iterator_t<Base>>>>\n\t\t: outer_(std::move(i.outer_))\n\t\t, inner_(std::move(i.inner_))\n\t\t, parent_(i.parent_) {}\n\n\t\tconstexpr decltype(auto) operator*() const { return *inner_; }\n\n\t\tconstexpr iterator_t<Base> operator->() const\n\t\trequires __has_arrow<iterator_t<Base>> {\n\t\t\treturn inner_;\n\t\t}\n\n\t\tconstexpr __iterator& operator++() {\n\t\t\tauto&& inner_rng = [this]() -> auto&& {\n\t\t\t\tif constexpr (ref_is_glvalue) return *outer_;\n\t\t\t\telse return parent_->inner_;\n\t\t\t}();\n\n\t\t\tif (++inner_ == __stl2::end(inner_rng)) {\n\t\t\t\t++outer_;\n\t\t\t\tsatisfy_();\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr void operator++(int) { ++*this; }\n\n\t\tconstexpr __iterator operator++(int)\n\t\trequires ref_is_glvalue && forward_range<Base> &&\n\t\t\tforward_range<iter_reference_t<iterator_t<Base>>>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr __iterator& operator--()\n\t\trequires ref_is_glvalue && bidirectional_range<Base> &&\n\t\t\tbidirectional_range<iter_reference_t<iterator_t<Base>>> &&\n\t\t\tcommon_range<iter_reference_t<iterator_t<Base>>>\n\t\t{\n\t\t\tif (outer_ == __stl2::end(parent_->base_)) {\n\t\t\t\tinner_ = __stl2::end(*--outer_);\n\t\t\t}\n\t\t\twhile (inner_ == __stl2::begin(*outer_)) {\n\t\t\t\tinner_ = __stl2::end(*--outer_);\n\t\t\t}\n\t\t\t--inner_;\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr __iterator operator--(int)\n\t\trequires ref_is_glvalue && bidirectional_range<Base> &&\n\t\t\tbidirectional_range<iter_reference_t<iterator_t<Base>>> &&\n\t\t\tcommon_range<iter_reference_t<iterator_t<Base>>>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t--*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tfriend constexpr bool operator==(const __iterator& x, const __iterator& y)\n\t\trequires ref_is_glvalue && equality_comparable<iterator_t<Base>> &&\n\t\t\tequality_comparable<iterator_t<iter_reference_t<iterator_t<Base>>>>\n\t\t{ return bool(x.outer_ == y.outer_) && bool(x.inner_ == y.inner_); } // TODO: file LWG issue\n\n\t\tfriend constexpr bool operator!=(const __iterator& x, const __iterator& y)\n\t\trequires ref_is_glvalue && equality_comparable<iterator_t<Base>> &&\n\t\t\tequality_comparable<iterator_t<iter_reference_t<iterator_t<Base>>>>\n\t\t{ return !(x == y); }\n\n\t\tfriend constexpr decltype(auto) iter_move(const __iterator& i)\n\t\tnoexcept(noexcept(__stl2::iter_move(i.inner_)))\n\t\t{ return __stl2::iter_move(i.inner_); }\n\n\t\tfriend constexpr void iter_swap(const __iterator& x, const __iterator& y)\n\t\tnoexcept(noexcept(__stl2::iter_swap(x.inner_, y.inner_)))\n\t\t{ __stl2::iter_swap(x.inner_, y.inner_); }\n\t};\n\n\ttemplate<input_range V>\n\trequires view<V> && input_range<iter_reference_t<iterator_t<V>>> &&\n\t\t(detail::_GLvalueRange<V> || view<iter_value_t<iterator_t<V>>>)\n\ttemplate<bool Const>\n\tstruct join_view<V>::__sentinel {\n\tprivate:\n\t\tfriend __sentinel<true>;\n\t\tusing Base = __maybe_const<Const, V>;\n\t\tusing Parent = __maybe_const<Const, join_view>;\n\n\t\tsentinel_t<Base> end_ = sentinel_t<Base>();\n\n\t\tconstexpr bool equal(const __iterator<Const>& i) const {\n\t\t\treturn i.outer_ == end_;\n\t\t}\n\tpublic:\n\t\t__sentinel() = default;\n\n\t\tconstexpr explicit __sentinel(Parent& parent)\n\t\t: end_(__stl2::end(parent.base_)) {}\n\n\t\tconstexpr __sentinel(__sentinel<!Const> s) requires Const &&\n\t\t\tconvertible_to<sentinel_t<V>, sentinel_t<Base>>\n\t\t: end_(std::move(s.end_)) {}\n\n\t\tfriend constexpr bool operator==(const __iterator<Const>& x, const __sentinel& y)\n\t\t{ return y.equal(x); }\n\t\tfriend constexpr bool operator==(const __sentinel& x, const __iterator<Const>& y)\n\t\t{ return x.equal(y); }\n\t\tfriend constexpr bool operator!=(const __iterator<Const>& x, const __sentinel& y)\n\t\t{ return !y.equal(x); }\n\t\tfriend constexpr bool operator!=(const __sentinel& x, const __iterator<Const>& y)\n\t\t{ return !x.equal(y); }\n\t};\n\n\tnamespace views {\n\t\tstruct __join_fn : detail::__pipeable<__join_fn> {\n\t\t\ttemplate<class R>\n\t\t\tconstexpr auto operator()(R&& r) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\tjoin_view{static_cast<R&&>(r)}\n\t\t\t)\n\t\t};\n\n\t\tinline constexpr __join_fn join{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/move.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_MOVE_HPP\n#define STL2_VIEW_MOVE_HPP\n\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/move_iterator.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<view Rng>\n\t\trequires input_range<Rng>\n\t\tclass STL2_EMPTY_BASES move_view\n\t\t: detail::ebo_box<Rng, move_view<Rng>>\n\t\t, public view_interface<move_view<Rng>> {\n\t\t\tusing base_t = detail::ebo_box<Rng, move_view<Rng>>;\n\t\t\tusing base_t::get;\n\t\tpublic:\n\t\t\tmove_view() requires default_initializable<Rng> = default;\n\n\t\t\tconstexpr move_view(Rng rng)\n\t\t\tnoexcept(std::is_nothrow_move_constructible<Rng>::value)\n\t\t\t: base_t{std::move(rng)} {}\n\n\t\t\tmove_iterator<iterator_t<Rng>> begin() const\n\t\t\trequires range<const Rng>\n\t\t\t{ return __stl2::make_move_iterator(__stl2::begin(get())); }\n\t\t\tmove_sentinel<sentinel_t<Rng>> end() const\n\t\t\trequires range<const Rng>\n\t\t\t{ return __stl2::make_move_sentinel(__stl2::end(get())); }\n\t\t\tmove_iterator<iterator_t<Rng>> end() const\n\t\t\trequires range<const Rng> && common_range<const Rng>\n\t\t\t{ return __stl2::make_move_iterator(__stl2::end(get())); }\n\n\t\t\tauto size() const\n\t\t\trequires range<const Rng> && sized_range<const Rng>\n\t\t\t{ return __stl2::size(get()); }\n\t\t\tbool empty() const\n\t\t\trequires range<const Rng> && requires(const Rng& r) { __stl2::empty(r); }\n\t\t\t{ return __stl2::empty(get()); }\n\n\t\t\tmove_iterator<iterator_t<Rng>> begin()\n\t\t\trequires (!range<const Rng>)\n\t\t\t{ return __stl2::make_move_iterator(__stl2::begin(get())); }\n\t\t\tmove_sentinel<sentinel_t<Rng>> end()\n\t\t\trequires (!range<const Rng>)\n\t\t\t{ return __stl2::make_move_sentinel(__stl2::end(get())); }\n\t\t\tmove_iterator<iterator_t<Rng>> end()\n\t\t\trequires (!range<const Rng> && common_range<Rng>)\n\t\t\t{ return __stl2::make_move_iterator(__stl2::end(get())); }\n\n\t\t\tauto size()\n\t\t\trequires (!range<const Rng> && sized_range<Rng>)\n\t\t\t{ return __stl2::size(get()); }\n\t\t\tbool empty()\n\t\t\trequires (!range<const Rng>)\n\t\t\t{ return __stl2::empty(get()); }\n\t\t};\n\t} // namespace ext\n\n\ttemplate<class V>\n\tinline constexpr bool enable_view<ext::move_view<V>> = true;\n\n\tnamespace views {\n\t\tstruct __move_fn : detail::__pipeable<__move_fn> {\n\t\t\ttemplate<input_range Rng>\n\t\t\trequires viewable_range<Rng>\n\t\t\tconstexpr __stl2::ext::move_view<all_view<Rng>> operator()(Rng&& rng) const {\n\t\t\t\treturn __stl2::ext::move_view<all_view<Rng>>{\n\t\t\t\t\tviews::all(std::forward<Rng>(rng))};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __move_fn move{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/ref.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_REF_HPP\n#define STL2_VIEW_REF_HPP\n\n#include <memory>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\t// ref_view [ranges.view.ref]\n\ttemplate<range R>\n\trequires std::is_object_v<R>\n\tstruct STL2_EMPTY_BASES ref_view;\n\n\t// Not an extension: P1252 makes this user-visible\n\tnamespace __ref_view_detail {\n\t\tstruct __adl_hook {};\n\n\t\t// Not to spec: should be hidden friends.\n\t\ttemplate<class R>\n\t\tconstexpr iterator_t<R> begin(ref_view<R> r) {\n\t\t\treturn r.begin();\n\t\t}\n\t\ttemplate<class R>\n\t\tconstexpr sentinel_t<R> end(ref_view<R> r) {\n\t\t\treturn r.end();\n\t\t}\n\t}\n\n\ttemplate<range R>\n\trequires std::is_object_v<R>\n\tstruct STL2_EMPTY_BASES ref_view\n\t: private __ref_view_detail::__adl_hook\n\t, view_interface<ref_view<R>> {\n\tprivate:\n\t\tR* r_ = nullptr;\n\n\t\tstatic void fun(R&) noexcept; // not defined\n\t\tstatic void fun(R&&) = delete;\n\tpublic:\n\t\tconstexpr ref_view() noexcept = default;\n\n\t\ttemplate<_NotSameAs<ref_view> T>\n\t\trequires requires(T&& t) { fun(static_cast<T&&>(t)); }\n\t\tconstexpr ref_view(T&& t)\n\t\tnoexcept(is_nothrow_convertible_v<T, R&>) // strengthened\n\t\t: r_{std::addressof(static_cast<R&>(static_cast<T&&>(t)))} {}\n\n\t\tconstexpr R& base() const noexcept { return *r_; }\n\n\t\tconstexpr iterator_t<R> begin() const { return __stl2::begin(*r_); }\n\t\tconstexpr sentinel_t<R> end() const { return __stl2::end(*r_); }\n\n\t\tconstexpr bool empty() const requires detail::CanEmpty<R> {\n\t\t\treturn __stl2::empty(*r_);\n\t\t}\n\n\t\tconstexpr auto size() const requires sized_range<R> {\n\t\t\treturn __stl2::size(*r_);\n\t\t}\n\n\t\tconstexpr auto data() const requires contiguous_range<R> {\n\t\t\treturn __stl2::data(*r_);\n\t\t}\n\t};\n\n\t// This deduction guide is the P/R for LWG 3173\n\ttemplate<class R>\n\tref_view(R&) -> ref_view<R>;\n\n\tnamespace views::ext {\n\t\tstruct __ref_fn : detail::__pipeable<__ref_fn> {\n\t\t\ttemplate<class R>\n\t\t\tauto operator()(R&& r) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\tref_view{std::forward<R>(r)}\n\t\t\t)\n\t\t};\n\n\t\tinline constexpr __ref_fn ref{};\n\t} // namespace views::ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/repeat.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_REPEAT_HPP\n#define STL2_VIEW_REPEAT_HPP\n\n#include <memory>\n#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<copy_constructible_object T>\n\t\tstruct STL2_EMPTY_BASES repeat_view\n\t\t: private detail::semiregular_box<T>\n\t\t, view_interface<repeat_view<T>>\n\t\t{\n\t\tprivate:\n\t\t\tusing storage_t = detail::semiregular_box<T>;\n\t\t\tusing storage_t::get;\n\n\t\t\ttemplate<bool IsConst>\n\t\t\tstruct cursor {\n\t\t\tprivate:\n\t\t\t\tfriend cursor<true>;\n\t\t\t\tusing E = __maybe_const<IsConst, T>;\n\t\t\t\tdetail::raw_ptr<E> value_;\n\n\t\t\tpublic:\n\t\t\t\tcursor() = default;\n\t\t\t\tconstexpr explicit cursor(__maybe_const<IsConst, repeat_view>& r) noexcept\n\t\t\t\t: value_{std::addressof(r.get())} {}\n\t\t\t\tconstexpr cursor(const cursor<!IsConst>& that) noexcept requires IsConst\n\t\t\t\t: value_{that.value_} {}\n\n\t\t\t\tconstexpr E& read() const noexcept\n\t\t\t\t{ return *value_; }\n\t\t\t\tconstexpr E* arrow() const noexcept\n\t\t\t\t{ return value_; }\n\t\t\t\tconstexpr bool equal(const cursor&) const noexcept { return true; }\n\t\t\t\tconstexpr void next() noexcept {}\n\t\t\t\tconstexpr void prev() noexcept {}\n\t\t\t\tconstexpr void advance(std::ptrdiff_t) noexcept {}\n\t\t\t\tconstexpr std::ptrdiff_t distance_to(const cursor&) const noexcept\n\t\t\t\t{ return 0; }\n\t\t\t};\n\n\t\tpublic:\n\t\t\trepeat_view() = default;\n\t\t\ttemplate<_NotSameAs<repeat_view> U>\n\t\t\trequires convertible_to<U, T>\n\t\t\texplicit constexpr repeat_view(U&& u)\n\t\t\tnoexcept(std::is_nothrow_constructible_v<T, U>)\n\t\t\t: storage_t{static_cast<U&&>(u)} {}\n\n\t\t\tconstexpr T& value() noexcept { return get(); }\n\t\t\tconstexpr const T& value() const noexcept { return get(); }\n\n\t\t\tconstexpr basic_iterator<cursor<false>> begin() noexcept\n\t\t\t{ return basic_iterator{cursor<false>{*this}}; }\n\t\t\tconstexpr basic_iterator<cursor<true>> begin() const noexcept\n\t\t\t{ return basic_iterator{cursor<true>{*this}}; }\n\n\t\t\tconstexpr unreachable_sentinel_t end() const noexcept { return {}; }\n\t\t};\n\n\t\ttemplate<class T>\n\t\trepeat_view(T) -> repeat_view<T>;\n\t} // namespace ext\n\n\tnamespace views::ext {\n\t\tstruct __repeat_fn {\n\t\t\ttemplate<class T>\n\t\t\tconstexpr auto operator()(T&& t) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\t__stl2::ext::repeat_view{static_cast<T&&>(t)}\n\t\t\t)\n\t\t};\n\n\t\tinline constexpr __repeat_fn repeat{};\n\t} // namespace views::ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/repeat_n.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_REPEAT_N_HPP\n#define STL2_VIEW_REPEAT_N_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/view/repeat.hpp>\n#include <stl2/view/take_exactly.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<copy_constructible_object T>\n\t\tusing repeat_n_view = take_exactly_view<repeat_view<T>>;\n\t} // namespace ext\n\n\tnamespace views::ext {\n\t\tstruct __repeat_n_fn {\n\t\tprivate:\n\t\ttemplate<class T> using V = __stl2::ext::repeat_n_view<__uncvref<T>>;\n\t\tpublic:\n\t\t\ttemplate<class T>\n\t\t\tconstexpr auto operator()(T&& t, std::ptrdiff_t const n) const\n\t\t\tnoexcept(noexcept(V<T>{repeat(static_cast<T&&>(t)), n}))\n\t\t\trequires requires { V<T>{repeat(static_cast<T&&>(t)), n}; } {\n\t\t\t\tSTL2_EXPECT(n >= 0);\n\t\t\t\treturn V<T>{repeat(static_cast<T&&>(t)), n};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __repeat_n_fn repeat_n{};\n\t} // namespace views::ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/reverse.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_REVERSE_HPP\n#define STL2_VIEW_REVERSE_HPP\n\n#include <stl2/detail/cached_position.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/reverse_iterator.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<view V>\n\trequires bidirectional_range<V>\n\tclass STL2_EMPTY_BASES reverse_view\n\t: public view_interface<reverse_view<V>>\n\t, private detail::cached_position<V, reverse_view<V>, !common_range<V>> {\n\tprivate:\n\t\tV base_ = V();\n\n\t\tconstexpr auto& end_() noexcept {\n\t\t\treturn static_cast<typename reverse_view::cached_position&>(*this);\n\t\t}\n\tpublic:\n\t\treverse_view() = default;\n\n\t\tconstexpr explicit reverse_view(V base)\n\t\t: base_{std::move(base)} {}\n\n\t\tconstexpr V base() const { return base_; }\n\n\t\tconstexpr reverse_iterator<iterator_t<V>> begin() {\n\t\t\tif constexpr (common_range<V>) {\n\t\t\t\treturn reverse_iterator<iterator_t<V>>{__stl2::end(base_)};\n\t\t\t} else {\n\t\t\t\tconst auto cached = static_cast<bool>(end_());\n\t\t\t\titerator_t<V> first = cached\n\t\t\t\t\t? end_().get(base_)\n\t\t\t\t\t: next(__stl2::begin(base_), __stl2::end(base_));\n\t\t\t\tif (!cached)\n\t\t\t\t\tend_().set(base_, first);\n\t\t\t\treturn reverse_iterator<iterator_t<V>>{std::move(first)};\n\t\t\t}\n\t\t}\n\n\t\tconstexpr auto begin() const requires common_range<const V> {\n\t\t\treturn reverse_iterator<iterator_t<const V>>{__stl2::end(base_)};\n\t\t}\n\n\t\tconstexpr reverse_iterator<iterator_t<V>> end() {\n\t\t\treturn reverse_iterator<iterator_t<V>>{__stl2::begin(base_)};\n\t\t}\n\t\tconstexpr auto end() const requires common_range<const V> {\n\t\t\treturn reverse_iterator<iterator_t<const V>>{__stl2::begin(base_)};\n\t\t}\n\n\t\tconstexpr auto size() requires sized_range<V> {\n\t\t\treturn __stl2::size(base_);\n\t\t}\n\t\tconstexpr auto size() const requires sized_range<const V> {\n\t\t\treturn __stl2::size(base_);\n\t\t}\n\t};\n\n\ttemplate<class R>\n\treverse_view(R&&) -> reverse_view<all_view<R>>;\n\n\tnamespace views {\n\t\ttemplate<class>\n\t\tinline constexpr bool __is_reversible_subrange = false;\n\t\ttemplate<class I, subrange_kind K>\n\t\tinline constexpr bool __is_reversible_subrange<\n\t\t\tsubrange<reverse_iterator<I>, reverse_iterator<I>, K>> = true;\n\n\t\tstruct __reverse_fn : detail::__pipeable<__reverse_fn> {\n\t\t\ttemplate<bidirectional_range R>\n\t\t\trequires viewable_range<R>\n\t\t\tconstexpr auto operator()(R&& r) const {\n\t\t\t\tif constexpr (_SpecializationOf<R, reverse_view>) {\n\t\t\t\t\treturn std::forward<R>(r).base();\n\t\t\t\t} else if constexpr (__is_reversible_subrange<__uncvref<R>>) {\n\t\t\t\t\tusing I = decltype(begin(r).base());\n\t\t\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\t\t\treturn subrange<I, I, subrange_kind::sized>(\n\t\t\t\t\t\t\tr.end().base(), r.begin().base(), r.size());\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn subrange<I, I>(\n\t\t\t\t\t\t\tr.end().base(), r.begin().base());\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn reverse_view{std::forward<R>(r)};\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __reverse_fn reverse{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/single.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_SINGLE_HPP\n#define STL2_VIEW_SINGLE_HPP\n\n#include <memory>\n#include <utility>\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<copy_constructible T>\n\trequires std::is_object_v<T>\n\tclass single_view : public view_interface<single_view<T>> {\n\tprivate:\n\t\tdetail::semiregular_box<T> value_;\n\tpublic:\n\t\tsingle_view() = default;\n\t\tconstexpr explicit single_view(const T& t)\n\t\t: value_(t) {}\n\t\tconstexpr explicit single_view(T&& t)\n\t\t: value_(std::move(t)) {}\n\n\t\ttemplate<class... Args>\n\t\trequires constructible_from<T, Args...>\n\t\tconstexpr single_view(std::in_place_t, Args&&... args)\n\t\t: value_(std::in_place, std::forward<Args>(args)...) {}\n\n\t\tconstexpr T* begin() noexcept { return data(); }\n\t\tconstexpr const T* begin() const noexcept { return data(); }\n\t\tconstexpr T* end() noexcept { return data() + 1; }\n\t\tconstexpr const T* end() const noexcept { return data() + 1; }\n\t\tconstexpr static std::ptrdiff_t size() noexcept { return 1; }\n\t\tconstexpr T* data() noexcept { return std::addressof(value_.get()); }\n\t\tconstexpr const T* data() const noexcept { return std::addressof(value_.get()); }\n\t};\n\n\tnamespace views {\n\t\tstruct __single_fn {\n\t\t\ttemplate<class T>\n\t\t\tconstexpr auto operator()(T&& t) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\tsingle_view{std::forward<T>(t)}\n\t\t\t)\n\t\t};\n\n\t\tinline constexpr __single_fn single{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/split.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_SPLIT_HPP\n#define STL2_VIEW_SPLIT_HPP\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/algorithm/mismatch.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/single.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class R>\n\tMETA_CONCEPT _TinyRange =\n\t\tsized_range<R> &&\n\t\trequires {\n\t\t\ttypename meta::detail::require_constant<std::remove_reference_t<R>::size()>;\n\t\t} &&\n\t\tstd::remove_reference_t<R>::size() <= 1;\n\n\ttemplate<input_range Rng>\n\tstruct __split_view_base {\n\t\titerator_t<Rng> current_{};\n\t};\n\ttemplate<forward_range Rng>\n\tstruct __split_view_base<Rng> {};\n\n\ttemplate<input_range Rng, forward_range Pattern>\n\trequires view<Rng> && view<Pattern> &&\n\t\tindirectly_comparable<iterator_t<Rng>, iterator_t<Pattern>, equal_to> &&\n\t\t(forward_range<Rng> || _TinyRange<Pattern>)\n\tstruct split_view : private __split_view_base<Rng> {\n\tprivate:\n\t\ttemplate<bool Const> struct __outer_iterator;\n\t\ttemplate<bool Const> struct __inner_iterator;\n\n\t\tRng base_{};\n\t\tPattern pattern_{};\n\tpublic:\n\t\tsplit_view() = default;\n\t\tconstexpr split_view(Rng base, Pattern pattern)\n\t\t: base_(std::move(base))\n\t\t, pattern_(std::move(pattern)) {}\n\n\t\tconstexpr split_view(Rng base, iter_value_t<iterator_t<Rng>> e)\n\t\trequires constructible_from<Pattern, single_view<iter_value_t<iterator_t<Rng>>>>\n\t\t: base_(std::move(base))\n\t\t, pattern_(single_view{std::move(e)}) {}\n\n\t\tconstexpr auto begin() {\n\t\t\tif constexpr (forward_range<Rng>) {\n\t\t\t\treturn __outer_iterator<ext::simple_view<Rng>>{*this, __stl2::begin(base_)};\n\t\t\t} else {\n\t\t\t\tthis->current_ = __stl2::begin(base_);\n\t\t\t\treturn __outer_iterator<false>{*this};\n\t\t\t}\n\t\t}\n\n\t\tconstexpr auto begin() const\n\t\trequires forward_range<Rng> && forward_range<const Rng>\n\t\t{ return __outer_iterator<true>{*this, __stl2::begin(base_)}; }\n\n\t\tconstexpr auto end() requires forward_range<Rng> && common_range<Rng>\n\t\t{ return __outer_iterator<ext::simple_view<Rng>>{*this, __stl2::end(base_)}; }\n\n\t\tconstexpr auto end() const {\n\t\t\tconstexpr bool can_bound = forward_range<Rng> &&\n\t\t\t\tforward_range<const Rng> && common_range<const Rng>;\n\t\t\tif constexpr (can_bound) {\n\t\t\t\treturn __outer_iterator<true>{*this, __stl2::end(base_)};\n\t\t\t} else {\n\t\t\t\treturn default_sentinel;\n\t\t\t}\n\t\t}\n\t};\n\n\ttemplate<class Rng, class Pattern>\n\tsplit_view(Rng&&, Pattern&&) -> split_view<all_view<Rng>, all_view<Pattern>>;\n\n\ttemplate<input_range Rng>\n\tsplit_view(Rng&&, iter_value_t<iterator_t<Rng>>)\n\t\t-> split_view<all_view<Rng>, single_view<iter_value_t<iterator_t<Rng>>>>;\n\n\ttemplate<class, bool>\n\tstruct __split_view_outer_base {};\n\ttemplate<forward_range Rng, bool Const>\n\tstruct __split_view_outer_base<Rng, Const> {\n\t\titerator_t<__maybe_const<Const, Rng>> current_{};\n\t};\n\n\ttemplate<input_range Rng, forward_range Pattern>\n\trequires view<Rng> && view<Pattern> &&\n\t\tindirectly_comparable<iterator_t<Rng>, iterator_t<Pattern>, equal_to> &&\n\t\t(forward_range<Rng> || _TinyRange<Pattern>)\n\ttemplate<bool Const>\n\tstruct split_view<Rng, Pattern>::__outer_iterator\n\t: private __split_view_outer_base<Rng, Const> {\n\tprivate:\n\t\tfriend __outer_iterator<!Const>;\n\t\tfriend __inner_iterator<Const>;\n\n\t\tstatic_assert(forward_range<Rng> || !Const);\n\n\t\tusing Parent = __maybe_const<Const, split_view>;\n\t\tusing Base = __maybe_const<Const, Rng>;\n\n\t\tParent* parent_ = nullptr;\n\n\t\tconstexpr iterator_t<Base>& current() noexcept\n\t\trequires forward_range<Base>\n\t\t{ return this->current_; }\n\t\tconstexpr auto& current() const noexcept {\n\t\t\tif constexpr (forward_range<Base>) {\n\t\t\t\treturn this->current_;\n\t\t\t} else {\n\t\t\t\treturn parent_->current_;\n\t\t\t}\n\t\t}\n\n\t\tconstexpr bool at_end() const {\n\t\t\treturn current() == __stl2::end(parent_->base_);\n\t\t}\n\tpublic:\n\t\tusing iterator_category = meta::if_c<forward_range<Base>,\n\t\t\t__stl2::forward_iterator_tag, __stl2::input_iterator_tag>;\n\t\tusing difference_type = iter_difference_t<iterator_t<Base>>;\n\t\tstruct value_type;\n\n\t\t__outer_iterator() = default;\n\n\t\tconstexpr explicit  __outer_iterator(Parent& parent)\n\t\trequires (!forward_range<Base>)\n\t\t: parent_(std::addressof(parent)) {}\n\n\t\tconstexpr __outer_iterator(Parent& parent, iterator_t<Base> current)\n\t\trequires forward_range<Base>\n\t\t: __split_view_outer_base<Rng, Const>{std::move(current)}\n\t\t, parent_(std::addressof(parent)) {}\n\n\t\tconstexpr __outer_iterator(__outer_iterator<!Const> i)\n\t\trequires Const && convertible_to<iterator_t<Rng>, iterator_t<Base>>\n\t\t: __split_view_outer_base<Rng, Const>{i.current_}\n\t\t, parent_(i.parent_) {}\n\n\t\tconstexpr value_type operator*() const\n\t\t{ return value_type{*this}; }\n\n\t\tconstexpr __outer_iterator& operator++() {\n\t\t\tauto& cur = current();\n\t\t\tconst auto end = __stl2::end(parent_->base_);\n\t\t\tif (cur == end) return *this;\n\t\t\tconst auto [pbegin, pend] = subrange{parent_->pattern_};\n\t\t\tif (pbegin == pend) ++cur;\n\t\t\telse {\n\t\t\t\tdo {\n\t\t\t\t\tconst auto [b, p] = mismatch(cur, end, pbegin, pend);\n\t\t\t\t\tif (p == pend) {\n\t\t\t\t\t\t// The pattern matches, skip it\n\t\t\t\t\t\tcur = b;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} while (++cur != end);\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr decltype(auto) operator++(int) {\n\t\t\tif constexpr (forward_range<Base>) {\n\t\t\t\tauto tmp = *this;\n\t\t\t\t++*this;\n\t\t\t\treturn tmp;\n\t\t\t} else {\n\t\t\t\t++*this;\n\t\t\t}\n\t\t}\n\n\t\tfriend constexpr bool operator==(const __outer_iterator& x, const __outer_iterator& y)\n\t\trequires forward_range<Base>\n\t\t{ return x.current_ == y.current_; }\n\n\t\tfriend constexpr bool operator!=(const __outer_iterator& x, const __outer_iterator& y)\n\t\trequires forward_range<Base>\n\t\t{ return !(x == y); }\n\n\t\tfriend constexpr bool operator==(const __outer_iterator& x, default_sentinel_t)\n\t\t{ return x.at_end(); }\n\t\tfriend constexpr bool operator==(default_sentinel_t, const __outer_iterator& y)\n\t\t{ return y.at_end(); }\n\t\tfriend constexpr bool operator!=(const __outer_iterator& x, default_sentinel_t)\n\t\t{ return !x.at_end(); }\n\t\tfriend constexpr bool operator!=(default_sentinel_t, const __outer_iterator& y)\n\t\t{ return !y.at_end(); }\n\t};\n\n\ttemplate<input_range Rng, forward_range Pattern>\n\trequires view<Rng> && view<Pattern> &&\n\t\tindirectly_comparable<iterator_t<Rng>, iterator_t<Pattern>, equal_to> &&\n\t\t(forward_range<Rng> || _TinyRange<Pattern>)\n\ttemplate<bool Const>\n\tstruct split_view<Rng, Pattern>::__outer_iterator<Const>::value_type {\n\tprivate:\n\t\t__outer_iterator i_{};\n\tpublic:\n\t\tvalue_type() = default;\n\t\tconstexpr explicit value_type(__outer_iterator i)\n\t\t: i_(i) {}\n\n\t\tconstexpr __inner_iterator<Const> begin() const\n\t\t{ return __inner_iterator<Const>{i_}; }\n\n\t\tconstexpr default_sentinel_t end() const\n\t\t{ return default_sentinel; }\n\t};\n\n\ttemplate<input_range Rng, forward_range Pattern>\n\trequires view<Rng> && view<Pattern> &&\n\t\tindirectly_comparable<iterator_t<Rng>, iterator_t<Pattern>, equal_to> &&\n\t\t(forward_range<Rng> || _TinyRange<Pattern>)\n\ttemplate<bool Const>\n\tstruct split_view<Rng, Pattern>::__inner_iterator {\n\tprivate:\n\t\tusing Base = __maybe_const<Const, Rng>;\n\n\t\tstatic_assert(forward_range<Rng> || !Const);\n\n\t\t__outer_iterator<Const> i_{};\n\t\tbool zero_ = false;\n\n\t\tconstexpr bool at_end() const {\n\t\t\tauto cur = i_.current();\n\t\t\tauto end = __stl2::end(i_.parent_->base_);\n\t\t\tif (cur == end) return true;\n\t\t\tauto [pcur, pend] = subrange{i_.parent_->pattern_};\n\t\t\tif (pcur == pend) return zero_;\n\t\t\tdo {\n\t\t\t\tif (*cur != *pcur) return false;\n\t\t\t\tif (++pcur == pend) return true;\n\t\t\t} while (++cur != end);\n\t\t\treturn false;\n\t\t}\n\t\tconstexpr auto& current() const noexcept { return i_.current(); }\n\tpublic:\n\t\tusing iterator_category = iterator_category_t<__outer_iterator<Const>>;\n\t\tusing difference_type = iter_difference_t<iterator_t<Base>>;\n\t\tusing value_type = iter_value_t<iterator_t<Base>>;\n\n\t\t__inner_iterator() = default;\n\t\tconstexpr explicit __inner_iterator(__outer_iterator<Const> i)\n\t\t: i_{i} {}\n\n\t\tconstexpr decltype(auto) operator*() const\n\t\t{ return *i_.current(); }\n\n\t\tconstexpr __inner_iterator& operator++() {\n\t\t\tzero_ = true;\n\t\t\tif constexpr (!forward_range<Base>) {\n\t\t\t\tif constexpr (Pattern::size() == 0) {\n\t\t\t\t\treturn *this;\n\t\t\t\t}\n\t\t\t}\n\t\t\t++i_.current();\n\t\t\treturn *this;\n\t\t}\n\n\t\tconstexpr decltype(auto) operator++(int) {\n\t\t\tif constexpr (forward_range<Base>) {\n\t\t\t\tauto tmp = *this;\n\t\t\t\t++*this;\n\t\t\t\treturn tmp;\n\t\t\t} else\n\t\t\t\t++*this;\n\t\t}\n\n\t\tfriend constexpr bool operator==(const __inner_iterator& x, const __inner_iterator& y)\n\t\trequires forward_range<Base>\n\t\t{ return x.i_ == y.i_; }\n\t\tfriend constexpr bool operator!=(const __inner_iterator& x, const __inner_iterator& y)\n\t\trequires forward_range<Base>\n\t\t{ return !(x == y); }\n\n\t\tfriend constexpr bool operator==(const __inner_iterator& x, default_sentinel_t)\n\t\t{ return x.at_end(); }\n\t\tfriend constexpr bool operator==(default_sentinel_t, const __inner_iterator& y)\n\t\t{ return y.at_end(); }\n\t\tfriend constexpr bool operator!=(const __inner_iterator& x, default_sentinel_t)\n\t\t{ return !x.at_end(); }\n\t\tfriend constexpr bool operator!=(default_sentinel_t, const __inner_iterator& y)\n\t\t{ return !y.at_end(); }\n\n\t\tfriend constexpr decltype(auto) iter_move(const __inner_iterator& i)\n\t\tSTL2_NOEXCEPT_RETURN(\n\t\t\t__stl2::iter_move(i.current())\n\t\t)\n\n\t\tfriend constexpr void iter_swap(const __inner_iterator& x, const __inner_iterator& y)\n\t\tnoexcept(noexcept(__stl2::iter_swap(x.current(), y.current())))\n\t\trequires indirectly_swappable<iterator_t<Base>>\n\t\t{ __stl2::iter_swap(x.current(), y.current()); }\n\t};\n\n\tnamespace views {\n\t\tstruct __split_fn {\n\t\t\ttemplate<class E, class F>\n\t\t\tconstexpr auto operator()(E&& e, F&& f) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\tsplit_view{static_cast<E&&>(e), static_cast<F&&>(f)}\n\t\t\t)\n\n\t\t\ttemplate<copy_constructible T>\n\t\t\tconstexpr auto operator()(T&& t) const\n\t\t\t{ return detail::view_closure{*this, std::forward<T>(t)}; }\n\t\t};\n\n\t\tinline constexpr __split_fn split{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/subrange.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_SUBRANGE_HPP\n#define STL2_VIEW_SUBRANGE_HPP\n\n#include <tuple>\n#include <stl2/utility.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/algorithm/results.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/range/dangling.hpp>\n#include <stl2/detail/range/primitives.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<class From, class To>\n\t\tMETA_CONCEPT ConvertibleToNotSlicing =\n\t\t\tconvertible_to<From, To> &&\n\t\t\t// A conversion is a slicing conversion if the source and the\n\t\t\t// destination are both pointers, and if the pointed-to types differ\n\t\t\t// after removing cv qualifiers.\n\t\t\t!(std::is_pointer_v<std::decay_t<From>> &&\n\t\t\tstd::is_pointer_v<std::decay_t<To>> &&\n\t\t\t_NotSameAs<std::remove_pointer_t<std::decay_t<From>>,\n\t\t\t           std::remove_pointer_t<std::decay_t<To>>>);\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT PairLikeGCCBugs = requires(T t) {\n\t\t\t{ std::get<0>(t) } -> convertible_to<const std::tuple_element_t<0, T>&>;\n\t\t\t{ std::get<1>(t) } -> convertible_to<const std::tuple_element_t<1, T>&>;\n\t\t};\n\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT PairLike =\n\t\t\t!std::is_reference_v<T> && requires {\n\t\t\t\ttypename std::tuple_size<T>::type;\n\t\t\t\trequires derived_from<std::tuple_size<T>,\n\t\t\t\t\tstd::integral_constant<std::size_t, 2>>;\n\t\t\t\ttypename std::tuple_element_t<0, std::remove_const_t<T>>;\n\t\t\t\ttypename std::tuple_element_t<1, std::remove_const_t<T>>;\n\t\t\t\trequires PairLikeGCCBugs<T>; // Separate named concept to avoid\n\t\t\t\t                             // premature substitution.\n\t\t\t};\n\n\t\ttemplate<class T, class U, class V>\n\t\tMETA_CONCEPT PairLikeConvertibleFromGCCBugs =\n\t\t\t!std::is_reference_v<std::tuple_element_t<0, T>> &&\n\t\t\t!std::is_reference_v<std::tuple_element_t<1, T>> &&\n\t\t\tConvertibleToNotSlicing<U, std::tuple_element_t<0, T>> &&\n\t\t\tconvertible_to<V, std::tuple_element_t<1, T>>;\n\n\t\ttemplate<class T, class U, class V>\n\t\tMETA_CONCEPT PairLikeConvertibleFrom =\n\t\t\t!range<T> && PairLike<T> && constructible_from<T, U, V> &&\n\t\t\tPairLikeConvertibleFromGCCBugs<T, U, V>; // Separate named concept to avoid\n\t\t\t                                         // premature substitution.\n\n\t\ttemplate<class Derived, class Base>\n\t\tMETA_CONCEPT NotDerivedFrom = !derived_from<__uncvref<Derived>, Base>;\n\t} // namespace detail\n\n\tenum class subrange_kind : bool { unsized, sized };\n\n\ttemplate<input_or_output_iterator I, sentinel_for<I> S = I,\n\t\tsubrange_kind K = static_cast<subrange_kind>(sized_sentinel_for<S, I>)>\n\trequires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)\n\tclass subrange;\n\n\tnamespace __subrange_detail {\n\t\tstruct __adl_hook {};\n\n\t\t// Not to spec: these should be hidden friends\n\t\ttemplate<class I, class S, subrange_kind K>\n\t\tconstexpr I begin(subrange<I, S, K> r)\n\t\tnoexcept(std::is_nothrow_copy_constructible_v<I>) {\n\t\t\treturn r.begin();\n\t\t}\n\t\ttemplate<class I, class S, subrange_kind K>\n\t\tconstexpr S end(subrange<I, S, K> r)\n\t\tnoexcept(std::is_nothrow_copy_constructible_v<S>) {\n\t\t\treturn r.end();\n\t\t}\n\t}\n\n\ttemplate<input_or_output_iterator I, sentinel_for<I> S, subrange_kind K>\n\trequires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)\n\tclass STL2_EMPTY_BASES subrange\n\t: private __subrange_detail::__adl_hook\n\t, public view_interface<subrange<I, S, K>>\n\t{\n\t\tstatic constexpr bool StoreSize =\n\t\t\tK == subrange_kind::sized && !sized_sentinel_for<S, I>;\n\n\t\tmeta::if_c<StoreSize,\n\t\t\tstd::tuple<I, S, iter_difference_t<I>>,\n\t\t\tstd::tuple<I, S>> data_;\n\n\t\tconstexpr I& first_() noexcept {\n\t\t\treturn std::get<0>(data_);\n\t\t}\n\t\tconstexpr const I& first_() const noexcept {\n\t\t\treturn std::get<0>(data_);\n\t\t}\n\t\tconstexpr S& last_() noexcept {\n\t\t\treturn std::get<1>(data_);\n\t\t}\n\t\tconstexpr const S& last_() const noexcept {\n\t\t\treturn std::get<1>(data_);\n\t\t}\n\t\tconstexpr iter_difference_t<I>& size_() noexcept requires StoreSize {\n\t\t\treturn std::get<2>(data_);\n\t\t}\n\t\tconstexpr const iter_difference_t<I>& size_() const noexcept requires StoreSize {\n\t\t\treturn std::get<2>(data_);\n\t\t}\n\tpublic:\n\t\tsubrange() = default;\n\n\t\ttemplate<detail::ConvertibleToNotSlicing<I> I2>\n\t\tconstexpr subrange(I2&& i, S s)\n\t\t\trequires (!StoreSize)\n\t\t: data_{std::forward<I2>(i), std::move(s)} {}\n\n\t\ttemplate<detail::ConvertibleToNotSlicing<I> I2>\n\t\tconstexpr subrange(I2&& i, S s, iter_difference_t<I> n)\n\t\t\trequires (StoreSize)\n\t\t: data_{std::forward<I2>(i), std::move(s), n} {\n\t\t\tif constexpr (random_access_iterator<I>) {\n\t\t\t\tSTL2_EXPECT(first_() + n == last_());\n\t\t\t}\n\t\t}\n\t\ttemplate<detail::ConvertibleToNotSlicing<I> I2>\n\t\tconstexpr subrange(I2&& i, S s, iter_difference_t<I> n)\n\t\trequires sized_sentinel_for<S, I>\n\t\t: data_{std::forward<I2>(i), std::move(s)} {\n\t\t\tSTL2_EXPECT(last_() - first_() == n);\n\t\t}\n\n\t\ttemplate<detail::NotDerivedFrom<subrange> R>\n\t\trequires _ForwardingRange<R> &&\n\t\t\tdetail::ConvertibleToNotSlicing<iterator_t<R>, I> &&\n\t\t\tconvertible_to<sentinel_t<R>, S>\n\t\tconstexpr subrange(R&& r) requires (!StoreSize)\n\t\t: subrange{__stl2::begin(r), __stl2::end(r)} {}\n\n\t\ttemplate<detail::NotDerivedFrom<subrange> R>\n\t\trequires _ForwardingRange<R> &&\n\t\t\tdetail::ConvertibleToNotSlicing<iterator_t<R>, I> &&\n\t\t\tconvertible_to<sentinel_t<R>, S>\n\t\tconstexpr subrange(R&& r) requires StoreSize && sized_range<R>\n\t\t: subrange{__stl2::begin(r), __stl2::end(r), distance(r)} {}\n\n\t\ttemplate<_ForwardingRange R>\n\t\trequires\n\t\t\tdetail::ConvertibleToNotSlicing<iterator_t<R>, I> &&\n\t\t\tconvertible_to<sentinel_t<R>, S>\n\t\tconstexpr subrange(R&& r, iter_difference_t<I> n)\n\t\t\trequires (K == subrange_kind::sized)\n\t\t: subrange{__stl2::begin(r), __stl2::end(r), n} {\n\t\t\tif constexpr (sized_range<R>) {\n\t\t\t\tSTL2_EXPECT(n == distance(r));\n\t\t\t}\n\t\t}\n\n\t\ttemplate<detail::NotDerivedFrom<subrange> PairLike>\n\t\trequires detail::PairLikeConvertibleFrom<PairLike, const I&, const S&>\n\t\tconstexpr operator PairLike() const {\n\t\t\treturn PairLike(first_(), last_());\n\t\t}\n\n\t\tconstexpr I begin() const noexcept(std::is_nothrow_copy_constructible_v<I>) {\n\t\t\treturn first_();\n\t\t}\n\t\tconstexpr S end() const noexcept(std::is_nothrow_copy_constructible_v<S>) {\n\t\t\treturn last_();\n\t\t}\n\t\tconstexpr bool empty() const {\n\t\t\treturn first_() == last_();\n\t\t}\n\n\t\tconstexpr iter_difference_t<I> size() const requires (K == subrange_kind::sized) {\n\t\t\tif constexpr (StoreSize) {\n\t\t\t\treturn size_();\n\t\t\t} else {\n\t\t\t\treturn last_() - first_();\n\t\t\t}\n\t\t}\n\n\t\t[[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const {\n\t\t\tauto tmp = *this;\n\t\t\ttmp.advance(n);\n\t\t\treturn tmp;\n\t\t}\n\t\t[[nodiscard]] constexpr subrange prev(iter_difference_t<I> n = 1) const\n\t\trequires bidirectional_iterator<I> {\n\t\t\tauto tmp = *this;\n\t\t\ttmp.advance(-n);\n\t\t\treturn tmp;\n\t\t}\n\t\tconstexpr subrange& advance(iter_difference_t<I> n) {\n\t\t\tauto remainder = __stl2::advance(first_(), n, last_());\n\t\t\t(void)remainder;\n\t\t\tif constexpr (StoreSize) {\n\t\t\t\tsize_() -= n - remainder;\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\t};\n\n\ttemplate<class I, class S>\n\tsubrange(I, S) -> subrange<I, S>;\n\n\ttemplate<input_or_output_iterator I, class S>\n\tsubrange(I, S, iter_difference_t<I>) -> subrange<I, S, subrange_kind::sized>;\n\n\ttemplate<_ForwardingRange R>\n\tsubrange(R&&) -> subrange<iterator_t<R>, sentinel_t<R>,\n\t\t(sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)\n\t\t\t? subrange_kind::sized : subrange_kind::unsized>;\n\n\ttemplate<_ForwardingRange R>\n\tsubrange(R&&, iter_difference_t<iterator_t<R>>) ->\n\t\tsubrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;\n\n\tnamespace ext {\n\t\ttemplate<input_or_output_iterator I, sentinel_for<I> S = I>\n\t\tusing sized_subrange = subrange<I, S, subrange_kind::sized>;\n\t}\n\n\ttemplate<std::size_t N, class I, class S, subrange_kind K>\n\trequires (N < 2)\n\tconstexpr auto get(const subrange<I, S, K>& r) {\n\t\tif constexpr (N == 0) {\n\t\t\treturn r.begin();\n\t\t} else {\n\t\t\treturn r.end();\n\t\t}\n\t}\n\n\ttemplate<range R>\n\tusing safe_subrange_t =\t__maybe_dangling<R, subrange<iterator_t<R>>>;\n} STL2_CLOSE_NAMESPACE\n\nnamespace std {\n\ttemplate<class I, class S, ::__stl2::subrange_kind K>\n\tstruct tuple_size<::__stl2::subrange<I, S, K>>\n\t  : std::integral_constant<size_t, 2> {};\n\ttemplate<class I, class S, ::__stl2::subrange_kind K>\n\tstruct tuple_element<0, ::__stl2::subrange<I, S, K>>\n\t{ using type = I; };\n\ttemplate<class I, class S, ::__stl2::subrange_kind K>\n\tstruct tuple_element<1, ::__stl2::subrange<I, S, K>>\n\t{ using type = S; };\n}\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/take.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_TAKE_HPP\n#define STL2_VIEW_TAKE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<view R>\n\tstruct take_view : view_interface<take_view<R>> {\n\tprivate:\n\t\ttemplate<bool> struct __sentinel;\n\t\tusing D = iter_difference_t<iterator_t<R>>;\n\n\t\tR base_{};\n\t\tD count_{};\n\n\t\ttemplate<class Self>\n\t\tstatic constexpr auto begin_(Self& self) {\n\t\t\tusing RR = __maybe_const<std::is_const_v<Self>, R>;\n\t\t\tif constexpr (sized_range<RR>) {\n\t\t\t\tif constexpr (random_access_range<RR>) {\n\t\t\t\t\treturn __stl2::begin(self.base_);\n\t\t\t\t} else {\n\t\t\t\t\treturn counted_iterator{__stl2::begin(self.base_), static_cast<D>(self.size())};\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn counted_iterator{__stl2::begin(self.base_), self.count_};\n\t\t\t}\n\t\t}\n\t\ttemplate<class Self>\n\t\tstatic constexpr auto end_(Self& self) {\n\t\t\tconstexpr bool is_const = std::is_const_v<Self>;\n\t\t\tusing RR = __maybe_const<is_const, R>;\n\t\t\tif constexpr (random_access_range<RR> && sized_range<RR>) {\n\t\t\t\treturn __stl2::begin(self.base_) + self.size();\n\t\t\t} else if constexpr (sized_range<RR>) {\n\t\t\t\treturn default_sentinel;\n\t\t\t} else {\n\t\t\t\treturn __sentinel<is_const>{__stl2::end(self.base_)};\n\t\t\t}\n\t\t}\n\t\ttemplate<class Self>\n\t\tstatic constexpr auto size_(Self& self) {\n\t\t\tconst auto n = __stl2::size(self.base_);\n\t\t\tconst auto c = static_cast<decltype(n)>(self.count_);\n\t\t\treturn n < c ? n : c;\n\t\t}\n\tpublic:\n\t\ttake_view() = default;\n\n\t\tconstexpr take_view(R base, D count)\n\t\t: base_(static_cast<R&&>(base)), count_(count) {}\n\n\t\tconstexpr R base() const { return base_; }\n\n\t\tconstexpr auto begin() requires (!ext::simple_view<R>) { return begin_(*this); }\n\t\tconstexpr auto begin() const requires range<const R> { return begin_(*this); }\n\n\t\tconstexpr auto end() requires (!ext::simple_view<R>) { return end_(*this); }\n\t\tconstexpr auto end() const requires range<const R> || sized_range<R>\n\t\t{ return end_(*this); }\n\n\t\tconstexpr auto size() requires (!ext::simple_view<R> && sized_range<R>) { return size_(*this); }\n\t\tconstexpr auto size() const requires sized_range<const R> { return size_(*this); }\n\t};\n\n\ttemplate<range R>\n\ttake_view(R&&, iter_difference_t<iterator_t<R>>) -> take_view<all_view<R>>;\n\n\ttemplate<view R>\n\ttemplate<bool Const>\n\tstruct take_view<R>::__sentinel {\n\tprivate:\n\t\tusing Base = __maybe_const<Const, R>;\n\t\tusing CI = counted_iterator<iterator_t<Base>>;\n\n\t\tsentinel_t<Base> end_{};\n\tpublic:\n\t\t__sentinel() = default;\n\n\t\tconstexpr explicit __sentinel(sentinel_t<Base> end)\n\t\t: end_(end) {}\n\n\t\tconstexpr __sentinel(__sentinel<!Const> s)\n\t\trequires Const && convertible_to<sentinel_t<R>, sentinel_t<Base>>\n\t\t: end_(s.base()) {}\n\n\t\tconstexpr sentinel_t<Base> base() const { return end_; }\n\n\t\tfriend constexpr bool operator==(const __sentinel& x, const CI& y)\n\t\t{ return 0 == y.count() || x.end_ == y.base(); }\n\t\tfriend constexpr bool operator==(const CI& x, const __sentinel& y) { return y == x;}\n\t\tfriend constexpr bool operator!=(const __sentinel& x, const CI& y) { return !(x == y); }\n\t\tfriend constexpr bool operator!=(const CI& x, const __sentinel& y) { return !(y == x); }\n\t};\n\n\tnamespace views {\n\t\tstruct __take_fn {\n\t\t\ttemplate<range Rng>\n\t\t\tconstexpr auto operator()(Rng&& rng, iter_difference_t<iterator_t<Rng>> count) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\ttake_view{views::all(static_cast<Rng&&>(rng)), count}\n\t\t\t)\n\n\t\t\ttemplate<integral D>\n\t\t\tconstexpr auto operator()(D count) const\n\t\t\t{ return detail::view_closure{*this, static_cast<D>(count)}; }\n\t\t};\n\n\t\tinline constexpr __take_fn take{};\n\t}\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/take_exactly.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_TAKE_EXACTLY_HPP\n#define STL2_VIEW_TAKE_EXACTLY_HPP\n\n#include <utility>\n\n#include <stl2/type_traits.hpp>\n#include <stl2/detail/ebo_box.hpp>\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/detail/iterator/counted_iterator.hpp>\n#include <stl2/detail/iterator/default_sentinel.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace ext {\n\t\ttemplate<view Base>\n\t\tclass STL2_EMPTY_BASES take_exactly_view\n\t\t: public view_interface<take_exactly_view<Base>>\n\t\t, private detail::ebo_box<Base, take_exactly_view<Base>>\n\t\t{\n\t\t\tusing base_t = detail::ebo_box<Base, take_exactly_view<Base>>;\n\t\t\tusing base_t::get;\n\n\t\t\titer_difference_t<iterator_t<Base>> n_ = 0;\n\t\tpublic:\n\t\t\ttake_exactly_view() = default;\n\n\t\t\tconstexpr take_exactly_view(Base view, iter_difference_t<iterator_t<Base>> n)\n\t\t\tnoexcept(std::is_nothrow_move_constructible<Base>::value)\n\t\t\t: base_t{std::move(view)}, n_{n}\n\t\t\t{ STL2_EXPECT(n >= 0); }\n\n\t\t\tconstexpr auto begin()\n\t\t\tnoexcept(noexcept(counted_iterator{__stl2::begin(std::declval<Base&>()), n_}))\n\t\t\trequires (!range<Base const>)\n\t\t\t{ return counted_iterator{__stl2::begin(get()), n_}; }\n\n\t#if 0 // FIXME: Untagged bug workaround\n\t\t\tconstexpr auto data()\n\t\t\tnoexcept(noexcept(__stl2::data(std::declval<Base&>())))\n\t\t\trequires\n\t\t\t\t(!range<Base const> &&\n\t\t\t\trequires(Base& b) { __stl2::data(b); })\n\t\t\t{ return __stl2::data(get()); }\n\t#else\n\t\t\ttemplate<class B = Base>\n\t\t\trequires\n\t\t\t\t(same_as<B, Base> &&\n\t\t\t\t!range<B const> &&\n\t\t\t\trequires(B& b) { __stl2::data(b); })\n\t\t\tconstexpr auto data()\n\t\t\tnoexcept(noexcept(__stl2::data(std::declval<B&>())))\n\t\t\t{ return __stl2::data(get()); }\n\t#endif\n\n\t\t\tconstexpr auto begin() const\n\t\t\tnoexcept(noexcept(counted_iterator{__stl2::begin(std::declval<Base const&>()), n_}))\n\t\t\trequires range<Base const>\n\t\t\t{ return counted_iterator{__stl2::begin(get()), n_}; }\n\n\t#if 0 // FIXME: Untagged bug workaround\n\t\t\tconstexpr auto data() const\n\t\t\tnoexcept(noexcept(__stl2::data(std::declval<Base const&>())))\n\t\t\trequires\n\t\t\t\t(!range<Base const> &&\n\t\t\t\trequires(Base const& b) { __stl2::data(b); })\n\t\t\t{ return __stl2::data(get()); }\n\t#else\n\t\t\ttemplate<class B = Base>\n\t\t\trequires\n\t\t\t\tsame_as<B, Base> &&\n\t\t\t\trange<B const> &&\n\t\t\t\trequires(B const& b) { __stl2::data(b); }\n\t\t\tconstexpr auto data() const\n\t\t\tnoexcept(noexcept(__stl2::data(std::declval<B const&>())))\n\t\t\t{ return __stl2::data(get()); }\n\t#endif\n\n\t\t\tconstexpr default_sentinel_t end() const noexcept { return {}; }\n\t\t\tconstexpr iter_difference_t<iterator_t<Base>> size() const noexcept { return n_; }\n\t\t\tconstexpr bool empty() const noexcept { return n_ == 0; }\n\t\t};\n\n\t\ttemplate<range R>\n\t\ttake_exactly_view(R&& base, iter_difference_t<iterator_t<R>> n)\n\t\t\t-> take_exactly_view<all_view<R>>;\n\t} // namespace ext\n\n\ttemplate<class V>\n\tinline constexpr bool enable_view<ext::take_exactly_view<V>> = true;\n\n\tnamespace views::ext {\n\t\tstruct __take_exactly_fn : detail::__pipeable<__take_exactly_fn> {\n\t\t\ttemplate<class V>\n\t\t\tconstexpr auto operator()(V&& view, iter_difference_t<iterator_t<V>> const n) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\t__stl2::ext::take_exactly_view(all(std::forward<V>(view)), n)\n\t\t\t)\n\n\t\t\ttemplate<integral D>\n\t\t\tconstexpr auto operator()(D count) const {\n\t\t\t\treturn detail::view_closure(*this, static_cast<D>(count));\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __take_exactly_fn take_exactly{};\n\t} // namespace views::ext\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/take_while.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//  Copyright Christopher Di Bella\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_TAKE_WHILE_HPP\n#define STL2_VIEW_TAKE_WHILE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<view R, class Pred>\n\trequires input_range<R> && std::is_object_v<Pred> &&\n\t\tindirect_unary_predicate<const Pred, iterator_t<R>>\n\tclass STL2_EMPTY_BASES take_while_view\n\t: public view_interface<take_while_view<R, Pred>>\n\t, private detail::semiregular_box<Pred> {\n\t\ttemplate<bool> class __sentinel;\n\t\tusing storage_t = detail::semiregular_box<Pred>;\n\t\tusing storage_t::get;\n\tpublic:\n\t\ttake_while_view() = default;\n\n\t\tconstexpr take_while_view(R base, Pred pred)\n\t\t: storage_t{std::move(pred)}, base_(static_cast<R&&>(base)) {}\n\n\t\tconstexpr R base() const { return base_; }\n\t\tconstexpr const Pred& pred() const noexcept { return get(); }\n\n\t\tconstexpr auto begin() requires (!ext::simple_view<R>) { return begin_impl(*this); }\n\t\tconstexpr auto begin() const requires range<const R> { return begin_impl(*this); }\n\n\t\tconstexpr auto end() requires (!ext::simple_view<R>) { return end_impl(*this); }\n\t\tconstexpr auto end() const requires range<const R>\n\t\t{ return end_impl(*this); }\n\tprivate:\n\t\tR base_{};\n\n\t\ttemplate<class Self>\n\t\tstatic constexpr auto begin_impl(Self& self) { return __stl2::begin(self.base_); }\n\n\t\ttemplate<class Self>\n\t\tstatic constexpr auto end_impl(Self& self) {\n\t\t\tconstexpr bool is_const = std::is_const_v<Self>;\n\t\t\treturn __sentinel<is_const>{__stl2::end(self.base_), &self.pred()};\n\t\t}\n\t};\n\n\ttemplate<class R, class Pred>\n\ttake_while_view(R&&, Pred) -> take_while_view<all_view<R>, Pred>;\n\n\ttemplate<view R, class Pred>\n\trequires input_range<R> && std::is_object_v<Pred> &&\n\t\tindirect_unary_predicate<const Pred, iterator_t<R>>\n\ttemplate<bool Const>\n\tclass take_while_view<R, Pred>::__sentinel {\n\t\tfriend __sentinel<false>;\n\t\tusing Base = __maybe_const<Const, R>;\n\t\tsentinel_t<Base> end_{};\n\t\tconst Pred* pred_ = nullptr;\n\tpublic:\n\t\t__sentinel() = default;\n\n\t\tconstexpr explicit __sentinel(sentinel_t<Base> end, const Pred* pred)\n\t\t: end_(end), pred_(pred) {}\n\n\t\tconstexpr __sentinel(__sentinel<!Const> s)\n\t\trequires Const && convertible_to<sentinel_t<R>, sentinel_t<Base>>\n\t\t: end_(s.base()), pred_(s.pred_) {}\n\n\t\tconstexpr sentinel_t<Base> base() const { return end_; }\n\n\t\tfriend constexpr bool operator==(const __sentinel& x, const iterator_t<Base> y)\n\t\t{ return x.end_ == y || !(*x.pred_)(*y); }\n\t\tfriend constexpr bool operator==(const iterator_t<Base>& x, const __sentinel& y) { return y == x; }\n\t\tfriend constexpr bool operator!=(const __sentinel& x, const iterator_t<Base>& y) { return !(x == y); }\n\t\tfriend constexpr bool operator!=(const iterator_t<Base>& x, const __sentinel& y) { return !(y == x); }\n\t};\n\n\tnamespace views {\n\t\tstruct __take_while_fn : detail::__pipeable<__take_while_fn> {\n\t\t\ttemplate<class Rng, class Pred>\n\t\t\tconstexpr auto operator()(Rng&& rng, Pred&& pred) const\n\t\t\tSTL2_REQUIRES_RETURN(\n\t\t\t\ttake_while_view{views::all(static_cast<Rng&&>(rng)), std::forward<Pred>(pred)}\n\t\t\t)\n\n\t\t\ttemplate<__stl2::ext::copy_constructible_object Pred>\n\t\t\tconstexpr auto operator()(Pred pred) const\n\t\t\t{ return detail::view_closure{*this, std::move(pred)}; }\n\t\t};\n\n\t\tinline constexpr __take_while_fn take_while{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif // STL2_VIEW_TAKE_WHILE_HPP\n"
  },
  {
    "path": "include/stl2/view/transform.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_TRANSFORM_HPP\n#define STL2_VIEW_TRANSFORM_HPP\n\n#include <functional>\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/meta.hpp>\n#include <stl2/detail/semiregular_box.hpp>\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/functional/invoke.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <stl2/detail/view/view_closure.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/view_interface.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<input_range V, copy_constructible F>\n\trequires view<V> && std::is_object_v<F> &&\n\t\tregular_invocable<F&, iter_reference_t<iterator_t<V>>>\n\tclass transform_view : public view_interface<transform_view<V, F>> {\n\tprivate:\n\t\ttemplate<bool> class __iterator;\n\t\ttemplate<bool> class __sentinel;\n\n\t\tV base_ = V();\n\t\tdetail::semiregular_box<F> fun_;\n\n\tpublic:\n\t\ttransform_view() = default;\n\n\t\tconstexpr transform_view(V base, F fun)\n\t\t: base_(std::move(base)), fun_(std::move(fun)) {}\n\n\t\tconstexpr V base() const { return base_; }\n\n\t\tconstexpr __iterator<false> begin()\n\t\t{ return {*this, __stl2::begin(base_)}; }\n\n\t\t// Template to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\ttemplate<class ConstV = const V>\n\t\tconstexpr __iterator<true> begin() const requires range<ConstV> &&\n\t\t\tregular_invocable<const F&, iter_reference_t<iterator_t<ConstV>>>\n\t\t{ return {*this, __stl2::begin(base_)}; }\n\n\t\tconstexpr auto end() {\n\t\t\tif constexpr (common_range<V>) {\n\t\t\t\treturn __iterator<false>{*this, __stl2::end(base_)};\n\t\t\t} else {\n\t\t\t\treturn __sentinel<false>{__stl2::end(base_)};\n\t\t\t}\n\t\t}\n\n\t\t// Template to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\ttemplate<class ConstV = const V>\n\t\tconstexpr auto end() const requires range<ConstV> &&\n\t\t\tregular_invocable<const F&, iter_reference_t<iterator_t<ConstV>>>\n\t\t{\n\t\t\tif constexpr (common_range<const V>) {\n\t\t\t\treturn __iterator<true>{*this, __stl2::end(base_)};\n\t\t\t} else {\n\t\t\t\treturn __sentinel<true>{__stl2::end(base_)};\n\t\t\t}\n\t\t}\n\n\t\tconstexpr auto size() requires sized_range<V>\n\t\t{ return __stl2::size(base_); }\n\n\t\tconstexpr auto size() const requires sized_range<const V>\n\t\t{ return __stl2::size(base_); }\n\t};\n\n\ttemplate<class R, class F>\n\ttransform_view(R&& r, F fun) -> transform_view<all_view<R>, F>;\n\n\ttemplate<input_range V, copy_constructible F>\n\trequires view<V> && std::is_object_v<F> &&\n\t\tregular_invocable<F&, iter_reference_t<iterator_t<V>>>\n\ttemplate<bool Const>\n\tclass transform_view<V, F>::__iterator {\n\tprivate:\n\t\tusing Parent = __maybe_const<Const, transform_view>;\n\t\tusing Base = __maybe_const<Const, V>;\n\t\titerator_t<Base> current_{};\n\t\tParent* parent_ = nullptr;\n\t\tfriend __iterator<!Const>;\n\t\tfriend __sentinel<Const>;\n\tpublic:\n\t\tusing iterator_category = iterator_category_t<iterator_t<Base>>;\n\t\tusing value_type =\n\t\t\t__uncvref<invoke_result_t<F&, iter_reference_t<iterator_t<Base>>>>;\n\t\tusing difference_type = iter_difference_t<iterator_t<Base>>;\n\n\t\t__iterator() = default;\n\n\t\tconstexpr __iterator(Parent& parent, iterator_t<Base> current)\n\t\t: current_(current), parent_(&parent) {}\n\n\t\tconstexpr __iterator(__iterator<!Const> i)\n\t\trequires Const && convertible_to<iterator_t<V>, iterator_t<Base>>\n\t\t: current_(std::move(i.current_)), parent_(i.parent_) {}\n\n\t\tconstexpr iterator_t<Base> base() const\n\t\t{ return current_; }\n\n\t\tconstexpr decltype(auto) operator*() const\n\t\tnoexcept(noexcept(invoke(parent_->fun_.get(), *current_)))\n\t\t{ return invoke(parent_->fun_.get(), *current_); }\n\n\t\tconstexpr __iterator& operator++()\n\t\t{\n\t\t\t++current_;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr void operator++(int)\n\t\t{ ++current_; }\n\t\tconstexpr __iterator operator++(int) requires forward_range<Base>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr __iterator& operator--() requires bidirectional_range<Base>\n\t\t{\n\t\t\t--current_;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr __iterator operator--(int) requires bidirectional_range<Base>\n\t\t{\n\t\t\tauto tmp = *this;\n\t\t\t--*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tconstexpr __iterator& operator+=(difference_type n)\n\t\trequires random_access_range<Base>\n\t\t{\n\t\t\tcurrent_ += n;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr __iterator& operator-=(difference_type n)\n\t\trequires random_access_range<Base>\n\t\t{\n\t\t\tcurrent_ -= n;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr decltype(auto) operator[](difference_type n) const\n\t\trequires random_access_range<Base>\n\t\t{ return invoke(parent_->fun_.get(), current_[n]); }\n\n\t\tfriend constexpr bool operator==(const __iterator& x, const __iterator& y)\n\t\trequires equality_comparable<iterator_t<Base>>\n\t\t{ return x.current_ == y.current_; }\n\n\t\tfriend constexpr bool operator!=(const __iterator& x, const __iterator& y)\n\t\trequires equality_comparable<iterator_t<Base>>\n\t\t{ return !(x == y); }\n\n\t\tfriend constexpr bool operator<(const __iterator& x, const __iterator& y)\n\t\trequires random_access_range<Base>\n\t\t{ return x.current_ < y.current_; }\n\n\t\tfriend constexpr bool operator>(const __iterator& x, const __iterator& y)\n\t\trequires random_access_range<Base>\n\t\t{ return y < x; }\n\n\t\tfriend constexpr bool operator<=(const __iterator& x, const __iterator& y)\n\t\trequires random_access_range<Base>\n\t\t{ return !(y < x); }\n\n\t\tfriend constexpr bool operator>=(const __iterator& x, const __iterator& y)\n\t\trequires random_access_range<Base>\n\t\t{ return !(x < y); }\n\n\t\tfriend constexpr __iterator operator+(__iterator i, difference_type n)\n\t\trequires random_access_range<Base>\n\t\t{ return __iterator{*i.parent_, i.current_ + n}; }\n\n\t\tfriend constexpr __iterator operator+(difference_type n, __iterator i)\n\t\trequires random_access_range<Base>\n\t\t{ return __iterator{*i.parent_, i.current_ + n}; }\n\n\t\tfriend constexpr __iterator operator-(__iterator i, difference_type n)\n\t\trequires random_access_range<Base>\n\t\t{ return __iterator{*i.parent_, i.current_ - n}; }\n\n\t\tfriend constexpr difference_type operator-(const __iterator& x, const __iterator& y)\n\t\trequires random_access_range<Base>\n\t\t{ return x.current_ - y.current_; }\n\n\t\tfriend constexpr decltype(auto) iter_move(const __iterator& i)\n\t\t\tnoexcept(noexcept(*i))\n\t\t{\n\t\t\tif constexpr(std::is_lvalue_reference_v<decltype(*i)>)\n\t\t\t\treturn std::move(*i);\n\t\t\telse\n\t\t\t\treturn *i;\n\t\t}\n\n\t\tfriend constexpr void iter_swap(const __iterator& x, const __iterator& y)\n\t\t\tnoexcept(noexcept(__stl2::iter_swap(x.current_, y.current_)))\n\t\t{ __stl2::iter_swap(x.current_, y.current_); }\n\t};\n\n\ttemplate<input_range V, copy_constructible F>\n\trequires view<V> && std::is_object_v<F> &&\n\t\tregular_invocable<F&, iter_reference_t<iterator_t<V>>>\n\ttemplate<bool Const>\n\tclass transform_view<V, F>::__sentinel {\n\tprivate:\n\t\tusing Parent = __maybe_const<Const, transform_view>;\n\t\tusing Base = __maybe_const<Const, V>;\n\t\tsentinel_t<Base> end_{};\n\t\tfriend __sentinel<!Const>;\n\n\t\tconstexpr bool equal(const __iterator<Const>& i) const {\n\t\t\treturn i.current_ == end_;\n\t\t}\n\t\tconstexpr iter_difference_t<iterator_t<Base>>\n\t\tdistance(const __iterator<Const>& i) const {\n\t\t\treturn i.current_ - end_;\n\t\t}\n\tpublic:\n\t\t__sentinel() = default;\n\t\texplicit constexpr __sentinel(sentinel_t<Base> end)\n\t\t: end_(end) {}\n\t\tconstexpr __sentinel(__sentinel<!Const> i)\n\t\trequires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>\n\t\t: end_(std::move(i.end_)) {}\n\n\t\tconstexpr sentinel_t<Base> base() const\n\t\t{ return end_; }\n\n\t\tfriend constexpr bool operator==(const __iterator<Const>& x, const __sentinel& y)\n\t\t{ return y.equal(x); }\n\n\t\tfriend constexpr bool operator==(const __sentinel& x, const __iterator<Const>& y)\n\t\t{ return x.equal(y); }\n\n\t\tfriend constexpr bool operator!=(const __iterator<Const>& x, const __sentinel& y)\n\t\t{ return !y.equal(x); }\n\n\t\tfriend constexpr bool operator!=(const __sentinel& x, const __iterator<Const>& y)\n\t\t{ return !x.equal(y); }\n\n\t\tfriend constexpr iter_difference_t<iterator_t<Base>>\n\t\toperator-(const __iterator<Const>& x, const __sentinel& y)\n\t\trequires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>\n\t\t{ return -y.distance(x); }\n\n\t\tfriend constexpr iter_difference_t<iterator_t<Base>>\n\t\toperator-(const __sentinel& y, const __iterator<Const>& x)\n\t\trequires sized_sentinel_for<sentinel_t<Base>, iterator_t<Base>>\n\t\t{ return y.distance(x); }\n\t};\n\n\tnamespace views {\n\t\tstruct __transform_fn {\n\t\t\ttemplate<input_range Rng, copy_constructible F>\n\t\t\trequires\n\t\t\t\tviewable_range<Rng> && invocable<F&, iter_reference_t<iterator_t<Rng>>>\n\t\t\tconstexpr auto operator()(Rng&& rng, F fun) const {\n\t\t\t\treturn transform_view{std::forward<Rng>(rng), std::move(fun)};\n\t\t\t}\n\n\t\t\ttemplate<copy_constructible F>\n\t\t\tconstexpr auto operator()(F fun) const {\n\t\t\t\treturn detail::view_closure{*this, std::move(fun)};\n\t\t\t}\n\t\t};\n\n\t\tinline constexpr __transform_fn transform{};\n\t} // namespace views\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "include/stl2/view/view_interface.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_VIEW_INTERFACE_HPP\n#define STL2_VIEW_INTERFACE_HPP\n\n#include <stl2/detail/fwd.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/iterator/common_iterator.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n\nSTL2_OPEN_NAMESPACE {\n\tnamespace detail {\n\t\ttemplate<range Rng>\n\t\tstruct __range_common_iterator_impl {\n\t\t\tusing type = common_iterator<iterator_t<Rng>, sentinel_t<Rng>>;\n\t\t};\n\t\ttemplate<common_range Rng>\n\t\tstruct __range_common_iterator_impl<Rng> {\n\t\t\tusing type = iterator_t<Rng>;\n\t\t};\n\t\ttemplate<range Rng>\n\t\tusing __range_common_iterator =\n\t\t\ttypename __range_common_iterator_impl<Rng>::type;\n\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT CanEmpty = range<R> && requires(R& r) { empty(r); };\n\t\ttemplate<class R>\n\t\tMETA_CONCEPT SizedSentinelForwardRange = forward_range<R> && sized_sentinel_for<sentinel_t<R>, iterator_t<R>>;\n\t\ttemplate<class C, class R> // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\tMETA_CONCEPT ContainerConvertibleGCCBugs = input_range<R> &&\n\t\t\tconvertible_to<iter_reference_t<iterator_t<R>>, iter_value_t<iterator_t<C>>> &&\n\t\t\tconstructible_from<C, __range_common_iterator<R>, __range_common_iterator<R>>;\n\t\ttemplate<class C, class R>\n\t\tMETA_CONCEPT ContainerConvertible = forward_range<C> && !view<C> &&\n\t\t\tContainerConvertibleGCCBugs<C, R>;\n\n\t\ttemplate<range R>\n\t\tconstexpr bool is_in_range(R&, iter_difference_t<iterator_t<R>> n) noexcept {\n\t\t\treturn 0 <= n;\n\t\t}\n\n\t\ttemplate<sized_range R>\n\t\tconstexpr bool is_in_range(R& r, iter_difference_t<iterator_t<R>> n)\n\t\t\tnoexcept(noexcept(size(r)))\n\t\t{\n\t\t\tauto sz = size(r);\n\t\t\tusing T = std::make_unsigned_t<common_type_t<\n\t\t\t\titer_difference_t<iterator_t<R>>,\n\t\t\t\tdecltype(sz)>>;\n\t\t\treturn static_cast<T>(n) < static_cast<T>(sz);\n\t\t}\n\t}\n\n\ttemplate<class D>\n\trequires std::is_class_v<D>\n\tclass view_interface : public view_base {\n\tprivate:\n\t\tconstexpr D& derived() noexcept {\n\t\t\tstatic_assert(derived_from<D, view_interface>);\n\t\t\treturn static_cast<D&>(*this);\n\t\t}\n\t\tconstexpr const D& derived() const noexcept {\n\t\t\tstatic_assert(derived_from<D, view_interface>);\n\t\t\treturn static_cast<const D&>(*this);\n\t\t}\n\tpublic:\n\t\tconstexpr bool empty() requires forward_range<D> {\n\t\t\tauto& d = derived();\n\t\t\treturn __stl2::begin(d) == __stl2::end(d);\n\t\t}\n\t\tconstexpr bool empty() const requires forward_range<const D> {\n\t\t\tauto& d = derived();\n\t\t\treturn begin(d) == end(d);\n\t\t}\n\n\t\tconstexpr explicit operator bool()\n\t\t// Distinct named concept to workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82740\n\t\trequires detail::CanEmpty<D> {\n\t\t\treturn !__stl2::empty(derived());\n\t\t}\n\t\t// Distinct named concept to workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82740\n\t\ttemplate<detail::CanEmpty = const D> // gcc_bugs_bugs_bugs\n\t\tconstexpr explicit operator bool() const {\n\t\t\treturn !__stl2::empty(derived());\n\t\t}\n\t\ttemplate<range R = D>\n\t\trequires contiguous_iterator<iterator_t<R>>\n\t\tconstexpr auto data() {\n\t\t\tauto& d = derived();\n\t\t\treturn __stl2::empty(d) ? nullptr\n\t\t\t\t: std::addressof(*begin(d));\n\t\t}\n\t\ttemplate<range R = const D>\n\t\trequires contiguous_iterator<iterator_t<R>>\n\t\tconstexpr auto data() const {\n\t\t\tauto& d = derived();\n\t\t\treturn __stl2::empty(d) ? nullptr\n\t\t\t\t: std::addressof(*begin(d));\n\t\t}\n\t\ttemplate<class R = const D> // gcc_bugs_bugs_bugs\n\t\tconstexpr auto size() const\n\t\t// Distinct named concept to workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\trequires detail::SizedSentinelForwardRange<R> {\n\t\t\tauto& d = derived();\n\t\t\treturn end(d) - begin(d);\n\t\t}\n\t\tconstexpr decltype(auto) front() requires forward_range<D> {\n\t\t\tauto& d = derived();\n\t\t\tconst auto first = begin(d);\n\t\t\tSTL2_EXPECT(first != end(d));\n\t\t\treturn *first;\n\t\t}\n\t\tconstexpr decltype(auto) front() const requires forward_range<const D> {\n\t\t\tauto& d = derived();\n\t\t\tconst auto first = begin(d);\n\t\t\tSTL2_EXPECT(first != end(d));\n\t\t\treturn *first;\n\t\t}\n\t\tconstexpr decltype(auto) back()\n\t\trequires bidirectional_range<D> && common_range<D> {\n\t\t\tauto& d = derived();\n\t\t\tauto last = end(d);\n\t\t\tSTL2_EXPECT(begin(d) != last);\n\t\t\treturn *--last;\n\t\t}\n\t\tconstexpr decltype(auto) back() const\n\t\trequires bidirectional_range<const D> && common_range<const D> {\n\t\t\tauto& d = derived();\n\t\t\tauto last = end(d);\n\t\t\tSTL2_EXPECT(begin(d) != last);\n\t\t\treturn *--last;\n\t\t}\n\t\ttemplate<random_access_range R = D>\n\t\tconstexpr decltype(auto) operator[](iter_difference_t<iterator_t<R>> n) {\n\t\t\tauto& d = derived();\n\t\t\tSTL2_EXPECT(detail::is_in_range(d, n));\n\t\t\treturn begin(d)[n];\n\t\t}\n\t\ttemplate<random_access_range R = const D>\n\t\tconstexpr decltype(auto) operator[](iter_difference_t<iterator_t<R>> n) const {\n\t\t\tauto& d = derived();\n\t\t\tSTL2_EXPECT(detail::is_in_range(d, n));\n\t\t\treturn begin(d)[n];\n\t\t}\n\t\t// Extension\n\t\t// Distinct named concept to workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507\n\t\ttemplate<detail::ContainerConvertible<const D&> C>\n\t\toperator C() const {\n\t\t\tauto& d = derived();\n\t\t\tusing I = detail::__range_common_iterator<const D>;\n\t\t\treturn C(I{begin(d)}, I{end(d)});\n\t\t}\n\t};\n} STL2_CLOSE_NAMESPACE\n\n#endif\n"
  },
  {
    "path": "test/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\n\nadd_library(stl2_test_config INTERFACE)\ntarget_link_libraries(stl2_test_config INTERFACE stl2)\ntarget_link_libraries(stl2_test_config INTERFACE $<$<CONFIG:Debug>:Sanitizer::all>)\ntarget_compile_options(stl2_test_config INTERFACE\n    $<$<CXX_COMPILER_ID:GNU>:\n        -ftemplate-backtrace-limit=0 -Wall -Wextra -pedantic -Werror -march=native\n        $<$<CONFIG:Debug>:-O0 -fno-inline -g3 -fstack-protector-all>\n        $<$<CONFIG:Release>:-Ofast -g0>>)\n\nfunction(add_stl2_test TESTNAME EXENAME FIRSTSOURCE)\n  add_executable(${EXENAME} ${FIRSTSOURCE} ${ARGN})\n  target_link_libraries(${EXENAME} stl2_test_config)\n  add_test(NAME ${TESTNAME} COMMAND $<TARGET_FILE:${EXENAME}>)\n  add_dependencies(stl2-check ${EXENAME})\nendfunction(add_stl2_test)\n\nadd_stl2_test(test.headers headers headers1.cpp headers2.cpp)\nadd_stl2_test(test.range_access range_access range_access.cpp)\nadd_stl2_test(test.common common common.cpp)\nadd_stl2_test(test.meta meta meta.cpp)\n\nadd_subdirectory(concepts)\nadd_subdirectory(detail)\nadd_subdirectory(functional)\nadd_subdirectory(iterator)\nadd_subdirectory(algorithm)\nadd_subdirectory(view)\nadd_subdirectory(memory)\n"
  },
  {
    "path": "test/algorithm/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_stl2_test(test.alg.adjacent_find alg.adjacent_find adjacent_find.cpp)\nadd_stl2_test(test.alg.all_of alg.all_of all_of.cpp)\nadd_stl2_test(test.alg.any_of alg.any_of any_of.cpp)\nadd_stl2_test(test.alg.binary_search alg.binary_search binary_search.cpp)\nadd_stl2_test(test.alg.copy alg.copy copy.cpp)\nadd_stl2_test(test.alg.copy_backward alg.copy_backward copy_backward.cpp)\nadd_stl2_test(test.alg.copy_if alg.copy_if copy_if.cpp)\nadd_stl2_test(test.alg.copy_n alg.copy_n copy_n.cpp)\nadd_stl2_test(test.alg.count alg.count count.cpp)\nadd_stl2_test(test.alg.count_if alg.count_if count_if.cpp)\nadd_stl2_test(test.alg.equal alg.equal equal.cpp)\nadd_stl2_test(test.alg.equal_range alg.equal_range equal_range.cpp)\nadd_stl2_test(test.alg.fill alg.fill fill.cpp)\nadd_stl2_test(test.alg.fill_n alg.fill_n fill_n.cpp)\nadd_stl2_test(test.alg.find alg.find find.cpp)\nadd_stl2_test(test.alg.find_end alg.find_end find_end.cpp)\nadd_stl2_test(test.alg.find_first_of alg.find_first_of find_first_of.cpp)\nadd_stl2_test(test.alg.find_if alg.find_if find_if.cpp)\nadd_stl2_test(test.alg.find_if_not alg.find_if_not find_if_not.cpp)\nadd_stl2_test(test.alg.for_each alg.for_each for_each.cpp)\nadd_stl2_test(test.alg.generate alg.generate generate.cpp)\nadd_stl2_test(test.alg.generate_n alg.generate_n generate_n.cpp)\nadd_stl2_test(test.alg.includes alg.includes includes.cpp)\nadd_stl2_test(test.alg.inplace_merge alg.inplace_merge inplace_merge.cpp)\nadd_stl2_test(test.alg.is_heap1 alg.is_heap1 is_heap1.cpp)\nadd_stl2_test(test.alg.is_heap2 alg.is_heap2 is_heap2.cpp)\nadd_stl2_test(test.alg.is_heap3 alg.is_heap3 is_heap3.cpp)\nadd_stl2_test(test.alg.is_heap4 alg.is_heap4 is_heap4.cpp)\nadd_stl2_test(test.alg.is_heap_until1 alg.is_heap_until1 is_heap_until1.cpp)\nadd_stl2_test(test.alg.is_heap_until2 alg.is_heap_until2 is_heap_until2.cpp)\nadd_stl2_test(test.alg.is_heap_until3 alg.is_heap_until3 is_heap_until3.cpp)\nadd_stl2_test(test.alg.is_heap_until4 alg.is_heap_until4 is_heap_until4.cpp)\nadd_stl2_test(test.alg.is_partitioned alg.is_partitioned is_partitioned.cpp)\nadd_stl2_test(test.alg.is_permutation alg.is_permutation is_permutation.cpp)\nadd_stl2_test(test.alg.is_sorted alg.is_sorted is_sorted.cpp)\nadd_stl2_test(test.alg.is_sorted_until alg.is_sorted_until is_sorted_until.cpp)\nadd_stl2_test(test.alg.lexicographical_compare alg.lexicographical_compare lexicographical_compare.cpp)\nadd_stl2_test(test.alg.lower_bound alg.lower_bound lower_bound.cpp)\nadd_stl2_test(test.alg.make_heap alg.make_heap make_heap.cpp)\nadd_stl2_test(test.alg.max alg.max max.cpp)\nadd_stl2_test(test.alg.max_element alg.max_element max_element.cpp)\nadd_stl2_test(test.alg.merge alg.merge merge.cpp)\nadd_stl2_test(test.alg.min alg.min min.cpp)\nadd_stl2_test(test.alg.min_element alg.min_element min_element.cpp)\nadd_stl2_test(test.alg.minmax alg.minmax minmax.cpp)\nadd_stl2_test(test.alg.minmax_element alg.minmax_element minmax_element.cpp)\nadd_stl2_test(test.alg.mismatch alg.mismatch mismatch.cpp)\nadd_stl2_test(test.alg.move alg.move move.cpp)\nadd_stl2_test(test.alg.move_backward alg.move_backward move_backward.cpp)\nadd_stl2_test(test.alg.next_permutation alg.next_permutation next_permutation.cpp)\nadd_stl2_test(test.alg.none_of alg.none_of none_of.cpp)\nadd_stl2_test(test.alg.nth_element alg.nth_element nth_element.cpp)\nadd_stl2_test(test.alg.partial_sort alg.partial_sort partial_sort.cpp)\nadd_stl2_test(test.alg.partial_sort_copy alg.partial_sort_copy partial_sort_copy.cpp)\nadd_stl2_test(test.alg.partition alg.partition partition.cpp)\nadd_stl2_test(test.alg.partition_copy alg.partition_copy partition_copy.cpp)\nadd_stl2_test(test.alg.partition_point alg.partition_point partition_point.cpp)\nadd_stl2_test(test.alg.pop_heap alg.pop_heap pop_heap.cpp)\nadd_stl2_test(test.alg.prev_permutation alg.prev_permutation prev_permutation.cpp)\nadd_stl2_test(test.alg.push_heap alg.push_heap push_heap.cpp)\nadd_stl2_test(test.alg.remove alg.remove remove.cpp)\nadd_stl2_test(test.alg.remove_copy alg.remove_copy remove_copy.cpp)\nadd_stl2_test(test.alg.remove_copy_if alg.remove_copy_if remove_copy_if.cpp)\nadd_stl2_test(test.alg.remove_if alg.remove_if remove_if.cpp)\nadd_stl2_test(test.alg.replace alg.replace replace.cpp)\nadd_stl2_test(test.alg.replace_copy alg.replace_copy replace_copy.cpp)\nadd_stl2_test(test.alg.replace_copy_if alg.replace_copy_if replace_copy_if.cpp)\nadd_stl2_test(test.alg.replace_if alg.replace_if replace_if.cpp)\nadd_stl2_test(test.alg.reverse alg.reverse reverse.cpp)\nadd_stl2_test(test.alg.reverse_copy alg.reverse_copy reverse_copy.cpp)\nadd_stl2_test(test.alg.rotate alg.rotate rotate.cpp)\nadd_stl2_test(test.alg.rotate_copy alg.rotate_copy rotate_copy.cpp)\nadd_stl2_test(test.alg.sample alg.sample sample.cpp)\nadd_stl2_test(test.alg.search alg.search search.cpp)\nadd_stl2_test(test.alg.search_n alg.search_n search_n.cpp)\nadd_stl2_test(test.alg.set_difference1 alg.set_difference1 set_difference1.cpp)\nadd_stl2_test(test.alg.set_difference2 alg.set_difference2 set_difference2.cpp)\nadd_stl2_test(test.alg.set_difference3 alg.set_difference3 set_difference3.cpp)\nadd_stl2_test(test.alg.set_difference4 alg.set_difference4 set_difference4.cpp)\nadd_stl2_test(test.alg.set_difference5 alg.set_difference5 set_difference5.cpp)\nadd_stl2_test(test.alg.set_difference6 alg.set_difference6 set_difference6.cpp)\nadd_stl2_test(test.alg.set_intersection1 alg.set_intersection1 set_intersection1.cpp)\nadd_stl2_test(test.alg.set_intersection2 alg.set_intersection2 set_intersection2.cpp)\nadd_stl2_test(test.alg.set_intersection3 alg.set_intersection3 set_intersection3.cpp)\nadd_stl2_test(test.alg.set_intersection4 alg.set_intersection4 set_intersection4.cpp)\nadd_stl2_test(test.alg.set_intersection5 alg.set_intersection5 set_intersection5.cpp)\nadd_stl2_test(test.alg.set_intersection6 alg.set_intersection6 set_intersection6.cpp)\nadd_stl2_test(test.alg.set_symmetric_difference1 alg.set_symmetric_difference1 set_symmetric_difference1.cpp)\nadd_stl2_test(test.alg.set_symmetric_difference2 alg.set_symmetric_difference2 set_symmetric_difference2.cpp)\nadd_stl2_test(test.alg.set_symmetric_difference3 alg.set_symmetric_difference3 set_symmetric_difference3.cpp)\nadd_stl2_test(test.alg.set_symmetric_difference4 alg.set_symmetric_difference4 set_symmetric_difference4.cpp)\nadd_stl2_test(test.alg.set_symmetric_difference5 alg.set_symmetric_difference5 set_symmetric_difference5.cpp)\nadd_stl2_test(test.alg.set_symmetric_difference6 alg.set_symmetric_difference6 set_symmetric_difference6.cpp)\nadd_stl2_test(test.alg.set_union1 alg.set_union1 set_union1.cpp)\nadd_stl2_test(test.alg.set_union2 alg.set_union2 set_union2.cpp)\nadd_stl2_test(test.alg.set_union3 alg.set_union3 set_union3.cpp)\nadd_stl2_test(test.alg.set_union4 alg.set_union4 set_union4.cpp)\nadd_stl2_test(test.alg.set_union5 alg.set_union5 set_union5.cpp)\nadd_stl2_test(test.alg.set_union6 alg.set_union6 set_union6.cpp)\nadd_stl2_test(test.alg.shuffle alg.shuffle shuffle.cpp)\nadd_stl2_test(test.alg.sort alg.sort sort.cpp)\nadd_stl2_test(test.alg.sort_heap alg.sort_heap sort_heap.cpp)\nadd_stl2_test(test.alg.stable_partition alg.stable_partition stable_partition.cpp)\nadd_stl2_test(test.alg.stable_sort alg.stable_sort stable_sort.cpp)\nadd_stl2_test(test.alg.swap_ranges alg.swap_ranges swap_ranges.cpp)\nadd_stl2_test(test.alg.transform alg.transform transform.cpp)\nadd_stl2_test(test.alg.unique alg.unique unique.cpp)\nadd_stl2_test(test.alg.unique_copy alg.unique_copy unique_copy.cpp)\nadd_stl2_test(test.alg.upper_bound alg.upper_bound upper_bound.cpp)\n"
  },
  {
    "path": "test/algorithm/adjacent_find.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/adjacent_find.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main()\n{\n\tint v1[] = { 0, 2, 2, 4, 6 };\n\tCHECK(ranges::adjacent_find(ranges::begin(v1), ranges::end(v1)) == &v1[1]);\n\tCHECK(ranges::adjacent_find(v1) == &v1[1]);\n\n\tstd::pair<int, int> v2[] = {{0, 0}, {0, 2}, {0, 2}, {0, 4}, {0, 6}};\n\tCHECK(ranges::adjacent_find(ranges::begin(v2), ranges::end(v2),\n\t\t\tranges::equal_to{}, &std::pair<int, int>::second) == &v2[1]);\n\tCHECK(ranges::adjacent_find(v2, ranges::equal_to{}, &std::pair<int, int>::second) == &v2[1]);\n\tstatic_assert(std::is_same<\n\t\tstd::pair<int,int>*,\n\t\tdecltype(ranges::adjacent_find(v2, ranges::equal_to{},\n\t\t\t&std::pair<int, int>::second))>::value);\n\n\tauto l = {0, 2, 2, 4, 6};\n\tCHECK(ranges::adjacent_find(ranges::subrange(l))[2] == 4);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/all_of.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Andrew Sutton 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/all_of.hpp>\n\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nbool even(int n) { return n % 2 == 0; }\n\nstruct S {\n\tS(bool p) : test(p) { }\n\n\tbool p() const { return test; }\n\n\tbool test;\n};\n\nint main()\n{\n\tstd::vector<int> all_even { 0, 2, 4, 6 };\n\tstd::vector<int> one_even { 1, 3, 4, 7 };\n\tstd::vector<int> none_even { 1, 3, 5, 7 };\n\tCHECK(ranges::all_of(all_even.begin(), all_even.end(), even));\n\tCHECK(!ranges::all_of(one_even.begin(), one_even.end(), even));\n\tCHECK(!ranges::all_of(none_even.begin(), none_even.end(), even));\n\n\tCHECK(ranges::all_of(all_even, even));\n\tCHECK(!ranges::all_of(one_even, even));\n\tCHECK(!ranges::all_of(none_even, even));\n\n\t{\n\t\tauto l = {0, 2, 4, 6};\n\t\tCHECK(ranges::all_of(std::move(l), [](int n) { return n % 2 == 0; }));\n\t}\n\t{\n\t\tauto l = {1, 3, 4, 7};\n\t\tCHECK(!ranges::all_of(std::move(l), [](int n) { return n % 2 == 0; }));\n\t}\n\t{\n\t\tauto l = {1, 3, 5, 7};\n\t\tCHECK(!ranges::all_of(std::move(l), [](int n) { return n % 2 == 0; }));\n\t}\n\n\tstd::vector<S> all_true { true, true, true };\n\tstd::vector<S> one_true { false, false, true };\n\tstd::vector<S> none_true { false, false, false };\n\tCHECK(ranges::all_of(all_true.begin(), all_true.end(), &S::p));\n\tCHECK(!ranges::all_of(one_true.begin(), one_true.end(), &S::p));\n\tCHECK(!ranges::all_of(none_true.begin(), none_true.end(), &S::p));\n\n\tCHECK(ranges::all_of(all_true, &S::p));\n\tCHECK(!ranges::all_of(one_true, &S::p));\n\tCHECK(!ranges::all_of(none_true, &S::p));\n\n\t{\n\t\tauto l = {S(true), S(true), S(true)};\n\t\tCHECK(ranges::all_of(std::move(l), &S::p));\n\t}\n\t{\n\t\tauto l = {S(false), S(true), S(false)};\n\t\tCHECK(!ranges::all_of(std::move(l), &S::p));\n\t}\n\t{\n\t\tauto l = {S(false), S(false), S(false)};\n\t\tCHECK(!ranges::all_of(std::move(l), &S::p));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/any_of.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Andrew Sutton 2014\n//  Copyright Gonzalo Brito Gadeschi 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/any_of.hpp>\n\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = std::experimental::ranges;\n\nbool even(int n) { return n % 2 == 0; }\n\nstruct S {\n\tS(bool p) : test(p) { }\n\n\tbool p() const { return test; }\n\n\tbool test;\n};\n\nint main()\n{\n\tstd::vector<int> all_even { 0, 2, 4, 6 };\n\tstd::vector<int> one_even { 1, 3, 4, 7 };\n\tstd::vector<int> none_even { 1, 3, 5, 7 };\n\tCHECK(ranges::any_of(all_even.begin(), all_even.end(), even));\n\tCHECK(ranges::any_of(one_even.begin(), one_even.end(), even));\n\tCHECK(!ranges::any_of(none_even.begin(), none_even.end(), even));\n\n\tCHECK(ranges::any_of(all_even, even));\n\tCHECK(ranges::any_of(one_even, even));\n\tCHECK(!ranges::any_of(none_even, even));\n\n\t{\n\t\tauto l = {0, 2, 4, 6};\n\t\tCHECK(ranges::any_of(std::move(l), [](int n) { return n % 2 == 0; }));\n\t}\n\t{\n\t\tauto l = {1, 3, 4, 7};\n\t\tCHECK(ranges::any_of(std::move(l), [](int n) { return n % 2 == 0; }));\n\t}\n\t{\n\t\tauto l = {1, 3, 5, 7};\n\t\tCHECK(!ranges::any_of(std::move(l), [](int n) { return n % 2 == 0; }));\n\t}\n\n\tstd::vector<S> all_true { true, true, true };\n\tstd::vector<S> one_true { false, false, true };\n\tstd::vector<S> none_true { false, false, false };\n\tCHECK(ranges::any_of(all_true.begin(), all_true.end(), &S::p));\n\tCHECK(ranges::any_of(one_true.begin(), one_true.end(), &S::p));\n\tCHECK(!ranges::any_of(none_true.begin(), none_true.end(), &S::p));\n\n\tCHECK(ranges::any_of(all_true, &S::p));\n\tCHECK(ranges::any_of(one_true, &S::p));\n\tCHECK(!ranges::any_of(none_true, &S::p));\n\n\t{\n\t\tauto l = {S(true), S(true), S(true)};\n\t\tCHECK(ranges::any_of(std::move(l), &S::p));\n\t}\n\t{\n\t\tauto l = {S(false), S(true), S(false)};\n\t\tCHECK(ranges::any_of(std::move(l), &S::p));\n\t}\n\t{\n\t\tauto l = {S(false), S(false), S(false)};\n\t\tCHECK(!ranges::any_of(std::move(l), &S::p));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/binary_search.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n#include <stl2/detail/algorithm/binary_search.hpp>\n#include <stl2/view/iota.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main()\n{\n\tusing ranges::begin;\n\tusing ranges::end;\n\tusing ranges::size;\n\tusing ranges::less;\n\n\tstd::pair<int, int> a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\tconst std::pair<int, int> c[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\n\tCHECK(ranges::binary_search(begin(a), end(a), a[0]));\n\tCHECK(ranges::binary_search(begin(a), end(a), a[1], less()));\n\tCHECK(ranges::binary_search(begin(a), end(a), 1, less(), &std::pair<int, int>::first));\n\n\tCHECK(ranges::binary_search(a, a[2]));\n\tCHECK(ranges::binary_search(c, c[3]));\n\n\tCHECK(ranges::binary_search(a, a[4], less()));\n\tCHECK(ranges::binary_search(c, c[5], less()));\n\n\tCHECK(ranges::binary_search(a, 1, less(), &std::pair<int, int>::first));\n\tCHECK(ranges::binary_search(c, 1, less(), &std::pair<int, int>::first));\n\n\tCHECK(ranges::binary_search(a, 0, less(), &std::pair<int, int>::first));\n\tCHECK(ranges::binary_search(c, 0, less(), &std::pair<int, int>::first));\n\n\tCHECK(!ranges::binary_search(a, -1, less(), &std::pair<int, int>::first));\n\tCHECK(!ranges::binary_search(c, -1, less(), &std::pair<int, int>::first));\n\n\tCHECK(!ranges::binary_search(a, 4, less(), &std::pair<int, int>::first));\n\tCHECK(!ranges::binary_search(c, 4, less(), &std::pair<int, int>::first));\n\n\tCHECK(ranges::binary_search(ranges::iota_view<int>{0}, 42));\n\n\t{\n\t\tauto il = {0, 3, 5, 7, 9, 11, 13};\n\t\tCHECK(ranges::binary_search(std::move(il), 11));\n\t}\n\t{\n\t\tauto il = {0, 3, 5, 7, 9, 11, 13};\n\t\tCHECK(!ranges::binary_search(std::move(il), 8));\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/utility.hpp>\n#include <algorithm>\n#include <cstring>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<ranges::input_iterator I>\n\trequires ranges::regular<ranges::iter_value_t<I>>\nstruct delimiter {\n\tdelimiter() = default;\n\tdelimiter(ranges::iter_value_t<I> value) :\n\t\tvalue_{std::move(value)} {}\n\n\tfriend bool operator==(const delimiter& lhs, const delimiter& rhs) {\n\t\treturn lhs.value_ == rhs.value_;\n\t}\n\tfriend bool operator!=(const delimiter& lhs, const delimiter& rhs) {\n\t\treturn !(lhs == rhs);\n\t}\n\tfriend bool operator==(const I& i, const delimiter& s) {\n\t\treturn *i == s.value_;\n\t}\n\tfriend bool operator==(const delimiter& s, const I& i) {\n\t\treturn i == s;\n\t}\n\tfriend bool operator!=(const I& i, const delimiter& s) {\n\t\treturn !(i == s);\n\t}\n\tfriend bool operator!=(const delimiter& s, const I& i) {\n\t\treturn !(i == s);\n\t}\nprivate:\n\tranges::iter_value_t<I> value_;\n};\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I>\n\tstruct common_type<I, ::delimiter<I>> {\n\t\tusing type = common_iterator<I, ::delimiter<I>>;\n\t};\n\ttemplate<class I>\n\t\tstruct common_type<::delimiter<I>, I> {\n\t\tusing type = common_iterator<I, ::delimiter<I>>;\n\t};\n} STL2_CLOSE_NAMESPACE\n\nint main() {\n\tusing ranges::begin;\n\tusing ranges::end;\n\tusing ranges::size;\n\n\tstd::pair<int, int> const a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\tstatic_assert(size(a) == 6, \"\");\n\tstd::pair<int, int> out[size(a)] = {};\n\n\tauto res = ranges::copy(begin(a), end(a), out);\n\tCHECK(res.in == end(a));\n\tCHECK(res.out == out + size(out));\n\tCHECK(std::equal(a, a + size(a), out));\n\n\tstd::fill_n(out, size(out), std::make_pair(0, 0));\n\tCHECK(!std::equal(a, a + size(a), out));\n\n\tres = ranges::copy(a, out);\n\tCHECK(res.in == a + size(a));\n\tCHECK(res.out == out + size(out));\n\tCHECK(std::equal(a, a + size(a), out));\n\n\tstd::fill_n(out, size(out), std::make_pair(0, 0));\n\n\t{\n\t\tchar const *sz = \"hello world\";\n\t\tchar buf[50];\n\t\tauto str = ranges::subrange(sz, delimiter<const char*>{'\\0'});\n\t\t{\n\t\t\tstd::fill_n(buf, sizeof(buf), '\\0');\n\t\t\tauto res3 = ranges::copy(str, buf);\n\t\t\t*res3.out = '\\0';\n\t\t\tCHECK(res3.in == std::next(begin(str), std::strlen(sz)));\n\t\t\tCHECK(res3.out == buf + std::strlen(sz));\n\t\t\tCHECK(std::strcmp(sz, buf) == 0);\n\t\t}\n\t\t{\n\t\t\tstd::fill_n(buf, sizeof(buf), '\\0');\n\t\t\tauto res4 = ranges::copy(std::move(str), buf);\n\t\t\t*res4.out = '\\0';\n\t\t\tCHECK(res4.in == std::next(begin(str), std::strlen(sz)));\n\t\t\tCHECK(res4.out == buf + std::strlen(sz));\n\t\t\tCHECK(std::strcmp(sz, buf) == 0);\n\t\t}\n\t}\n\n\t{\n\t\tint target[8]{};\n\t\tauto l = {1,2,3,4,5,6};\n\t\tCHECK(ranges::copy(std::move(l), target + 1).out == target + 7);\n\t\tCHECK_EQUAL(target, {0,1,2,3,4,5,6,0});\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/copy_backward.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/copy_backward.hpp>\n#include <stl2/view/repeat.hpp>\n#include <cstring>\n#include <utility>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tvoid test_repeat_view() {\n\t\t{\n\t\t\tauto v = ranges::ext::repeat_view<int>(42);\n\t\t\tint target[8]{};\n\t\t\tauto result = ranges::copy_backward(ranges::counted_iterator{v.begin(), 4},\n\t\t\t\tranges::counted_iterator{v.begin(), 0}, ranges::end(target));\n\t\t\tCHECK(result.in.count() == 0);\n\t\t\tCHECK(result.in.base() == v.begin());\n\t\t\tCHECK(result.out == target + 4);\n\t\t\tCHECK(std::count(target, target + 4, 0) == 4);\n\t\t\tCHECK(std::count(target + 4, target + 8, 42) == 4);\n\t\t}\n\t\t{\n\t\t\tauto v = ranges::ext::repeat_view<int>(42);\n\t\t\tint target[8]{};\n\t\t\tauto result = ranges::copy_backward(ranges::counted_iterator{v.begin(), 4},\n\t\t\t\tranges::default_sentinel, ranges::end(target));\n\t\t\tCHECK(result.in.count() == 0);\n\t\t\tCHECK(result.in.base() == v.begin());\n\t\t\tCHECK(result.out == target + 4);\n\t\t\tCHECK(std::count(target, target + 4, 0) == 4);\n\t\t\tCHECK(std::count(target + 4, target + 8, 42) == 4);\n\t\t}\n\t}\n\n\tvoid test_initializer_list() {\n\t\tint target[8]{};\n\t\tauto l1 = {1, 2, 3, 4};\n\t\tauto result = ranges::copy_backward(std::move(l1), ranges::end(target));\n\t\tCHECK(result.out == target + 4);\n\t\tCHECK(std::count(target, target + 4, 0) == 4);\n\t\tauto l2 = {1, 2, 3, 4};\n\t\tCHECK_EQUAL(ranges::subrange(target + 4, target + 8), std::move(l2));\n\t}\n}\n\nint main() {\n\tusing ranges::begin;\n\tusing ranges::end;\n\tusing ranges::size;\n\n\tstd::pair<int, int> const a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\tstatic_assert(size(a) == 6, \"\");\n\tstd::pair<int, int> out[size(a)] = {};\n\n\tauto res = ranges::copy_backward(begin(a), end(a), end(out));\n\tCHECK(res.in == end(a));\n\tCHECK(res.out == begin(out));\n\tCHECK(std::equal(a, a + size(a), out));\n\n\tstd::fill_n(out, size(out), std::pair(0, 0));\n\tCHECK(!std::equal(a, a + size(a), out));\n\n\tres = ranges::copy_backward(a, end(out));\n\tCHECK(res.in == end(a));\n\tCHECK(res.out == begin(out));\n\tCHECK(std::equal(a, a + size(a), out));\n\n\tstd::fill_n(out, size(out), std::pair(0, 0));\n\tauto res2 = ranges::copy_backward(std::move(a), end(out));\n\tCHECK(res2.out == begin(out));\n\tCHECK(std::equal(a, a + size(a), out));\n\n\ttest_repeat_view();\n\ttest_initializer_list();\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/copy_if.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/algorithm/copy_if.hpp>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main() {\n\tstatic const int source[] = {5,4,3,2,1,0};\n\tstatic constexpr std::ptrdiff_t n = sizeof(source)/sizeof(source[0]);\n\n\tstatic const int evens[] = {4,2,0};\n\tstatic_assert(sizeof(evens) / sizeof(evens[0]) == n / 2);\n\tauto is_even = [](int i) {\n\t\treturn i % 2 == 0;\n\t};\n\n\n\t{\n\t\tint target[n];\n\t\tstd::fill_n(target, n, -1);\n\n\t\tstatic const int evens[] = {4,2,0};\n\t\tauto is_even = [](int i){\n\t\t\treturn i % 2 == 0;\n\t\t};\n\n\t\tauto res = ranges::copy_if(source, source + n, target, is_even);\n\t\tCHECK(res.in == source + n);\n\t\tCHECK(res.out == target + n / 2);\n\n\t\tCHECK(std::equal(target, target + n / 2, evens));\n\t\tCHECK(std::count(target + n / 2, target + n, -1) == n / 2);\n\t}\n\n\t{\n\t\tint target[n];\n\t\tstd::fill_n(target, n, -1);\n\n\t\tauto res = ranges::copy_if(source, target, is_even);\n\t\tCHECK(res.in == source + n);\n\t\tCHECK(res.out == target + n / 2);\n\n\t\tCHECK(std::equal(target, target + n / 2, evens));\n\t\tCHECK(std::count(target + n / 2, target + n, -1) == n / 2);\n\t}\n\n\t{\n\t\tint target[n];\n\t\tstd::fill_n(target, n, -1);\n\n\t\tauto res = ranges::copy_if(std::move(source), target, is_even);\n\t\tstatic_assert(ranges::same_as<decltype(res.in), ranges::dangling>);\n\t\tCHECK(res.out == target + n / 2);\n\n\t\tCHECK(std::equal(target, target + n / 2, evens));\n\t\tCHECK(std::count(target + n / 2, target + n, -1) == n / 2);\n\t}\n\n\t{\n\t\tstruct S { int value; };\n\t\tS source[n];\n\t\tfor (auto i = n; i-- > 0;) {\n\t\t\tsource[i].value = i;\n\t\t}\n\t\tS target[n];\n\t\tfor (auto i = n; i-- > 0;) {\n\t\t\ttarget[i].value = -1;\n\t\t}\n\n\t\tauto res = ranges::copy_if(source, target, is_even, &S::value);\n\t\tCHECK(res.in == source + n);\n\t\tCHECK(res.out == target + n / 2);\n\n\t\tfor (auto i = n / 2; i-- > 0;) {\n\t\t\tCHECK(target[i].value == source[2 * i].value);\n\t\t}\n\n\t\tCHECK(std::count_if(target + n / 2, target + n, [](const S& s){\n\t\t\t\t\treturn s.value == -1; }) == n / 2);\n\t}\n\n\t{\n\t\tint target[n];\n\t\tstd::fill_n(target, n, -1);\n\n\t\t{\n\t\t\tauto l = {5,4,3,2,1,0};\n\t\t\tauto res = ranges::copy_if(std::move(l), target, is_even);\n\t\t\tCHECK(res.out == target + n / 2);\n\t\t}\n\n\t\tCHECK(std::equal(target, target + n / 2, evens));\n\t\tCHECK(std::count(target + n / 2, target + n, -1) == n / 2);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/copy_n.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/algorithm/copy_n.hpp>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main() {\n\tstatic const int source[] = {5,4,3,2,1,0};\n\tstatic constexpr std::ptrdiff_t n = sizeof(source)/sizeof(source[0]);\n\tint target[n];\n\n\tstd::fill_n(target, n, 0);\n\tstatic_assert(n >= 2);\n\tauto res = ranges::copy_n(source, n - 2, target);\n\tCHECK(res.in == source + n - 2);\n\tCHECK(res.out == target + n - 2);\n\n\tCHECK(std::equal(source, source + n - 2, target));\n\tCHECK(target[n - 2] == 0);\n\tCHECK(target[n - 1] == 0);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/count.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Andrew Sutton 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/count.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\tusing __stl2::count, __stl2::size, __stl2::subrange;\n\n\tint ia[] = {0, 1, 2, 2, 0, 1, 2, 3};\n\tconstexpr unsigned cia = size(ia);\n\n\tCHECK(count(input_iterator<const int*>(ia),\n\t\t\t\tsentinel<const int*>(ia + cia), 2) == 3);\n\tCHECK(count(input_iterator<const int*>(ia),\n\t\t\t\tsentinel<const int*>(ia + cia), 7) == 0);\n\tCHECK(count(input_iterator<const int*>(ia),\n\t\t\t\tsentinel<const int*>(ia), 2) == 0);\n\n\tCHECK(count(subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t  sentinel<const int*>(ia + cia)), 2) == 3);\n\tCHECK(count(subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t  sentinel<const int*>(ia + cia)), 7) == 0);\n\tCHECK(count(subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t  sentinel<const int*>(ia)), 2) == 0);\n\n\tS sa[] = {{0}, {1}, {2}, {2}, {0}, {1}, {2}, {3}};\n\tconstexpr unsigned csa = size(ia);\n\n\tCHECK(count(input_iterator<const S*>(sa),\n\t\t\t\tsentinel<const S*>(sa + csa), 2, &S::i) == 3);\n\tCHECK(count(input_iterator<const S*>(sa),\n\t\t\t\tsentinel<const S*>(sa + csa), 7, &S::i) == 0);\n\tCHECK(count(input_iterator<const S*>(sa),\n\t\t\t\tsentinel<const S*>(sa), 2, &S::i) == 0);\n\n\tCHECK(count(subrange(input_iterator<const S*>(sa),\n\t\t\t\t\t  sentinel<const S*>(sa + csa)), 2, &S::i) == 3);\n\tCHECK(count(subrange(input_iterator<const S*>(sa),\n\t\t\t\t\t  sentinel<const S*>(sa + csa)), 7, &S::i) == 0);\n\tCHECK(count(subrange(input_iterator<const S*>(sa),\n\t\t\t\t\t  sentinel<const S*>(sa)), 2, &S::i) == 0);\n\n\t{\n\t\tauto l = {0, 1, 2, 2, 0, 1, 2, 3};\n\t\tCHECK(count(std::move(l), 2) == 3);\n\t}\n\t{\n\t\tauto l = {0, 1, 2, 2, 0, 1, 2, 3};\n\t\tCHECK(count(std::move(l), 7) == 0);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/count_if.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/count_if.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nstruct S\n{\n\tint i;\n};\n\nstruct T\n{\n\tbool b;\n\tbool m() { return b; }\n};\n\nint main()\n{\n\tusing __stl2::count_if, __stl2::size, __stl2::subrange;\n\n\tauto equals = [](auto&& i){\n\t  return [i = static_cast<decltype(i)>(i)](const auto& j) {\n\t\treturn i == j;\n\t  };\n\t};\n\n\tint ia[] = {0, 1, 2, 2, 0, 1, 2, 3};\n\tconstexpr unsigned cia = size(ia);\n\n\tCHECK(count_if(input_iterator<const int*>(ia),\n\t\t\t\t   sentinel<const int*>(ia + cia), equals(2)) == 3);\n\tCHECK(count_if(input_iterator<const int*>(ia),\n\t\t\t\t   sentinel<const int*>(ia + cia), equals(7)) == 0);\n\tCHECK(count_if(input_iterator<const int*>(ia),\n\t\t\t\t   sentinel<const int*>(ia), equals(2)) == 0);\n\n\tCHECK(count_if(subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t sentinel<const int*>(ia + cia)), equals(2)) == 3);\n\tCHECK(count_if(subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t sentinel<const int*>(ia + cia)), equals(7)) == 0);\n\tCHECK(count_if(subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t sentinel<const int*>(ia)), equals(2)) == 0);\n\n\tS sa[] = {{0}, {1}, {2}, {2}, {0}, {1}, {2}, {3}};\n\tconstexpr unsigned csa = size(ia);\n\n\tCHECK(count_if(input_iterator<const S*>(sa),\n\t\t\t\t   sentinel<const S*>(sa + csa), equals(2), &S::i) == 3);\n\tCHECK(count_if(input_iterator<const S*>(sa),\n\t\t\t\t   sentinel<const S*>(sa + csa), equals(7), &S::i) == 0);\n\tCHECK(count_if(input_iterator<const S*>(sa),\n\t\t\t\t   sentinel<const S*>(sa), equals(2), &S::i) == 0);\n\n\tCHECK(count_if(subrange(input_iterator<const S*>(sa),\n\t\t\t\t\t\t sentinel<const S*>(sa + csa)), equals(2), &S::i) == 3);\n\tCHECK(count_if(subrange(input_iterator<const S*>(sa),\n\t\t\t\t\t\t sentinel<const S*>(sa + csa)), equals(7), &S::i) == 0);\n\tCHECK(count_if(subrange(input_iterator<const S*>(sa),\n\t\t\t\t\t\t sentinel<const S*>(sa)), equals(2), &S::i) == 0);\n\n\tT ta[] = {{true}, {false}, {true}, {false}, {false}, {true}, {false}, {false}, {true}, {false}};\n\tCHECK(count_if(input_iterator<T*>(ta),\n\t\t\t\t   sentinel<T*>(ta + size(ta)), &T::m) == 4);\n\tCHECK(count_if(input_iterator<T*>(ta),\n\t\t\t\t   sentinel<T*>(ta + size(ta)), &T::b) == 4);\n\tCHECK(count_if(subrange(input_iterator<T*>(ta),\n\t\t\t\t\t\t sentinel<T*>(ta + size(ta))), &T::m) == 4);\n\tCHECK(count_if(subrange(input_iterator<T*>(ta),\n\t\t\t\t\t\t sentinel<T*>(ta + size(ta))), &T::b) == 4);\n\n\t{\n\t\tauto l = {0, 1, 2, 2, 0, 1, 2, 3};\n\t\tCHECK(count_if(std::move(l), equals(2)) == 3);\n\t}\n\t{\n\t\tauto l = {0, 1, 2, 2, 0, 1, 2, 3};\n\t\tCHECK(count_if(std::move(l), equals(42)) == 0);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/equal.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/equal.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nint comparison_count = 0;\n\ntemplate<typename T>\nbool counting_equals(const T &a, const T &b) {\n\t++comparison_count;\n\treturn a == b;\n}\n\nint main() {\n\tusing ranges::equal, ranges::distance, ranges::subrange;\n\n\tauto test_case = [](const bool result, const int count,\n\t\tconst auto first1, const auto last1, const auto first2, const auto last2)\n\t{\n\t\tCHECK(equal(first1, last1, first2, last2) == result);\n\n\t\tcomparison_count = 0;\n\t\tCHECK(equal(first1, last1, first2, last2, counting_equals<int>) == result);\n\t\tCHECK(comparison_count == count);\n\n\t\tCHECK(equal(subrange{first1, last1}, subrange{first2, last2}) == result);\n\n\t\tcomparison_count = 0;\n\t\tCHECK(equal(subrange{first1, last1}, subrange{first2, last2}, counting_equals<int>) == result);\n\t\tCHECK(comparison_count == count);\n\t};\n\n\tusing I = input_iterator<const int*>;\n\tusing S = sentinel<const int*>;\n\tusing R = random_access_iterator<const int*>;\n\n\tstatic const int ia[] = {0, 1, 2, 3, 4, 5};\n\tconstexpr auto s = distance(ia);\n\tstatic const int ib[] = {0, 1, 2, 5, 4, 5};\n\tstatic_assert(distance(ib) == s);\n\n\ttest_case(true,  s,     I(ia), S(ia + s), I(ia), S(ia + s));\n\ttest_case(true,  s,     R(ia), R(ia + s), R(ia), R(ia + s));\n\ttest_case(true,  s,     R(ia), S(ia + s), R(ia), S(ia + s));\n\ttest_case(false, 4,     I(ia), S(ia + s), I(ib), S(ib + s));\n\ttest_case(false, 4,     R(ia), R(ia + s), R(ib), R(ib + s));\n\ttest_case(false, 4,     R(ia), S(ia + s), R(ib), S(ib + s));\n\ttest_case(false, s - 1, I(ia), S(ia + s), I(ia), S(ia + s - 1));\n\ttest_case(false, 0,     R(ia), R(ia + s), R(ia), R(ia + s - 1));\n\ttest_case(false, s - 1, R(ia), S(ia + s), R(ia), S(ia + s - 1));\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/equal_range.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/equal_range.hpp>\n#include <iterator>\n#include <vector>\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/iterator/move_iterator.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/join.hpp>\n#include <stl2/view/repeat_n.hpp>\n#include <stl2/view/take.hpp>\n#include <stl2/view/transform.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct my_int {\n\tint value;\n};\n\nbool compare(my_int lhs, my_int rhs) {\n\treturn lhs.value < rhs.value;\n}\n\nvoid not_totally_ordered() {\n\t// This better compile!\n\tstd::vector<my_int> vec;\n\tranges::equal_range(vec, my_int{10}, compare);\n}\n\ntemplate<class Iter, class Sent, class T, class Proj = ranges::identity>\nvoid test(Iter first, Sent last, const T& value, Proj proj = {}) {\n\tauto i = ranges::equal_range(first, last, value, ranges::less{}, proj);\n\tfor (Iter j = first; j != i.begin(); ++j)\n\t\tCHECK(ranges::invoke(proj, *j) < value);\n\tfor (Iter j = i.begin(); j != last; ++j)\n\t\tCHECK(!(ranges::invoke(proj, *j) < value));\n\tfor (Iter j = first; j != i.end(); ++j)\n\t\tCHECK(!(value < ranges::invoke(proj, *j)));\n\tfor (Iter j = i.end(); j != last; ++j)\n\t\tCHECK(value < ranges::invoke(proj, *j));\n\n\tauto res = ranges::equal_range(\n\t\tranges::subrange(first, last), value, ranges::less{}, proj);\n\tfor (Iter j = first; j != res.begin(); ++j)\n\t\tCHECK(ranges::invoke(proj, *j) < value);\n\tfor (Iter j = res.begin(); j != last; ++j)\n\t\tCHECK(!(ranges::invoke(proj, *j) < value));\n\tfor (Iter j = first; j != res.end(); ++j)\n\t\tCHECK(!(value < ranges::invoke(proj, *j)));\n\tfor (Iter j = res.end(); j != last; ++j)\n\t\tCHECK(value < ranges::invoke(proj, *j));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test() {\n\tusing namespace ranges::views;\n\tstatic constexpr unsigned M = 10;\n\tstd::vector<int> v;\n\tauto input = iota(0) | take(100) | transform([](int i){return ext::repeat_n(i,M);}) | join;\n\tranges::copy(input, ranges::back_inserter(v));\n\tfor (int x = 0; x <= (int)M; ++x)\n\t\ttest(Iter(v.data()), Sent(v.data()+v.size()), x);\n}\n\nint main() {\n\tint d[] = {0, 1, 2, 3};\n\tfor (int* e = d; e <= d+4; ++e)\n\t\tfor (int x = -1; x <= 4; ++x)\n\t\t\ttest(d, e, x);\n\n\ttest<forward_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*> >();\n\ttest<random_access_iterator<const int*> >();\n\ttest<const int*>();\n\n\ttest<forward_iterator<const int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, sentinel<const int*> >();\n\n\t{\n\t\tstruct foo { int i; };\n\n\t\tfoo some_foos[] = {{1}, {2}, {4}};\n\t\ttest(some_foos, some_foos + 3, 2, &foo::i);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/fill.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/fill.hpp>\n#include <cstring>\n#include <string>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_char() {\n\tconst unsigned n = 4;\n\tchar ca[n] = {0};\n\tauto i = ranges::fill(Iter(ca), Sent(ca+n), char(1));\n\tCHECK(ca[0] == 1);\n\tCHECK(ca[1] == 1);\n\tCHECK(ca[2] == 1);\n\tCHECK(ca[3] == 1);\n\tCHECK(i == Iter(ca + 4));\n\n\tauto rng = ranges::subrange(Iter(ca), Sent(ca+n));\n\ti = ranges::fill(rng, char(2));\n\tCHECK(ca[0] == 2);\n\tCHECK(ca[1] == 2);\n\tCHECK(ca[2] == 2);\n\tCHECK(ca[3] == 2);\n\tCHECK(i == Iter(ca + 4));\n\n\tauto j = ranges::fill(ranges::subrange(Iter(ca), Sent(ca+n)), char(3));\n\tCHECK(ca[0] == 3);\n\tCHECK(ca[1] == 3);\n\tCHECK(ca[2] == 3);\n\tCHECK(ca[3] == 3);\n\tCHECK(j == Iter(ca + 4));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_int() {\n\tconst unsigned n = 4;\n\tint ia[n] = {0};\n\tranges::fill(Iter(ia), Sent(ia+n), 1);\n\tCHECK(ia[0] == 1);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 1);\n\tCHECK(ia[3] == 1);\n\n\tauto rng = ranges::subrange(Iter(ia), Sent(ia+n));\n\tranges::fill(rng, 2);\n\tCHECK(ia[0] == 2);\n\tCHECK(ia[2] == 2);\n\tCHECK(ia[2] == 2);\n\tCHECK(ia[3] == 2);\n}\n\nint main() {\n\ttest_char<forward_iterator<char*> >();\n\ttest_char<bidirectional_iterator<char*> >();\n\ttest_char<random_access_iterator<char*> >();\n\ttest_char<char*>();\n\n\ttest_char<forward_iterator<char*>, sentinel<char*> >();\n\ttest_char<bidirectional_iterator<char*>, sentinel<char*> >();\n\ttest_char<random_access_iterator<char*>, sentinel<char*> >();\n\n\ttest_int<forward_iterator<int*> >();\n\ttest_int<bidirectional_iterator<int*> >();\n\ttest_int<random_access_iterator<int*> >();\n\ttest_int<int*>();\n\n\ttest_int<forward_iterator<int*>, sentinel<int*> >();\n\ttest_int<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_int<random_access_iterator<int*>, sentinel<int*> >();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/fill_n.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/fill_n.hpp>\n#include <cstring>\n#include <string>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<ranges::forward_iterator I, ranges::sentinel_for<I> S, class T>\n\trequires ranges::writable<I, const T&>\nI count_and_fill(I i, S s, const T& t) {\n\treturn ranges::fill_n(i, ranges::distance(i, s), t);\n}\n\ntemplate<ranges::forward_range Rng, class T>\n\trequires ranges::writable<ranges::iterator_t<Rng>, const T&>\nranges::safe_iterator_t<Rng> count_and_fill(Rng&& rng, const T& t) {\n\treturn ranges::fill_n(ranges::begin(rng), ranges::distance(rng), t);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_char() {\n\tconst unsigned n = 4;\n\tchar ca[n] = {0};\n\tauto i = count_and_fill(Iter(ca), Sent(ca+n), char(1));\n\tCHECK(ca[0] == 1);\n\tCHECK(ca[1] == 1);\n\tCHECK(ca[2] == 1);\n\tCHECK(ca[3] == 1);\n\tCHECK(i == Iter(ca + 4));\n\n\tauto rng = ranges::subrange(Iter(ca), Sent(ca+n));\n\ti = count_and_fill(rng, char(2));\n\tCHECK(ca[0] == 2);\n\tCHECK(ca[1] == 2);\n\tCHECK(ca[2] == 2);\n\tCHECK(ca[3] == 2);\n\tCHECK(i == Iter(ca + 4));\n\n\tauto j = count_and_fill(ranges::subrange(Iter(ca), Sent(ca+n)), char(3));\n\tCHECK(ca[0] == 3);\n\tCHECK(ca[1] == 3);\n\tCHECK(ca[2] == 3);\n\tCHECK(ca[3] == 3);\n\tCHECK(j == Iter(ca + 4));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_int() {\n\tconst unsigned n = 4;\n\tint ia[n] = {0};\n\tcount_and_fill(Iter(ia), Sent(ia+n), 1);\n\tCHECK(ia[0] == 1);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 1);\n\tCHECK(ia[3] == 1);\n\n\tauto rng = ranges::subrange(Iter(ia), Sent(ia+n));\n\tcount_and_fill(rng, 2);\n\tCHECK(ia[0] == 2);\n\tCHECK(ia[2] == 2);\n\tCHECK(ia[2] == 2);\n\tCHECK(ia[3] == 2);\n}\n\nint main() {\n\ttest_char<forward_iterator<char*> >();\n\ttest_char<bidirectional_iterator<char*> >();\n\ttest_char<random_access_iterator<char*> >();\n\ttest_char<char*>();\n\n\ttest_char<forward_iterator<char*>, sentinel<char*> >();\n\ttest_char<bidirectional_iterator<char*>, sentinel<char*> >();\n\ttest_char<random_access_iterator<char*>, sentinel<char*> >();\n\n\ttest_int<forward_iterator<int*> >();\n\ttest_int<bidirectional_iterator<int*> >();\n\ttest_int<random_access_iterator<int*> >();\n\ttest_int<int*>();\n\n\ttest_int<forward_iterator<int*>, sentinel<int*> >();\n\ttest_int<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_int<random_access_iterator<int*>, sentinel<int*> >();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/find.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/find.hpp>\n#include <stl2/utility.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct S {\n\tint i_;\n};\n\nint main() {\n\tusing ranges::find, ranges::size, ranges::subrange, ranges::end;\n\n\tint ia[] = {0, 1, 2, 3, 4, 5};\n\tauto first = [&ia]{ return input_iterator<const int*>{ia}; };\n\tconstexpr auto s = size(ia);\n\tconst auto last = sentinel<const int*>(ia + s);\n\n\tauto r = find(first(), last, 3);\n\tCHECK((r != last && *r == 3));\n\n\tr = find(first(), last, 10);\n\tCHECK(r == last);\n\n\tint *pi = find(ia, 3);\n\tCHECK((pi != ia+s && *pi == 3));\n\tpi = find(ia, 10);\n\tCHECK(pi == ia+s);\n\n\tauto pj = find(subrange(ia), 3);\n\tCHECK((pj != ia+s && *pj == 3));\n\tpj = find(subrange(ia), 10);\n\tCHECK(pj == ia+s);\n\n\tS sa[] = {{0}, {1}, {2}, {3}, {4}, {5}};\n\tS *ps = find(sa, 3, &S::i_);\n\tCHECK((ps != end(sa) && ps->i_ == 3));\n\tps = find(sa, 10, &S::i_);\n\tCHECK(ps == end(sa));\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/find_end.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/find_end.hpp>\n#include <stl2/utility.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>\nvoid test() {\n\tusing namespace ranges;\n\n\tint ia[] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 0, 1, 0};\n\tconstexpr unsigned sa = size(ia);\n\tint b[] = {0};\n\tint c[] = {0, 1};\n\tint d[] = {0, 1, 2};\n\tint e[] = {0, 1, 2, 3};\n\tint f[] = {0, 1, 2, 3, 4};\n\tint g[] = {0, 1, 2, 3, 4, 5};\n\tint h[] = {0, 1, 2, 3, 4, 5, 6};\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b + 1)) == Iter1(ia + sa - 1));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(c), Sent2(c + 2)) == Iter1(ia + 18));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(d), Sent2(d + 3)) == Iter1(ia + 15));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(e), Sent2(e + 4)) == Iter1(ia + 11));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(f), Sent2(f + 5)) == Iter1(ia + 6));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(g), Sent2(g + 6)) == Iter1(ia));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(h), Sent2(h + 7)) == Iter1(ia + sa));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b)) == Iter1(ia + sa));\n\tCHECK(find_end(Iter1(ia), Sent1(ia), Iter2(b), Sent2(b + 1)) == Iter1(ia));\n\n\tauto ir = subrange(Iter1(ia), Sent1(ia + sa));\n\tCHECK(find_end(ir, subrange(Iter2(b), Sent2(b + 1))) == Iter1(ia + sa - 1));\n\tCHECK(find_end(ir, subrange(Iter2(c), Sent2(c + 2))) == Iter1(ia + 18));\n\tCHECK(find_end(ir, subrange(Iter2(d), Sent2(d + 3))) == Iter1(ia + 15));\n\tCHECK(find_end(ir, subrange(Iter2(e), Sent2(e + 4))) == Iter1(ia + 11));\n\tCHECK(find_end(ir, subrange(Iter2(f), Sent2(f + 5))) == Iter1(ia + 6));\n\tCHECK(find_end(ir, subrange(Iter2(g), Sent2(g + 6))) == Iter1(ia));\n\tCHECK(find_end(ir, subrange(Iter2(h), Sent2(h + 7))) == Iter1(ia + sa));\n\tCHECK(find_end(ir, subrange(Iter2(b), Sent2(b))) == Iter1(ia + sa));\n\n\tCHECK(find_end(std::move(ir), subrange(Iter2(b), Sent2(b + 1))) == Iter1(ia + sa - 1));\n\tCHECK(find_end(std::move(ir), subrange(Iter2(c), Sent2(c + 2))) == Iter1(ia + 18));\n\tCHECK(find_end(std::move(ir), subrange(Iter2(d), Sent2(d + 3))) == Iter1(ia + 15));\n\tCHECK(find_end(std::move(ir), subrange(Iter2(e), Sent2(e + 4))) == Iter1(ia + 11));\n\tCHECK(find_end(std::move(ir), subrange(Iter2(f), Sent2(f + 5))) == Iter1(ia + 6));\n\tCHECK(find_end(std::move(ir), subrange(Iter2(g), Sent2(g + 6))) == Iter1(ia));\n\tCHECK(find_end(std::move(ir), subrange(Iter2(h), Sent2(h + 7))) == Iter1(ia + sa));\n\tCHECK(find_end(std::move(ir), subrange(Iter2(b), Sent2(b))) == Iter1(ia + sa));\n\n\tauto er = subrange(Iter1(ia), Sent1(ia));\n\tCHECK(find_end(er, subrange(Iter2(b), Sent2(b + 1))) == Iter1(ia));\n\tCHECK(find_end(std::move(er), subrange(Iter2(b), Sent2(b + 1))) == Iter1(ia));\n}\n\nstruct count_equal {\n\tstatic unsigned count;\n\ttemplate<class T>\n\tbool operator()(const T& x, const T& y) {\n\t\t++count; return x == y;\n\t}\n};\n\nunsigned count_equal::count = 0;\n\ntemplate<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>\nvoid test_pred() {\n\tusing namespace ranges;\n\n\tint ia[] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 0, 1, 0};\n\tconstexpr unsigned sa = size(ia);\n\tint b[] = {0};\n\tint c[] = {0, 1};\n\tint d[] = {0, 1, 2};\n\tint e[] = {0, 1, 2, 3};\n\tint f[] = {0, 1, 2, 3, 4};\n\tint g[] = {0, 1, 2, 3, 4, 5};\n\tint h[] = {0, 1, 2, 3, 4, 5, 6};\n\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b + 1), count_equal()) == Iter1(ia + sa - 1));\n\tCHECK(count_equal::count <= 1 * (sa - 1 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(c), Sent2(c + 2), count_equal()) == Iter1(ia + 18));\n\tCHECK(count_equal::count <= 2 * (sa - 2 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(d), Sent2(d + 3), count_equal()) == Iter1(ia + 15));\n\tCHECK(count_equal::count <= 3 * (sa - 3 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(e), Sent2(e + 4), count_equal()) == Iter1(ia + 11));\n\tCHECK(count_equal::count <= 4 * (sa - 4 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(f), Sent2(f + 5), count_equal()) == Iter1(ia + 6));\n\tCHECK(count_equal::count <= 5 * (sa - 5 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(g), Sent2(g + 6), count_equal()) == Iter1(ia));\n\tCHECK(count_equal::count <= 6 * (sa - 6 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(h), Sent2(h + 7), count_equal()) == Iter1(ia + sa));\n\tCHECK(count_equal::count <= 7 * (sa - 7 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b), count_equal()) == Iter1(ia + sa));\n\tCHECK(count_equal::count == 0u);\n\tcount_equal::count = 0;\n\tCHECK(find_end(Iter1(ia), Sent1(ia), Iter2(b), Sent2(b + 1), count_equal()) == Iter1(ia));\n\tCHECK(count_equal::count == 0u);\n\n\tauto ir = subrange(Iter1(ia), Sent1(ia + sa));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(b), Sent2(b + 1)), count_equal()) == Iter1(ia + sa - 1));\n\tCHECK(count_equal::count <= 1 * (sa - 1 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(c), Sent2(c + 2)), count_equal()) == Iter1(ia + 18));\n\tCHECK(count_equal::count <= 2 * (sa - 2 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(d), Sent2(d + 3)), count_equal()) == Iter1(ia + 15));\n\tCHECK(count_equal::count <= 3 * (sa - 3 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(e), Sent2(e + 4)), count_equal()) == Iter1(ia + 11));\n\tCHECK(count_equal::count <= 4 * (sa - 4 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(f), Sent2(f + 5)), count_equal()) == Iter1(ia + 6));\n\tCHECK(count_equal::count <= 5 * (sa - 5 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(g), Sent2(g + 6)), count_equal()) == Iter1(ia));\n\tCHECK(count_equal::count <= 6 * (sa - 6 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(h), Sent2(h + 7)), count_equal()) == Iter1(ia + sa));\n\tCHECK(count_equal::count <= 7 * (sa - 7 + 1));\n\tcount_equal::count = 0;\n\tCHECK(find_end(ir, subrange(Iter2(b), Sent2(b)), count_equal()) == Iter1(ia + sa));\n\tCHECK(count_equal::count == 0u);\n\tcount_equal::count = 0;\n\tauto er = subrange(Iter1(ia), Sent1(ia));\n\tCHECK(find_end(er, subrange(Iter2(b), Sent2(b + 1)), count_equal()) == Iter1(ia));\n\tCHECK(count_equal::count == 0u);\n}\n\nstruct S {\n\tint i_;\n};\n\ntemplate<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>\nvoid test_proj() {\n\tusing namespace ranges;\n\n\tS ia[] = {{0}, {1}, {2}, {3}, {4}, {5}, {0}, {1}, {2}, {3}, {4}, {0}, {1}, {2}, {3}, {0}, {1}, {2}, {0}, {1}, {0}};\n\tconstexpr unsigned sa = size(ia);\n\tint b[] = {0};\n\tint c[] = {0, 1};\n\tint d[] = {0, 1, 2};\n\tint e[] = {0, 1, 2, 3};\n\tint f[] = {0, 1, 2, 3, 4};\n\tint g[] = {0, 1, 2, 3, 4, 5};\n\tint h[] = {0, 1, 2, 3, 4, 5, 6};\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b + 1), equal_to(), &S::i_) == Iter1(ia + sa - 1));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(c), Sent2(c + 2), equal_to(), &S::i_) == Iter1(ia + 18));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(d), Sent2(d + 3), equal_to(), &S::i_) == Iter1(ia + 15));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(e), Sent2(e + 4), equal_to(), &S::i_) == Iter1(ia + 11));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(f), Sent2(f + 5), equal_to(), &S::i_) == Iter1(ia + 6));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(g), Sent2(g + 6), equal_to(), &S::i_) == Iter1(ia));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(h), Sent2(h + 7), equal_to(), &S::i_) == Iter1(ia + sa));\n\tCHECK(find_end(Iter1(ia), Sent1(ia + sa), Iter2(b), Sent2(b), equal_to(), &S::i_) == Iter1(ia + sa));\n\tCHECK(find_end(Iter1(ia), Sent1(ia), Iter2(b), Sent2(b + 1), equal_to(), &S::i_) == Iter1(ia));\n\n\tauto ir = subrange(Iter1(ia), Sent1(ia + sa));\n\tCHECK(find_end(ir, subrange(Iter2(b), Sent2(b + 1)), equal_to(), &S::i_) == Iter1(ia + sa - 1));\n\tCHECK(find_end(ir, subrange(Iter2(c), Sent2(c + 2)), equal_to(), &S::i_) == Iter1(ia + 18));\n\tCHECK(find_end(ir, subrange(Iter2(d), Sent2(d + 3)), equal_to(), &S::i_) == Iter1(ia + 15));\n\tCHECK(find_end(ir, subrange(Iter2(e), Sent2(e + 4)), equal_to(), &S::i_) == Iter1(ia + 11));\n\tCHECK(find_end(ir, subrange(Iter2(f), Sent2(f + 5)), equal_to(), &S::i_) == Iter1(ia + 6));\n\tCHECK(find_end(ir, subrange(Iter2(g), Sent2(g + 6)), equal_to(), &S::i_) == Iter1(ia));\n\tCHECK(find_end(ir, subrange(Iter2(h), Sent2(h + 7)), equal_to(), &S::i_) == Iter1(ia + sa));\n\tCHECK(find_end(ir, subrange(Iter2(b), Sent2(b)), equal_to(), &S::i_) == Iter1(ia + sa));\n\tauto er = subrange(Iter1(ia), Sent1(ia));\n\tCHECK(find_end(er, subrange(Iter2(b), Sent2(b + 1)), equal_to(), &S::i_) == Iter1(ia));\n}\n\nint main() {\n\ttest<forward_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*> >();\n\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\n\ttest_pred<forward_iterator<const int*>, forward_iterator<const int*> >();\n\ttest_pred<forward_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest_pred<forward_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest_pred<bidirectional_iterator<const int*>, forward_iterator<const int*> >();\n\ttest_pred<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest_pred<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest_pred<random_access_iterator<const int*>, forward_iterator<const int*> >();\n\ttest_pred<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest_pred<random_access_iterator<const int*>, random_access_iterator<const int*> >();\n\n\ttest_pred<forward_iterator<const int*>, forward_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<forward_iterator<const int*>, bidirectional_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<forward_iterator<const int*>, random_access_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<bidirectional_iterator<const int*>, forward_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<bidirectional_iterator<const int*>, random_access_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<random_access_iterator<const int*>, forward_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<random_access_iterator<const int*>, bidirectional_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\ttest_pred<random_access_iterator<const int*>, random_access_iterator<const int*>, sentinel<const int*>, sentinel<const int *> >();\n\n\ttest_proj<forward_iterator<const S*>, forward_iterator<const int*> >();\n\ttest_proj<forward_iterator<const S*>, bidirectional_iterator<const int*> >();\n\ttest_proj<forward_iterator<const S*>, random_access_iterator<const int*> >();\n\ttest_proj<bidirectional_iterator<const S*>, forward_iterator<const int*> >();\n\ttest_proj<bidirectional_iterator<const S*>, bidirectional_iterator<const int*> >();\n\ttest_proj<bidirectional_iterator<const S*>, random_access_iterator<const int*> >();\n\ttest_proj<random_access_iterator<const S*>, forward_iterator<const int*> >();\n\ttest_proj<random_access_iterator<const S*>, bidirectional_iterator<const int*> >();\n\ttest_proj<random_access_iterator<const S*>, random_access_iterator<const int*> >();\n\n\ttest_proj<forward_iterator<const S*>, forward_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<forward_iterator<const S*>, bidirectional_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<forward_iterator<const S*>, random_access_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<bidirectional_iterator<const S*>, forward_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<bidirectional_iterator<const S*>, bidirectional_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<bidirectional_iterator<const S*>, random_access_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<random_access_iterator<const S*>, forward_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<random_access_iterator<const S*>, bidirectional_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\ttest_proj<random_access_iterator<const S*>, random_access_iterator<const int*>, sentinel<const S*>, sentinel<const int *> >();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/find_first_of.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/find_first_of.hpp>\n\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n#include \"../test_utils.hpp\"\n\nnamespace rng = std::experimental::ranges;\n\nvoid test_iter()\n{\n\tint ia[] = {0, 1, 2, 3, 0, 1, 2, 3};\n\tstatic constexpr unsigned sa = rng::size(ia);\n\tint ib[] = {1, 3, 5, 7};\n\tstatic constexpr unsigned sb = rng::size(ib);\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia + sa),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ib),\n\t\t\t\t\t\t\t sentinel<const int*>(ib + sb)) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+1));\n\tint ic[] = {7};\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia + sa),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t sentinel<const int*>(ic + 1)) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia + sa),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t sentinel<const int*>(ic)) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t sentinel<const int*>(ic+1)) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia));\n}\n\nvoid test_iter_pred()\n{\n\tint ia[] = {0, 1, 2, 3, 0, 1, 2, 3};\n\tstatic constexpr unsigned sa = rng::size(ia);\n\tint ib[] = {1, 3, 5, 7};\n\tstatic constexpr unsigned sb = rng::size(ib);\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia + sa),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ib),\n\t\t\t\t\t\t\t sentinel<const int*>(ib + sb),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+1));\n\tint ic[] = {7};\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia + sa),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t sentinel<const int*>(ic + 1),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia + sa),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t sentinel<const int*>(ic),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t sentinel<const int*>(ia),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t sentinel<const int*>(ic+1),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia));\n}\n\nvoid test_rng()\n{\n\tint ia[] = {0, 1, 2, 3, 0, 1, 2, 3};\n\tstatic constexpr unsigned sa = rng::size(ia);\n\tint ib[] = {1, 3, 5, 7};\n\tstatic constexpr unsigned sb = rng::size(ib);\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ib),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ib + sb))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+1));\n\tCHECK(rng::find_first_of(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa)),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ib),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ib + sb))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+1));\n\tint ic[] = {7};\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic + 1))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic+1))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia));\n\tCHECK(rng::find_first_of(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa)),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic + 1))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa)),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia)),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic+1))) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia));\n}\n\nvoid test_rng_pred()\n{\n\tint ia[] = {0, 1, 2, 3, 0, 1, 2, 3};\n\tstatic constexpr unsigned sa = rng::size(ia);\n\tint ib[] = {1, 3, 5, 7};\n\tstatic constexpr unsigned sb = rng::size(ib);\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ib),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ib + sb)),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+1));\n\tint ic[] = {7};\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic + 1)),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic)),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia+sa));\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t input_iterator<const int*>(ia))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const int*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const int*>(ic+1)),\n\t\t\t\t\t\t\t std::equal_to<int>()) ==\n\t\t\t\t\t\t\t input_iterator<const int*>(ia));\n}\n\nstruct S\n{\n\tint i;\n};\n\nvoid test_rng_pred_proj()\n{\n\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{0}, S{1}, S{2}, S{3}};\n\tstatic constexpr unsigned sa = rng::size(ia);\n\tS ib[] = {S{1}, S{3}, S{5}, S{7}};\n\tstatic constexpr unsigned sb = rng::size(ib);\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const S*>(ia),\n\t\t\t\t\t\t\t input_iterator<const S*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const S*>(ib),\n\t\t\t\t\t\t\t forward_iterator<const S*>(ib + sb)),\n\t\t\t\t\t\t\t std::equal_to<int>(), &S::i, &S::i) ==\n\t\t\t\t\t\t\t input_iterator<const S*>(ia+1));\n\tS ic[] = {S{7}};\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const S*>(ia),\n\t\t\t\t\t\t\t input_iterator<const S*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const S*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const S*>(ic + 1)),\n\t\t\t\t\t\t\t std::equal_to<int>(), &S::i, &S::i) ==\n\t\t\t\t\t\t\t input_iterator<const S*>(ia+sa));\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const S*>(ia),\n\t\t\t\t\t\t\t input_iterator<const S*>(ia + sa))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const S*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const S*>(ic)),\n\t\t\t\t\t\t\t std::equal_to<int>(), &S::i, &S::i) ==\n\t\t\t\t\t\t\t input_iterator<const S*>(ia+sa));\n\tCHECK(rng::find_first_of(as_lvalue(rng::subrange(input_iterator<const S*>(ia),\n\t\t\t\t\t\t\t input_iterator<const S*>(ia))),\n\t\t\t\t\t\t\t rng::subrange(forward_iterator<const S*>(ic),\n\t\t\t\t\t\t\t forward_iterator<const S*>(ic+1)),\n\t\t\t\t\t\t\t std::equal_to<int>(), &S::i, &S::i) ==\n\t\t\t\t\t\t\t input_iterator<const S*>(ia));\n}\n\nint main()\n{\n\t::test_iter();\n\t::test_iter_pred();\n\t::test_rng();\n\t::test_rng_pred();\n\t::test_rng_pred_proj();\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/find_if.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/utility.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nstruct S\n{\n\tint i_;\n};\n\nint main()\n{\n\tusing __stl2::find_if, __stl2::size, __stl2::end, __stl2::subrange;\n\n\tint ia[] = {0, 1, 2, 3, 4, 5};\n\tconstexpr unsigned s = size(ia);\n\tinput_iterator<const int*> r = find_if(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t\t\t\t   input_iterator<const int*>(ia + s),\n\t\t\t\t\t\t\t\t\t\t   [](int i){return i == 3;});\n\tCHECK(*r == 3);\n\tr = find_if(input_iterator<const int*>(ia),\n\t\t\t\tinput_iterator<const int*>(ia+s),\n\t\t\t\t[](int i){return i == 10;});\n\tCHECK(r == input_iterator<const int*>(ia+s));\n\n\tr = find_if(input_iterator<const int*>(ia),\n\t\t\t\tsentinel<const int*>(ia+s),\n\t\t\t\t[](int i){return i == 3;});\n\tCHECK(*r == 3);\n\tr = find_if(input_iterator<const int*>(ia),\n\t\t\t\tsentinel<const int*>(ia+s),\n\t\t\t\t[](int i){return i == 10;});\n\tCHECK(r == input_iterator<const int*>(ia+s));\n\n\tint *pi = find_if(ia, [](int i){return i == 3;});\n\tCHECK(*pi == 3);\n\tpi = find_if(ia, [](int i){return i == 10;});\n\tCHECK(pi == ia+s);\n\n\tauto pj = find_if(subrange(ia), [](int i){return i == 3;});\n\tCHECK(*pj == 3);\n\tpj = find_if(subrange(ia), [](int i){return i == 10;});\n\tCHECK(pj == ia+s);\n\n\tS sa[] = {{0}, {1}, {2}, {3}, {4}, {5}};\n\tS *ps = find_if(sa, [](int i){return i == 3;}, &S::i_);\n\tCHECK(ps->i_ == 3);\n\tps = find_if(sa, [](int i){return i == 10;}, &S::i_);\n\tCHECK(ps == end(sa));\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/find_if_not.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/find_if_not.hpp>\n#include <stl2/utility.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nstruct S\n{\n\tint i_;\n};\n\nint main()\n{\n\tusing __stl2::find_if_not, __stl2::size, __stl2::end, __stl2::subrange;\n\n\tint ia[] = {0, 1, 2, 3, 4, 5};\n\tconstexpr unsigned s = size(ia);\n\tinput_iterator<const int*> r = find_if_not(input_iterator<const int*>(ia),\n\t\t\t\t\t\t\t\t\t\t\t   input_iterator<const int*>(ia + s),\n\t\t\t\t\t\t\t\t\t\t\t   [](int i){return i != 3;});\n\tCHECK(*r == 3);\n\tr = find_if_not(input_iterator<const int*>(ia),\n\t\t\t\t\tinput_iterator<const int*>(ia+s),\n\t\t\t\t\t[](int i){return i != 10;});\n\tCHECK(r == input_iterator<const int*>(ia+s));\n\n\tr = find_if_not(input_iterator<const int*>(ia),\n\t\t\t\t\tsentinel<const int*>(ia+s),\n\t\t\t\t\t[](int i){return i != 3;});\n\tCHECK(*r == 3);\n\tr = find_if_not(input_iterator<const int*>(ia),\n\t\t\t\t\tsentinel<const int*>(ia+s),\n\t\t\t\t\t[](int i){return i != 10;});\n\tCHECK(r == input_iterator<const int*>(ia+s));\n\n\tint *pi = find_if_not(ia, [](int i){return i != 3;});\n\tCHECK(*pi == 3);\n\tpi = find_if_not(ia, [](int i){return i != 10;});\n\tCHECK(pi == ia+s);\n\n\tauto pj = find_if_not(subrange{ia}, [](int i){return i != 3;});\n\tCHECK(*pj == 3);\n\tpj = find_if_not(subrange{ia}, [](int i){return i != 10;});\n\tCHECK(pj == ia+s);\n\n\tS sa[] = {{0}, {1}, {2}, {3}, {4}, {5}};\n\tS *ps = find_if_not(sa, [](int i){return i != 3;}, &S::i_);\n\tCHECK(ps->i_ == 3);\n\tps = find_if_not(sa, [](int i){return i != 10;}, &S::i_);\n\tCHECK(ps == end(sa));\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/for_each.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/iterator.hpp>\n#include <stl2/detail/algorithm/for_each.hpp>\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct S {\n\tvoid p() const { *p_ += i_; }\n\tint *p_;\n\tint i_;\n};\n\nint main() {\n\tint sum = 0;\n\tauto fun = [&](int i){ sum += i; };\n\tstd::vector<int> v1 { 0, 2, 4, 6 };\n\tCHECK(ranges::for_each(v1.begin(), v1.end(), fun).in == v1.end());\n\tCHECK(ranges::for_each(v1, fun).in == v1.end());\n\tCHECK(sum == 24);\n\n\tsum = 0;\n\tauto rfun = [&](int& i){ sum += i; };\n\tCHECK(ranges::for_each(v1.begin(), v1.end(), rfun).in == v1.end());\n\tCHECK(ranges::for_each(v1, rfun).in == v1.end());\n\tCHECK(sum == 24);\n\n\tsum = 0;\n\tstd::vector<S> v2{{&sum, 0}, {&sum, 2}, {&sum, 4}, {&sum, 6}};\n\tCHECK(ranges::for_each(v2.begin(), v2.end(), &S::p).in == v2.end());\n\tCHECK(ranges::for_each(v2, &S::p).in == v2.end());\n\tCHECK(sum == 24);\n\n\tsum = 0;\n\tCHECK(ranges::for_each(ranges::subrange(v1.begin(), v1.end()), fun).in == v1.end());\n\tCHECK(sum == 12);\n\n\t{\n\t\tsum = 0;\n\t\tauto il = {0, 2, 4, 6};\n\t\tranges::for_each(il, fun);\n\t\tranges::for_each(std::move(il), fun);\n\t\tCHECK(sum == 24);\n\t}\n\t{\n\t\tauto il = {0, 2, 4, 6};\n\t\tauto result = ranges::for_each(std::move(il), [sum = 0](int i) mutable -> int {\n\t\t\treturn sum += i;\n\t\t});\n\t\tCHECK(result.fun(0) == 12);\n\t}\n\n\t// Should compile\n\tint matrix[3][4] = {};\n\tranges::for_each(matrix, [](int(&)[4]){});\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/generate.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/generate.hpp>\n#include <stl2/iterator.hpp>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct gen_test {\n\tint i_;\n\tgen_test() = default;\n\tgen_test(int i) : i_(i) {}\n\tint operator()() {return i_++;}\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid test() {\n\tconst unsigned n = 4;\n\tint ia[n] = {0};\n\tauto f = gen_test{1};\n\tauto res1 = ranges::generate(Iter(ia), Sent(ia + n), ranges::ref(f));\n\tCHECK(ia[0] == 1);\n\tCHECK(ia[1] == 2);\n\tCHECK(ia[2] == 3);\n\tCHECK(ia[3] == 4);\n\tCHECK(res1 == Iter(ia + n));\n\tCHECK(f.i_ == 5);\n\n\tauto rng = ranges::subrange(Iter(ia), Sent(ia + n));\n\tauto res2 = ranges::generate(rng, ranges::ref(f));\n\tCHECK(ia[0] == 5);\n\tCHECK(ia[1] == 6);\n\tCHECK(ia[2] == 7);\n\tCHECK(ia[3] == 8);\n\tCHECK(res2 == Iter(ia + n));\n\tCHECK(f.i_ == 9);\n\n\tauto res3 = ranges::generate(std::move(rng), ranges::ref(f));\n\tCHECK(ia[0] == 9);\n\tCHECK(ia[1] == 10);\n\tCHECK(ia[2] == 11);\n\tCHECK(ia[3] == 12);\n\tCHECK(res3 == Iter(ia + n));\n\tCHECK(f.i_ == 13);\n}\n\nvoid test2() {\n\t// Test ranges::generate with a genuine output range\n\tstd::vector<int> v;\n\tauto rng = ranges::subrange(\n\t\tranges::counted_iterator{ranges::back_inserter(v), 5},\n\t\tranges::default_sentinel);\n\tranges::generate(rng, gen_test(1));\n\tCHECK(v.size() == 5u);\n\tCHECK(v[0] == 1);\n\tCHECK(v[1] == 2);\n\tCHECK(v[2] == 3);\n\tCHECK(v[3] == 4);\n\tCHECK(v[4] == 5);\n}\n\nint main() {\n\ttest<forward_iterator<int*> >();\n\ttest<bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<int*> >();\n\ttest<int*>();\n\n\ttest<forward_iterator<int*>, sentinel<int*> >();\n\ttest<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest2();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/generate_n.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/generate_n.hpp>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nstruct gen_test\n{\n\tint i_;\n\tgen_test() = default;\n\tgen_test(int i) : i_(i) {}\n\tint operator()() {return i_++;}\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest()\n{\n\tconst unsigned n = 4;\n\tint ia[n] = {0};\n\tIter res = stl2::generate_n(Iter(ia), n, gen_test(1));\n\tCHECK(ia[0] == 1);\n\tCHECK(ia[1] == 2);\n\tCHECK(ia[2] == 3);\n\tCHECK(ia[3] == 4);\n\tCHECK(res == Iter(ia + n));\n}\n\nvoid test2()\n{\n\t// Test stl2::generate with a genuine output range\n\tstd::vector<int> v;\n\tstl2::generate_n(stl2::back_inserter(v), 5, gen_test(1));\n\tCHECK(v.size() == 5u);\n\tCHECK(v[0] == 1);\n\tCHECK(v[1] == 2);\n\tCHECK(v[2] == 3);\n\tCHECK(v[3] == 4);\n\tCHECK(v[4] == 5);\n}\n\nint main()\n{\n\ttest<forward_iterator<int*> >();\n\ttest<bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<int*> >();\n\ttest<int*>();\n\n\ttest<forward_iterator<int*>, sentinel<int*> >();\n\ttest<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest2();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/includes.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/includes.hpp>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nauto const true_  = [](bool b){CHECK(b);};\nauto const false_ = [](bool b){CHECK(!b);};\n\nauto includes_fn = [](auto&&... args) {\n  return stl2::includes(std::forward<decltype(args)>(args)...);\n};\n\ntemplate<class Iter1, class Iter2>\nvoid\ntest_iter()\n{\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[] = {1, 2};\n\tint id[] = {3, 3, 3, 3};\n\n\tauto includes = make_testable_2<true, true>(includes_fn);\n\n\tincludes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib)).check(true_);\n\tincludes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib+1)).check(false_);\n\tincludes(Iter1(ia), Iter1(ia+1), Iter2(ib), Iter2(ib)).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa)).check(true_);\n\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb)).check(true_);\n\tincludes(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa)).check(false_);\n\n\tincludes(Iter1(ia), Iter1(ia+2), Iter2(ic), Iter2(ic+2)).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+2), Iter2(ib), Iter2(ib+2)).check(false_);\n\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+1)).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+2)).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+3)).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+4)).check(false_);\n}\n\ntemplate<class Iter1, class Iter2>\nvoid\ntest_comp()\n{\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[] = {1, 2};\n\tint id[] = {3, 3, 3, 3};\n\n\tauto includes = make_testable_2<true, true>(includes_fn);\n\n\tincludes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib), std::less<int>()).check(true_);\n\tincludes(Iter1(ia), Iter1(ia), Iter2(ib), Iter2(ib+1), std::less<int>()).check(false_);\n\tincludes(Iter1(ia), Iter1(ia+1), Iter2(ib), Iter2(ib), std::less<int>()).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(ia), Iter2(ia+sa), std::less<int>()).check(true_);\n\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), std::less<int>()).check(true_);\n\tincludes(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), std::less<int>()).check(false_);\n\n\tincludes(Iter1(ia), Iter1(ia+2), Iter2(ic), Iter2(ic+2), std::less<int>()).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+2), Iter2(ib), Iter2(ib+2), std::less<int>()).check(false_);\n\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+1), std::less<int>()).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+2), std::less<int>()).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+3), std::less<int>()).check(true_);\n\tincludes(Iter1(ia), Iter1(ia+sa), Iter2(id), Iter2(id+4), std::less<int>()).check(false_);\n}\n\ntemplate<class Iter1, class Iter2>\nvoid test()\n{\n\ttest_iter<Iter1, Iter2>();\n\ttest_comp<Iter1, Iter2>();\n}\n\nstruct S\n{\n\tint i;\n};\n\nstruct T\n{\n\tint j;\n};\n\nint main()\n{\n\ttest<input_iterator<const int*>, input_iterator<const int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<input_iterator<const int*>, const int*>();\n\n\ttest<forward_iterator<const int*>, input_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, const int*>();\n\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*>();\n\n\ttest<random_access_iterator<const int*>, input_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, const int*>();\n\n\ttest<const int*, input_iterator<const int*> >();\n\ttest<const int*, forward_iterator<const int*> >();\n\ttest<const int*, bidirectional_iterator<const int*> >();\n\ttest<const int*, random_access_iterator<const int*> >();\n\ttest<const int*, const int*>();\n\n\t// Test projections\n\t{\n\t\tS ia[] = {{1}, {2}, {2}, {3}, {3}, {3}, {4}, {4}, {4}, {4}};\n\t\tT id[] = {{3}, {3}, {3}};\n\t\tCHECK(stl2::includes(ia, id, std::less<int>(), &S::i, &T::j));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/inplace_merge.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/inplace_merge.hpp>\n#include <cassert>\n#include <algorithm>\n#include <random>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter, typename Sent = Iter>\nvoid\ntest_one_iter(unsigned N, unsigned M)\n{\n\tassert(M <= N);\n\tint* ia = new int[N];\n\tfor (unsigned i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::sort(ia, ia+M);\n\tstd::sort(ia+M, ia+N);\n\tauto res = stl2::inplace_merge(Iter(ia), Iter(ia+M), Sent(ia+N));\n\tCHECK(res == Iter(ia+N));\n\tif(N > 0)\n\t{\n\t\tCHECK(ia[0] == 0);\n\t\tCHECK(ia[N-1] == (int)N-1);\n\t\tCHECK(std::is_sorted(ia, ia+N));\n\t}\n\tdelete [] ia;\n}\n\ntemplate<class Iter, typename Sent = Iter>\nvoid\ntest_one_rng(unsigned N, unsigned M)\n{\n\tassert(M <= N);\n\tint* ia = new int[N];\n\tfor (unsigned i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::sort(ia, ia+M);\n\tstd::sort(ia+M, ia+N);\n\tauto res = stl2::inplace_merge(::as_lvalue(stl2::subrange(Iter(ia), Sent(ia+N))), Iter(ia+M));\n\tCHECK(res == Iter(ia+N));\n\tif(N > 0)\n\t{\n\t\tCHECK(ia[0] == 0);\n\t\tCHECK(ia[N-1] == (int)N-1);\n\t\tCHECK(std::is_sorted(ia, ia+N));\n\t}\n\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::sort(ia, ia+M);\n\tstd::sort(ia+M, ia+N);\n\tauto res2 = stl2::inplace_merge(stl2::subrange(Iter(ia), Sent(ia+N)), Iter(ia+M));\n\tCHECK(res2 == Iter(ia+N));\n\tif(N > 0)\n\t{\n\t\tCHECK(ia[0] == 0);\n\t\tCHECK(ia[N-1] == (int)N-1);\n\t\tCHECK(std::is_sorted(ia, ia+N));\n\t}\n\n\tdelete [] ia;\n}\n\ntemplate<class Iter>\nvoid\ntest_one(unsigned N, unsigned M)\n{\n\ttest_one_iter<Iter>(N, M);\n\ttest_one_iter<Iter, typename sentinel_type<Iter>::type>(N, M);\n\ttest_one_rng<Iter>(N, M);\n\ttest_one_rng<Iter, typename sentinel_type<Iter>::type>(N, M);\n}\n\ntemplate<class Iter>\nvoid\ntest(unsigned N)\n{\n\ttest_one<Iter>(N, 0);\n\ttest_one<Iter>(N, N/4);\n\ttest_one<Iter>(N, N/2);\n\ttest_one<Iter>(N, 3*N/4);\n\ttest_one<Iter>(N, N);\n}\n\ntemplate<class Iter>\nvoid\ntest()\n{\n\ttest_one<Iter>(0, 0);\n\ttest_one<Iter>(1, 0);\n\ttest_one<Iter>(1, 1);\n\ttest_one<Iter>(2, 0);\n\ttest_one<Iter>(2, 1);\n\ttest_one<Iter>(2, 2);\n\ttest_one<Iter>(3, 0);\n\ttest_one<Iter>(3, 1);\n\ttest_one<Iter>(3, 2);\n\ttest_one<Iter>(3, 3);\n\ttest<Iter>(4);\n\ttest<Iter>(100);\n\ttest<Iter>(1000);\n}\n\nint main()\n{\n\t// test<forward_iterator<int*> >();\n\ttest<bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<int*> >();\n\ttest<int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/is_heap.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n// Implementation based on the code in libc++\n//   http://http://libcxx.llvm.org/\n\n#include <stl2/detail/algorithm/is_heap.hpp>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nvoid test()\n{\n#if defined(IS_HEAP_1) || defined(IS_HEAP_2)\n\tauto is_heap = make_testable_1([](auto&&... args) {\n\t\treturn stl2::is_heap(std::forward<decltype(args)>(args)...);\n\t});\n#endif\n\n#ifdef IS_HEAP_1\n\tint i1[] = {0, 0};\n\tis_heap(i1, i1).check([&](bool r){ CHECK(r); });\n\tis_heap(i1, i1+1).check([&](bool r){ CHECK(r == (std::is_heap_until(i1, i1+1) == i1+1)); });\n\tint i2[] = {0, 1};\n\tint i3[] = {1, 0};\n\tis_heap(i1, i1+2).check([&](bool r){ CHECK(r == (std::is_heap_until(i1, i1+2) == i1+2)); });\n\tis_heap(i2, i2+2).check([&](bool r){ CHECK(r == (std::is_heap_until(i2, i2+2) == i2+2)); });\n\tis_heap(i3, i3+2).check([&](bool r){ CHECK(r == (std::is_heap_until(i3, i3+2) == i3+2)); });\n\tint i4[] = {0, 0, 0};\n\tint i5[] = {0, 0, 1};\n\tint i6[] = {0, 1, 0};\n\tint i7[] = {0, 1, 1};\n\tint i8[] = {1, 0, 0};\n\tint i9[] = {1, 0, 1};\n\tint i10[] = {1, 1, 0};\n\tis_heap(i4, i4+3).check([&](bool r){ CHECK(r == (std::is_heap_until(i4, i4+3) == i4+3)); });\n\tis_heap(i5, i5+3).check([&](bool r){ CHECK(r == (std::is_heap_until(i5, i5+3) == i5+3)); });\n\tis_heap(i6, i6+3).check([&](bool r){ CHECK(r == (std::is_heap_until(i6, i6+3) == i6+3)); });\n\tis_heap(i7, i7+3).check([&](bool r){ CHECK(r == (std::is_heap_until(i7, i7+3) == i7+3)); });\n\tis_heap(i8, i8+3).check([&](bool r){ CHECK(r == (std::is_heap_until(i8, i8+3) == i8+3)); });\n\tis_heap(i9, i9+3).check([&](bool r){ CHECK(r == (std::is_heap_until(i9, i9+3) == i9+3)); });\n\tis_heap(i10, i10+3).check([&](bool r){ CHECK(r == (std::is_heap_until(i10, i10+3) == i10+3)); });\n\tint i11[] = {0, 0, 0, 0};\n\tint i12[] = {0, 0, 0, 1};\n\tint i13[] = {0, 0, 1, 0};\n\tint i14[] = {0, 0, 1, 1};\n\tint i15[] = {0, 1, 0, 0};\n\tint i16[] = {0, 1, 0, 1};\n\tint i17[] = {0, 1, 1, 0};\n\tint i18[] = {0, 1, 1, 1};\n\tint i19[] = {1, 0, 0, 0};\n\tint i20[] = {1, 0, 0, 1};\n\tint i21[] = {1, 0, 1, 0};\n\tint i22[] = {1, 0, 1, 1};\n\tint i23[] = {1, 1, 0, 0};\n\tint i24[] = {1, 1, 0, 1};\n\tint i25[] = {1, 1, 1, 0};\n\tis_heap(i11, i11+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i11, i11+4) == i11+4)); });\n\tis_heap(i12, i12+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i12, i12+4) == i12+4)); });\n\tis_heap(i13, i13+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i13, i13+4) == i13+4)); });\n\tis_heap(i14, i14+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i14, i14+4) == i14+4)); });\n\tis_heap(i15, i15+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i15, i15+4) == i15+4)); });\n\tis_heap(i16, i16+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i16, i16+4) == i16+4)); });\n\tis_heap(i17, i17+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i17, i17+4) == i17+4)); });\n\tis_heap(i18, i18+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i18, i18+4) == i18+4)); });\n\tis_heap(i19, i19+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i19, i19+4) == i19+4)); });\n\tis_heap(i20, i20+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i20, i20+4) == i20+4)); });\n\tis_heap(i21, i21+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i21, i21+4) == i21+4)); });\n\tis_heap(i22, i22+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i22, i22+4) == i22+4)); });\n\tis_heap(i23, i23+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i23, i23+4) == i23+4)); });\n\tis_heap(i24, i24+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i24, i24+4) == i24+4)); });\n\tis_heap(i25, i25+4).check([&](bool r){ CHECK(r == (std::is_heap_until(i25, i25+4) == i25+4)); });\n\tint i26[] = {0, 0, 0, 0, 0};\n\tint i27[] = {0, 0, 0, 0, 1};\n\tint i28[] = {0, 0, 0, 1, 0};\n\tint i29[] = {0, 0, 0, 1, 1};\n\tint i30[] = {0, 0, 1, 0, 0};\n\tint i31[] = {0, 0, 1, 0, 1};\n\tint i32[] = {0, 0, 1, 1, 0};\n\tint i33[] = {0, 0, 1, 1, 1};\n\tint i34[] = {0, 1, 0, 0, 0};\n\tint i35[] = {0, 1, 0, 0, 1};\n\tint i36[] = {0, 1, 0, 1, 0};\n\tint i37[] = {0, 1, 0, 1, 1};\n\tint i38[] = {0, 1, 1, 0, 0};\n\tint i39[] = {0, 1, 1, 0, 1};\n\tint i40[] = {0, 1, 1, 1, 0};\n\tint i41[] = {0, 1, 1, 1, 1};\n\tint i42[] = {1, 0, 0, 0, 0};\n\tint i43[] = {1, 0, 0, 0, 1};\n\tint i44[] = {1, 0, 0, 1, 0};\n\tint i45[] = {1, 0, 0, 1, 1};\n\tint i46[] = {1, 0, 1, 0, 0};\n\tint i47[] = {1, 0, 1, 0, 1};\n\tint i48[] = {1, 0, 1, 1, 0};\n\tint i49[] = {1, 0, 1, 1, 1};\n\tint i50[] = {1, 1, 0, 0, 0};\n\tint i51[] = {1, 1, 0, 0, 1};\n\tint i52[] = {1, 1, 0, 1, 0};\n\tint i53[] = {1, 1, 0, 1, 1};\n\tint i54[] = {1, 1, 1, 0, 0};\n\tint i55[] = {1, 1, 1, 0, 1};\n\tint i56[] = {1, 1, 1, 1, 0};\n\tis_heap(i26, i26+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i26, i26+5) == i26+5)); });\n\tis_heap(i27, i27+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i27, i27+5) == i27+5)); });\n\tis_heap(i28, i28+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i28, i28+5) == i28+5)); });\n\tis_heap(i29, i29+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i29, i29+5) == i29+5)); });\n\tis_heap(i30, i30+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i30, i30+5) == i30+5)); });\n\tis_heap(i31, i31+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i31, i31+5) == i31+5)); });\n\tis_heap(i32, i32+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i32, i32+5) == i32+5)); });\n\tis_heap(i33, i33+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i33, i33+5) == i33+5)); });\n\tis_heap(i34, i34+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i34, i34+5) == i34+5)); });\n\tis_heap(i35, i35+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i35, i35+5) == i35+5)); });\n\tis_heap(i36, i36+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i36, i36+5) == i36+5)); });\n\tis_heap(i37, i37+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i37, i37+5) == i37+5)); });\n\tis_heap(i38, i38+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i38, i38+5) == i38+5)); });\n\tis_heap(i39, i39+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i39, i39+5) == i39+5)); });\n\tis_heap(i40, i40+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i40, i40+5) == i40+5)); });\n\tis_heap(i41, i41+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i41, i41+5) == i41+5)); });\n\tis_heap(i42, i42+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i42, i42+5) == i42+5)); });\n\tis_heap(i43, i43+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i43, i43+5) == i43+5)); });\n\tis_heap(i44, i44+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i44, i44+5) == i44+5)); });\n\tis_heap(i45, i45+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i45, i45+5) == i45+5)); });\n\tis_heap(i46, i46+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i46, i46+5) == i46+5)); });\n\tis_heap(i47, i47+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i47, i47+5) == i47+5)); });\n\tis_heap(i48, i48+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i48, i48+5) == i48+5)); });\n\tis_heap(i49, i49+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i49, i49+5) == i49+5)); });\n\tis_heap(i50, i50+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i50, i50+5) == i50+5)); });\n\tis_heap(i51, i51+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i51, i51+5) == i51+5)); });\n\tis_heap(i52, i52+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i52, i52+5) == i52+5)); });\n\tis_heap(i53, i53+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i53, i53+5) == i53+5)); });\n\tis_heap(i54, i54+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i54, i54+5) == i54+5)); });\n\tis_heap(i55, i55+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i55, i55+5) == i55+5)); });\n\tis_heap(i56, i56+5).check([&](bool r){ CHECK(r == (std::is_heap_until(i56, i56+5) == i56+5)); });\n\tint i57[] = {0, 0, 0, 0, 0, 0};\n\tint i58[] = {0, 0, 0, 0, 0, 1};\n\tint i59[] = {0, 0, 0, 0, 1, 0};\n\tint i60[] = {0, 0, 0, 0, 1, 1};\n\tint i61[] = {0, 0, 0, 1, 0, 0};\n\tint i62[] = {0, 0, 0, 1, 0, 1};\n\tint i63[] = {0, 0, 0, 1, 1, 0};\n\tint i64[] = {0, 0, 0, 1, 1, 1};\n\tint i65[] = {0, 0, 1, 0, 0, 0};\n\tint i66[] = {0, 0, 1, 0, 0, 1};\n\tint i67[] = {0, 0, 1, 0, 1, 0};\n\tint i68[] = {0, 0, 1, 0, 1, 1};\n\tint i69[] = {0, 0, 1, 1, 0, 0};\n\tint i70[] = {0, 0, 1, 1, 0, 1};\n\tint i71[] = {0, 0, 1, 1, 1, 0};\n\tint i72[] = {0, 0, 1, 1, 1, 1};\n\tint i73[] = {0, 1, 0, 0, 0, 0};\n\tint i74[] = {0, 1, 0, 0, 0, 1};\n\tint i75[] = {0, 1, 0, 0, 1, 0};\n\tint i76[] = {0, 1, 0, 0, 1, 1};\n\tint i77[] = {0, 1, 0, 1, 0, 0};\n\tint i78[] = {0, 1, 0, 1, 0, 1};\n\tint i79[] = {0, 1, 0, 1, 1, 0};\n\tint i80[] = {0, 1, 0, 1, 1, 1};\n\tint i81[] = {0, 1, 1, 0, 0, 0};\n\tint i82[] = {0, 1, 1, 0, 0, 1};\n\tint i83[] = {0, 1, 1, 0, 1, 0};\n\tint i84[] = {0, 1, 1, 0, 1, 1};\n\tint i85[] = {0, 1, 1, 1, 0, 0};\n\tint i86[] = {0, 1, 1, 1, 0, 1};\n\tint i87[] = {0, 1, 1, 1, 1, 0};\n\tint i88[] = {0, 1, 1, 1, 1, 1};\n\tint i89[] = {1, 0, 0, 0, 0, 0};\n\tint i90[] = {1, 0, 0, 0, 0, 1};\n\tint i91[] = {1, 0, 0, 0, 1, 0};\n\tint i92[] = {1, 0, 0, 0, 1, 1};\n\tint i93[] = {1, 0, 0, 1, 0, 0};\n\tint i94[] = {1, 0, 0, 1, 0, 1};\n\tint i95[] = {1, 0, 0, 1, 1, 0};\n\tint i96[] = {1, 0, 0, 1, 1, 1};\n\tint i97[] = {1, 0, 1, 0, 0, 0};\n\tint i98[] = {1, 0, 1, 0, 0, 1};\n\tint i99[] = {1, 0, 1, 0, 1, 0};\n\tint i100[] = {1, 0, 1, 0, 1, 1};\n\tint i101[] = {1, 0, 1, 1, 0, 0};\n\tint i102[] = {1, 0, 1, 1, 0, 1};\n\tint i103[] = {1, 0, 1, 1, 1, 0};\n\tint i104[] = {1, 0, 1, 1, 1, 1};\n\tint i105[] = {1, 1, 0, 0, 0, 0};\n\tint i106[] = {1, 1, 0, 0, 0, 1};\n\tint i107[] = {1, 1, 0, 0, 1, 0};\n\tint i108[] = {1, 1, 0, 0, 1, 1};\n\tint i109[] = {1, 1, 0, 1, 0, 0};\n\tint i110[] = {1, 1, 0, 1, 0, 1};\n\tint i111[] = {1, 1, 0, 1, 1, 0};\n\tint i112[] = {1, 1, 0, 1, 1, 1};\n\tint i113[] = {1, 1, 1, 0, 0, 0};\n\tint i114[] = {1, 1, 1, 0, 0, 1};\n\tint i115[] = {1, 1, 1, 0, 1, 0};\n\tint i116[] = {1, 1, 1, 0, 1, 1};\n\tint i117[] = {1, 1, 1, 1, 0, 0};\n\tint i118[] = {1, 1, 1, 1, 0, 1};\n\tint i119[] = {1, 1, 1, 1, 1, 0};\n\tis_heap(i57, i57+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i57, i57+6) == i57+6)); });\n\tis_heap(i58, i58+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i58, i58+6) == i58+6)); });\n\tis_heap(i59, i59+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i59, i59+6) == i59+6)); });\n\tis_heap(i60, i60+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i60, i60+6) == i60+6)); });\n\tis_heap(i61, i61+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i61, i61+6) == i61+6)); });\n\tis_heap(i62, i62+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i62, i62+6) == i62+6)); });\n\tis_heap(i63, i63+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i63, i63+6) == i63+6)); });\n\tis_heap(i64, i64+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i64, i64+6) == i64+6)); });\n\tis_heap(i65, i65+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i65, i65+6) == i65+6)); });\n\tis_heap(i66, i66+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i66, i66+6) == i66+6)); });\n\tis_heap(i67, i67+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i67, i67+6) == i67+6)); });\n\tis_heap(i68, i68+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i68, i68+6) == i68+6)); });\n\tis_heap(i69, i69+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i69, i69+6) == i69+6)); });\n\tis_heap(i70, i70+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i70, i70+6) == i70+6)); });\n\tis_heap(i71, i71+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i71, i71+6) == i71+6)); });\n\tis_heap(i72, i72+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i72, i72+6) == i72+6)); });\n\tis_heap(i73, i73+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i73, i73+6) == i73+6)); });\n\tis_heap(i74, i74+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i74, i74+6) == i74+6)); });\n\tis_heap(i75, i75+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i75, i75+6) == i75+6)); });\n\tis_heap(i76, i76+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i76, i76+6) == i76+6)); });\n\tis_heap(i77, i77+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i77, i77+6) == i77+6)); });\n\tis_heap(i78, i78+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i78, i78+6) == i78+6)); });\n\tis_heap(i79, i79+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i79, i79+6) == i79+6)); });\n\tis_heap(i80, i80+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i80, i80+6) == i80+6)); });\n\tis_heap(i81, i81+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i81, i81+6) == i81+6)); });\n\tis_heap(i82, i82+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i82, i82+6) == i82+6)); });\n\tis_heap(i83, i83+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i83, i83+6) == i83+6)); });\n\tis_heap(i84, i84+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i84, i84+6) == i84+6)); });\n\tis_heap(i85, i85+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i85, i85+6) == i85+6)); });\n\tis_heap(i86, i86+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i86, i86+6) == i86+6)); });\n\tis_heap(i87, i87+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i87, i87+6) == i87+6)); });\n\tis_heap(i88, i88+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i88, i88+6) == i88+6)); });\n\tis_heap(i89, i89+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i89, i89+6) == i89+6)); });\n\tis_heap(i90, i90+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i90, i90+6) == i90+6)); });\n\tis_heap(i91, i91+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i91, i91+6) == i91+6)); });\n\tis_heap(i92, i92+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i92, i92+6) == i92+6)); });\n\tis_heap(i93, i93+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i93, i93+6) == i93+6)); });\n\tis_heap(i94, i94+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i94, i94+6) == i94+6)); });\n\tis_heap(i95, i95+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i95, i95+6) == i95+6)); });\n\tis_heap(i96, i96+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i96, i96+6) == i96+6)); });\n\tis_heap(i97, i97+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i97, i97+6) == i97+6)); });\n\tis_heap(i98, i98+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i98, i98+6) == i98+6)); });\n\tis_heap(i99, i99+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i99, i99+6) == i99+6)); });\n\tis_heap(i100, i100+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i100, i100+6) == i100+6)); });\n\tis_heap(i101, i101+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i101, i101+6) == i101+6)); });\n\tis_heap(i102, i102+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i102, i102+6) == i102+6)); });\n\tis_heap(i103, i103+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i103, i103+6) == i103+6)); });\n\tis_heap(i104, i104+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i104, i104+6) == i104+6)); });\n\tis_heap(i105, i105+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i105, i105+6) == i105+6)); });\n\tis_heap(i106, i106+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i106, i106+6) == i106+6)); });\n\tis_heap(i107, i107+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i107, i107+6) == i107+6)); });\n\tis_heap(i108, i108+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i108, i108+6) == i108+6)); });\n\tis_heap(i109, i109+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i109, i109+6) == i109+6)); });\n\tis_heap(i110, i110+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i110, i110+6) == i110+6)); });\n\tis_heap(i111, i111+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i111, i111+6) == i111+6)); });\n\tis_heap(i112, i112+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i112, i112+6) == i112+6)); });\n\tis_heap(i113, i113+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i113, i113+6) == i113+6)); });\n\tis_heap(i114, i114+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i114, i114+6) == i114+6)); });\n\tis_heap(i115, i115+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i115, i115+6) == i115+6)); });\n\tis_heap(i116, i116+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i116, i116+6) == i116+6)); });\n\tis_heap(i117, i117+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i117, i117+6) == i117+6)); });\n\tis_heap(i118, i118+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i118, i118+6) == i118+6)); });\n\tis_heap(i119, i119+6).check([&](bool r){ CHECK(r == (std::is_heap_until(i119, i119+6) == i119+6)); });\n#endif\n#ifdef IS_HEAP_2\n\tint i120[] = {0, 0, 0, 0, 0, 0, 0};\n\tint i121[] = {0, 0, 0, 0, 0, 0, 1};\n\tint i122[] = {0, 0, 0, 0, 0, 1, 0};\n\tint i123[] = {0, 0, 0, 0, 0, 1, 1};\n\tint i124[] = {0, 0, 0, 0, 1, 0, 0};\n\tint i125[] = {0, 0, 0, 0, 1, 0, 1};\n\tint i126[] = {0, 0, 0, 0, 1, 1, 0};\n\tint i127[] = {0, 0, 0, 0, 1, 1, 1};\n\tint i128[] = {0, 0, 0, 1, 0, 0, 0};\n\tint i129[] = {0, 0, 0, 1, 0, 0, 1};\n\tint i130[] = {0, 0, 0, 1, 0, 1, 0};\n\tint i131[] = {0, 0, 0, 1, 0, 1, 1};\n\tint i132[] = {0, 0, 0, 1, 1, 0, 0};\n\tint i133[] = {0, 0, 0, 1, 1, 0, 1};\n\tint i134[] = {0, 0, 0, 1, 1, 1, 0};\n\tint i135[] = {0, 0, 0, 1, 1, 1, 1};\n\tint i136[] = {0, 0, 1, 0, 0, 0, 0};\n\tint i137[] = {0, 0, 1, 0, 0, 0, 1};\n\tint i138[] = {0, 0, 1, 0, 0, 1, 0};\n\tint i139[] = {0, 0, 1, 0, 0, 1, 1};\n\tint i140[] = {0, 0, 1, 0, 1, 0, 0};\n\tint i141[] = {0, 0, 1, 0, 1, 0, 1};\n\tint i142[] = {0, 0, 1, 0, 1, 1, 0};\n\tint i143[] = {0, 0, 1, 0, 1, 1, 1};\n\tint i144[] = {0, 0, 1, 1, 0, 0, 0};\n\tint i145[] = {0, 0, 1, 1, 0, 0, 1};\n\tint i146[] = {0, 0, 1, 1, 0, 1, 0};\n\tint i147[] = {0, 0, 1, 1, 0, 1, 1};\n\tint i148[] = {0, 0, 1, 1, 1, 0, 0};\n\tint i149[] = {0, 0, 1, 1, 1, 0, 1};\n\tint i150[] = {0, 0, 1, 1, 1, 1, 0};\n\tint i151[] = {0, 0, 1, 1, 1, 1, 1};\n\tint i152[] = {0, 1, 0, 0, 0, 0, 0};\n\tint i153[] = {0, 1, 0, 0, 0, 0, 1};\n\tint i154[] = {0, 1, 0, 0, 0, 1, 0};\n\tint i155[] = {0, 1, 0, 0, 0, 1, 1};\n\tint i156[] = {0, 1, 0, 0, 1, 0, 0};\n\tint i157[] = {0, 1, 0, 0, 1, 0, 1};\n\tint i158[] = {0, 1, 0, 0, 1, 1, 0};\n\tint i159[] = {0, 1, 0, 0, 1, 1, 1};\n\tint i160[] = {0, 1, 0, 1, 0, 0, 0};\n\tint i161[] = {0, 1, 0, 1, 0, 0, 1};\n\tint i162[] = {0, 1, 0, 1, 0, 1, 0};\n\tint i163[] = {0, 1, 0, 1, 0, 1, 1};\n\tint i164[] = {0, 1, 0, 1, 1, 0, 0};\n\tint i165[] = {0, 1, 0, 1, 1, 0, 1};\n\tint i166[] = {0, 1, 0, 1, 1, 1, 0};\n\tint i167[] = {0, 1, 0, 1, 1, 1, 1};\n\tint i168[] = {0, 1, 1, 0, 0, 0, 0};\n\tint i169[] = {0, 1, 1, 0, 0, 0, 1};\n\tint i170[] = {0, 1, 1, 0, 0, 1, 0};\n\tint i171[] = {0, 1, 1, 0, 0, 1, 1};\n\tint i172[] = {0, 1, 1, 0, 1, 0, 0};\n\tint i173[] = {0, 1, 1, 0, 1, 0, 1};\n\tint i174[] = {0, 1, 1, 0, 1, 1, 0};\n\tint i175[] = {0, 1, 1, 0, 1, 1, 1};\n\tint i176[] = {0, 1, 1, 1, 0, 0, 0};\n\tint i177[] = {0, 1, 1, 1, 0, 0, 1};\n\tint i178[] = {0, 1, 1, 1, 0, 1, 0};\n\tint i179[] = {0, 1, 1, 1, 0, 1, 1};\n\tint i180[] = {0, 1, 1, 1, 1, 0, 0};\n\tint i181[] = {0, 1, 1, 1, 1, 0, 1};\n\tint i182[] = {0, 1, 1, 1, 1, 1, 0};\n\tint i183[] = {0, 1, 1, 1, 1, 1, 1};\n\tint i184[] = {1, 0, 0, 0, 0, 0, 0};\n\tint i185[] = {1, 0, 0, 0, 0, 0, 1};\n\tint i186[] = {1, 0, 0, 0, 0, 1, 0};\n\tint i187[] = {1, 0, 0, 0, 0, 1, 1};\n\tint i188[] = {1, 0, 0, 0, 1, 0, 0};\n\tint i189[] = {1, 0, 0, 0, 1, 0, 1};\n\tint i190[] = {1, 0, 0, 0, 1, 1, 0};\n\tint i191[] = {1, 0, 0, 0, 1, 1, 1};\n\tint i192[] = {1, 0, 0, 1, 0, 0, 0};\n\tint i193[] = {1, 0, 0, 1, 0, 0, 1};\n\tint i194[] = {1, 0, 0, 1, 0, 1, 0};\n\tint i195[] = {1, 0, 0, 1, 0, 1, 1};\n\tint i196[] = {1, 0, 0, 1, 1, 0, 0};\n\tint i197[] = {1, 0, 0, 1, 1, 0, 1};\n\tint i198[] = {1, 0, 0, 1, 1, 1, 0};\n\tint i199[] = {1, 0, 0, 1, 1, 1, 1};\n\tint i200[] = {1, 0, 1, 0, 0, 0, 0};\n\tint i201[] = {1, 0, 1, 0, 0, 0, 1};\n\tint i202[] = {1, 0, 1, 0, 0, 1, 0};\n\tint i203[] = {1, 0, 1, 0, 0, 1, 1};\n\tint i204[] = {1, 0, 1, 0, 1, 0, 0};\n\tint i205[] = {1, 0, 1, 0, 1, 0, 1};\n\tint i206[] = {1, 0, 1, 0, 1, 1, 0};\n\tint i207[] = {1, 0, 1, 0, 1, 1, 1};\n\tint i208[] = {1, 0, 1, 1, 0, 0, 0};\n\tint i209[] = {1, 0, 1, 1, 0, 0, 1};\n\tint i210[] = {1, 0, 1, 1, 0, 1, 0};\n\tint i211[] = {1, 0, 1, 1, 0, 1, 1};\n\tint i212[] = {1, 0, 1, 1, 1, 0, 0};\n\tint i213[] = {1, 0, 1, 1, 1, 0, 1};\n\tint i214[] = {1, 0, 1, 1, 1, 1, 0};\n\tint i215[] = {1, 0, 1, 1, 1, 1, 1};\n\tint i216[] = {1, 1, 0, 0, 0, 0, 0};\n\tint i217[] = {1, 1, 0, 0, 0, 0, 1};\n\tint i218[] = {1, 1, 0, 0, 0, 1, 0};\n\tint i219[] = {1, 1, 0, 0, 0, 1, 1};\n\tint i220[] = {1, 1, 0, 0, 1, 0, 0};\n\tint i221[] = {1, 1, 0, 0, 1, 0, 1};\n\tint i222[] = {1, 1, 0, 0, 1, 1, 0};\n\tint i223[] = {1, 1, 0, 0, 1, 1, 1};\n\tint i224[] = {1, 1, 0, 1, 0, 0, 0};\n\tint i225[] = {1, 1, 0, 1, 0, 0, 1};\n\tint i226[] = {1, 1, 0, 1, 0, 1, 0};\n\tint i227[] = {1, 1, 0, 1, 0, 1, 1};\n\tint i228[] = {1, 1, 0, 1, 1, 0, 0};\n\tint i229[] = {1, 1, 0, 1, 1, 0, 1};\n\tint i230[] = {1, 1, 0, 1, 1, 1, 0};\n\tint i231[] = {1, 1, 0, 1, 1, 1, 1};\n\tint i232[] = {1, 1, 1, 0, 0, 0, 0};\n\tint i233[] = {1, 1, 1, 0, 0, 0, 1};\n\tint i234[] = {1, 1, 1, 0, 0, 1, 0};\n\tint i235[] = {1, 1, 1, 0, 0, 1, 1};\n\tint i236[] = {1, 1, 1, 0, 1, 0, 0};\n\tint i237[] = {1, 1, 1, 0, 1, 0, 1};\n\tint i238[] = {1, 1, 1, 0, 1, 1, 0};\n\tint i239[] = {1, 1, 1, 0, 1, 1, 1};\n\tint i240[] = {1, 1, 1, 1, 0, 0, 0};\n\tint i241[] = {1, 1, 1, 1, 0, 0, 1};\n\tint i242[] = {1, 1, 1, 1, 0, 1, 0};\n\tint i243[] = {1, 1, 1, 1, 0, 1, 1};\n\tint i244[] = {1, 1, 1, 1, 1, 0, 0};\n\tint i245[] = {1, 1, 1, 1, 1, 0, 1};\n\tint i246[] = {1, 1, 1, 1, 1, 1, 0};\n\tis_heap(i120, i120+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i120, i120+7) == i120+7)); });\n\tis_heap(i121, i121+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i121, i121+7) == i121+7)); });\n\tis_heap(i122, i122+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i122, i122+7) == i122+7)); });\n\tis_heap(i123, i123+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i123, i123+7) == i123+7)); });\n\tis_heap(i124, i124+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i124, i124+7) == i124+7)); });\n\tis_heap(i125, i125+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i125, i125+7) == i125+7)); });\n\tis_heap(i126, i126+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i126, i126+7) == i126+7)); });\n\tis_heap(i127, i127+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i127, i127+7) == i127+7)); });\n\tis_heap(i128, i128+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i128, i128+7) == i128+7)); });\n\tis_heap(i129, i129+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i129, i129+7) == i129+7)); });\n\tis_heap(i130, i130+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i130, i130+7) == i130+7)); });\n\tis_heap(i131, i131+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i131, i131+7) == i131+7)); });\n\tis_heap(i132, i132+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i132, i132+7) == i132+7)); });\n\tis_heap(i133, i133+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i133, i133+7) == i133+7)); });\n\tis_heap(i134, i134+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i134, i134+7) == i134+7)); });\n\tis_heap(i135, i135+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i135, i135+7) == i135+7)); });\n\tis_heap(i136, i136+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i136, i136+7) == i136+7)); });\n\tis_heap(i137, i137+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i137, i137+7) == i137+7)); });\n\tis_heap(i138, i138+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i138, i138+7) == i138+7)); });\n\tis_heap(i139, i139+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i139, i139+7) == i139+7)); });\n\tis_heap(i140, i140+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i140, i140+7) == i140+7)); });\n\tis_heap(i141, i141+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i141, i141+7) == i141+7)); });\n\tis_heap(i142, i142+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i142, i142+7) == i142+7)); });\n\tis_heap(i143, i143+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i143, i143+7) == i143+7)); });\n\tis_heap(i144, i144+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i144, i144+7) == i144+7)); });\n\tis_heap(i145, i145+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i145, i145+7) == i145+7)); });\n\tis_heap(i146, i146+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i146, i146+7) == i146+7)); });\n\tis_heap(i147, i147+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i147, i147+7) == i147+7)); });\n\tis_heap(i148, i148+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i148, i148+7) == i148+7)); });\n\tis_heap(i149, i149+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i149, i149+7) == i149+7)); });\n\tis_heap(i150, i150+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i150, i150+7) == i150+7)); });\n\tis_heap(i151, i151+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i151, i151+7) == i151+7)); });\n\tis_heap(i152, i152+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i152, i152+7) == i152+7)); });\n\tis_heap(i153, i153+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i153, i153+7) == i153+7)); });\n\tis_heap(i154, i154+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i154, i154+7) == i154+7)); });\n\tis_heap(i155, i155+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i155, i155+7) == i155+7)); });\n\tis_heap(i156, i156+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i156, i156+7) == i156+7)); });\n\tis_heap(i157, i157+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i157, i157+7) == i157+7)); });\n\tis_heap(i158, i158+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i158, i158+7) == i158+7)); });\n\tis_heap(i159, i159+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i159, i159+7) == i159+7)); });\n\tis_heap(i160, i160+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i160, i160+7) == i160+7)); });\n\tis_heap(i161, i161+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i161, i161+7) == i161+7)); });\n\tis_heap(i162, i162+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i162, i162+7) == i162+7)); });\n\tis_heap(i163, i163+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i163, i163+7) == i163+7)); });\n\tis_heap(i164, i164+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i164, i164+7) == i164+7)); });\n\tis_heap(i165, i165+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i165, i165+7) == i165+7)); });\n\tis_heap(i166, i166+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i166, i166+7) == i166+7)); });\n\tis_heap(i167, i167+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i167, i167+7) == i167+7)); });\n\tis_heap(i168, i168+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i168, i168+7) == i168+7)); });\n\tis_heap(i169, i169+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i169, i169+7) == i169+7)); });\n\tis_heap(i170, i170+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i170, i170+7) == i170+7)); });\n\tis_heap(i171, i171+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i171, i171+7) == i171+7)); });\n\tis_heap(i172, i172+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i172, i172+7) == i172+7)); });\n\tis_heap(i173, i173+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i173, i173+7) == i173+7)); });\n\tis_heap(i174, i174+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i174, i174+7) == i174+7)); });\n\tis_heap(i175, i175+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i175, i175+7) == i175+7)); });\n\tis_heap(i176, i176+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i176, i176+7) == i176+7)); });\n\tis_heap(i177, i177+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i177, i177+7) == i177+7)); });\n\tis_heap(i178, i178+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i178, i178+7) == i178+7)); });\n\tis_heap(i179, i179+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i179, i179+7) == i179+7)); });\n\tis_heap(i180, i180+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i180, i180+7) == i180+7)); });\n\tis_heap(i181, i181+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i181, i181+7) == i181+7)); });\n\tis_heap(i182, i182+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i182, i182+7) == i182+7)); });\n\tis_heap(i183, i183+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i183, i183+7) == i183+7)); });\n\tis_heap(i184, i184+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i184, i184+7) == i184+7)); });\n\tis_heap(i185, i185+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i185, i185+7) == i185+7)); });\n\tis_heap(i186, i186+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i186, i186+7) == i186+7)); });\n\tis_heap(i187, i187+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i187, i187+7) == i187+7)); });\n\tis_heap(i188, i188+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i188, i188+7) == i188+7)); });\n\tis_heap(i189, i189+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i189, i189+7) == i189+7)); });\n\tis_heap(i190, i190+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i190, i190+7) == i190+7)); });\n\tis_heap(i191, i191+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i191, i191+7) == i191+7)); });\n\tis_heap(i192, i192+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i192, i192+7) == i192+7)); });\n\tis_heap(i193, i193+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i193, i193+7) == i193+7)); });\n\tis_heap(i194, i194+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i194, i194+7) == i194+7)); });\n\tis_heap(i195, i195+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i195, i195+7) == i195+7)); });\n\tis_heap(i196, i196+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i196, i196+7) == i196+7)); });\n\tis_heap(i197, i197+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i197, i197+7) == i197+7)); });\n\tis_heap(i198, i198+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i198, i198+7) == i198+7)); });\n\tis_heap(i199, i199+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i199, i199+7) == i199+7)); });\n\tis_heap(i200, i200+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i200, i200+7) == i200+7)); });\n\tis_heap(i201, i201+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i201, i201+7) == i201+7)); });\n\tis_heap(i202, i202+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i202, i202+7) == i202+7)); });\n\tis_heap(i203, i203+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i203, i203+7) == i203+7)); });\n\tis_heap(i204, i204+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i204, i204+7) == i204+7)); });\n\tis_heap(i205, i205+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i205, i205+7) == i205+7)); });\n\tis_heap(i206, i206+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i206, i206+7) == i206+7)); });\n\tis_heap(i207, i207+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i207, i207+7) == i207+7)); });\n\tis_heap(i208, i208+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i208, i208+7) == i208+7)); });\n\tis_heap(i209, i209+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i209, i209+7) == i209+7)); });\n\tis_heap(i210, i210+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i210, i210+7) == i210+7)); });\n\tis_heap(i211, i211+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i211, i211+7) == i211+7)); });\n\tis_heap(i212, i212+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i212, i212+7) == i212+7)); });\n\tis_heap(i213, i213+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i213, i213+7) == i213+7)); });\n\tis_heap(i214, i214+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i214, i214+7) == i214+7)); });\n\tis_heap(i215, i215+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i215, i215+7) == i215+7)); });\n\tis_heap(i216, i216+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i216, i216+7) == i216+7)); });\n\tis_heap(i217, i217+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i217, i217+7) == i217+7)); });\n\tis_heap(i218, i218+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i218, i218+7) == i218+7)); });\n\tis_heap(i219, i219+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i219, i219+7) == i219+7)); });\n\tis_heap(i220, i220+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i220, i220+7) == i220+7)); });\n\tis_heap(i221, i221+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i221, i221+7) == i221+7)); });\n\tis_heap(i222, i222+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i222, i222+7) == i222+7)); });\n\tis_heap(i223, i223+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i223, i223+7) == i223+7)); });\n\tis_heap(i224, i224+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i224, i224+7) == i224+7)); });\n\tis_heap(i225, i225+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i225, i225+7) == i225+7)); });\n\tis_heap(i226, i226+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i226, i226+7) == i226+7)); });\n\tis_heap(i227, i227+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i227, i227+7) == i227+7)); });\n\tis_heap(i228, i228+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i228, i228+7) == i228+7)); });\n\tis_heap(i229, i229+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i229, i229+7) == i229+7)); });\n\tis_heap(i230, i230+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i230, i230+7) == i230+7)); });\n\tis_heap(i231, i231+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i231, i231+7) == i231+7)); });\n\tis_heap(i232, i232+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i232, i232+7) == i232+7)); });\n\tis_heap(i233, i233+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i233, i233+7) == i233+7)); });\n\tis_heap(i234, i234+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i234, i234+7) == i234+7)); });\n\tis_heap(i235, i235+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i235, i235+7) == i235+7)); });\n\tis_heap(i236, i236+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i236, i236+7) == i236+7)); });\n\tis_heap(i237, i237+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i237, i237+7) == i237+7)); });\n\tis_heap(i238, i238+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i238, i238+7) == i238+7)); });\n\tis_heap(i239, i239+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i239, i239+7) == i239+7)); });\n\tis_heap(i240, i240+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i240, i240+7) == i240+7)); });\n\tis_heap(i241, i241+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i241, i241+7) == i241+7)); });\n\tis_heap(i242, i242+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i242, i242+7) == i242+7)); });\n\tis_heap(i243, i243+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i243, i243+7) == i243+7)); });\n\tis_heap(i244, i244+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i244, i244+7) == i244+7)); });\n\tis_heap(i245, i245+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i245, i245+7) == i245+7)); });\n\tis_heap(i246, i246+7).check([&](bool r){ CHECK(r == (std::is_heap_until(i246, i246+7) == i246+7)); });\n#endif\n}\n\nvoid test_comp()\n{\n#if defined(IS_HEAP_3) || defined(IS_HEAP_4)\n\tauto is_heap = make_testable_1([](auto&&... args) {\n\t\treturn stl2::is_heap(std::forward<decltype(args)>(args)...);\n\t});\n#endif\n\n#ifdef IS_HEAP_3\n\tint i1[] = {0, 0};\n\tis_heap(i1, i1, std::greater<int>()).check([&](bool r){ CHECK(r); });\n\tis_heap(i1, i1+1, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i1, i1+1, std::greater<int>()) == i1+1)); });\n\tint i2[] = {0, 1};\n\tint i3[] = {1, 0};\n\tis_heap(i1, i1+2, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i1, i1+2, std::greater<int>()) == i1+2)); });\n\tis_heap(i2, i2+2, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i2, i2+2, std::greater<int>()) == i2+2)); });\n\tis_heap(i3, i3+2, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i3, i3+2, std::greater<int>()) == i3+2)); });\n\tint i4[] = {0, 0, 0};\n\tint i5[] = {0, 0, 1};\n\tint i6[] = {0, 1, 0};\n\tint i7[] = {0, 1, 1};\n\tint i8[] = {1, 0, 0};\n\tint i9[] = {1, 0, 1};\n\tint i10[] = {1, 1, 0};\n\tis_heap(i4, i4+3, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i4, i4+3, std::greater<int>()) == i4+3)); });\n\tis_heap(i5, i5+3, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i5, i5+3, std::greater<int>()) == i5+3)); });\n\tis_heap(i6, i6+3, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i6, i6+3, std::greater<int>()) == i6+3)); });\n\tis_heap(i7, i7+3, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i7, i7+3, std::greater<int>()) == i7+3)); });\n\tis_heap(i8, i8+3, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i8, i8+3, std::greater<int>()) == i8+3)); });\n\tis_heap(i9, i9+3, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i9, i9+3, std::greater<int>()) == i9+3)); });\n\tis_heap(i10, i10+3, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i10, i10+3, std::greater<int>()) == i10+3)); });\n\tint i11[] = {0, 0, 0, 0};\n\tint i12[] = {0, 0, 0, 1};\n\tint i13[] = {0, 0, 1, 0};\n\tint i14[] = {0, 0, 1, 1};\n\tint i15[] = {0, 1, 0, 0};\n\tint i16[] = {0, 1, 0, 1};\n\tint i17[] = {0, 1, 1, 0};\n\tint i18[] = {0, 1, 1, 1};\n\tint i19[] = {1, 0, 0, 0};\n\tint i20[] = {1, 0, 0, 1};\n\tint i21[] = {1, 0, 1, 0};\n\tint i22[] = {1, 0, 1, 1};\n\tint i23[] = {1, 1, 0, 0};\n\tint i24[] = {1, 1, 0, 1};\n\tint i25[] = {1, 1, 1, 0};\n\tis_heap(i11, i11+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i11, i11+4, std::greater<int>()) == i11+4)); });\n\tis_heap(i12, i12+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i12, i12+4, std::greater<int>()) == i12+4)); });\n\tis_heap(i13, i13+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i13, i13+4, std::greater<int>()) == i13+4)); });\n\tis_heap(i14, i14+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i14, i14+4, std::greater<int>()) == i14+4)); });\n\tis_heap(i15, i15+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i15, i15+4, std::greater<int>()) == i15+4)); });\n\tis_heap(i16, i16+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i16, i16+4, std::greater<int>()) == i16+4)); });\n\tis_heap(i17, i17+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i17, i17+4, std::greater<int>()) == i17+4)); });\n\tis_heap(i18, i18+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i18, i18+4, std::greater<int>()) == i18+4)); });\n\tis_heap(i19, i19+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i19, i19+4, std::greater<int>()) == i19+4)); });\n\tis_heap(i20, i20+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i20, i20+4, std::greater<int>()) == i20+4)); });\n\tis_heap(i21, i21+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i21, i21+4, std::greater<int>()) == i21+4)); });\n\tis_heap(i22, i22+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i22, i22+4, std::greater<int>()) == i22+4)); });\n\tis_heap(i23, i23+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i23, i23+4, std::greater<int>()) == i23+4)); });\n\tis_heap(i24, i24+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i24, i24+4, std::greater<int>()) == i24+4)); });\n\tis_heap(i25, i25+4, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i25, i25+4, std::greater<int>()) == i25+4)); });\n\tint i26[] = {0, 0, 0, 0, 0};\n\tint i27[] = {0, 0, 0, 0, 1};\n\tint i28[] = {0, 0, 0, 1, 0};\n\tint i29[] = {0, 0, 0, 1, 1};\n\tint i30[] = {0, 0, 1, 0, 0};\n\tint i31[] = {0, 0, 1, 0, 1};\n\tint i32[] = {0, 0, 1, 1, 0};\n\tint i33[] = {0, 0, 1, 1, 1};\n\tint i34[] = {0, 1, 0, 0, 0};\n\tint i35[] = {0, 1, 0, 0, 1};\n\tint i36[] = {0, 1, 0, 1, 0};\n\tint i37[] = {0, 1, 0, 1, 1};\n\tint i38[] = {0, 1, 1, 0, 0};\n\tint i39[] = {0, 1, 1, 0, 1};\n\tint i40[] = {0, 1, 1, 1, 0};\n\tint i41[] = {0, 1, 1, 1, 1};\n\tint i42[] = {1, 0, 0, 0, 0};\n\tint i43[] = {1, 0, 0, 0, 1};\n\tint i44[] = {1, 0, 0, 1, 0};\n\tint i45[] = {1, 0, 0, 1, 1};\n\tint i46[] = {1, 0, 1, 0, 0};\n\tint i47[] = {1, 0, 1, 0, 1};\n\tint i48[] = {1, 0, 1, 1, 0};\n\tint i49[] = {1, 0, 1, 1, 1};\n\tint i50[] = {1, 1, 0, 0, 0};\n\tint i51[] = {1, 1, 0, 0, 1};\n\tint i52[] = {1, 1, 0, 1, 0};\n\tint i53[] = {1, 1, 0, 1, 1};\n\tint i54[] = {1, 1, 1, 0, 0};\n\tint i55[] = {1, 1, 1, 0, 1};\n\tint i56[] = {1, 1, 1, 1, 0};\n\tis_heap(i26, i26+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i26, i26+5, std::greater<int>()) == i26+5)); });\n\tis_heap(i27, i27+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i27, i27+5, std::greater<int>()) == i27+5)); });\n\tis_heap(i28, i28+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i28, i28+5, std::greater<int>()) == i28+5)); });\n\tis_heap(i29, i29+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i29, i29+5, std::greater<int>()) == i29+5)); });\n\tis_heap(i30, i30+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i30, i30+5, std::greater<int>()) == i30+5)); });\n\tis_heap(i31, i31+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i31, i31+5, std::greater<int>()) == i31+5)); });\n\tis_heap(i32, i32+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i32, i32+5, std::greater<int>()) == i32+5)); });\n\tis_heap(i33, i33+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i33, i33+5, std::greater<int>()) == i33+5)); });\n\tis_heap(i34, i34+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i34, i34+5, std::greater<int>()) == i34+5)); });\n\tis_heap(i35, i35+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i35, i35+5, std::greater<int>()) == i35+5)); });\n\tis_heap(i36, i36+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i36, i36+5, std::greater<int>()) == i36+5)); });\n\tis_heap(i37, i37+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i37, i37+5, std::greater<int>()) == i37+5)); });\n\tis_heap(i38, i38+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i38, i38+5, std::greater<int>()) == i38+5)); });\n\tis_heap(i39, i39+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i39, i39+5, std::greater<int>()) == i39+5)); });\n\tis_heap(i40, i40+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i40, i40+5, std::greater<int>()) == i40+5)); });\n\tis_heap(i41, i41+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i41, i41+5, std::greater<int>()) == i41+5)); });\n\tis_heap(i42, i42+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i42, i42+5, std::greater<int>()) == i42+5)); });\n\tis_heap(i43, i43+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i43, i43+5, std::greater<int>()) == i43+5)); });\n\tis_heap(i44, i44+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i44, i44+5, std::greater<int>()) == i44+5)); });\n\tis_heap(i45, i45+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i45, i45+5, std::greater<int>()) == i45+5)); });\n\tis_heap(i46, i46+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i46, i46+5, std::greater<int>()) == i46+5)); });\n\tis_heap(i47, i47+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i47, i47+5, std::greater<int>()) == i47+5)); });\n\tis_heap(i48, i48+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i48, i48+5, std::greater<int>()) == i48+5)); });\n\tis_heap(i49, i49+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i49, i49+5, std::greater<int>()) == i49+5)); });\n\tis_heap(i50, i50+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i50, i50+5, std::greater<int>()) == i50+5)); });\n\tis_heap(i51, i51+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i51, i51+5, std::greater<int>()) == i51+5)); });\n\tis_heap(i52, i52+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i52, i52+5, std::greater<int>()) == i52+5)); });\n\tis_heap(i53, i53+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i53, i53+5, std::greater<int>()) == i53+5)); });\n\tis_heap(i54, i54+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i54, i54+5, std::greater<int>()) == i54+5)); });\n\tis_heap(i55, i55+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i55, i55+5, std::greater<int>()) == i55+5)); });\n\tis_heap(i56, i56+5, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i56, i56+5, std::greater<int>()) == i56+5)); });\n\tint i57[] = {0, 0, 0, 0, 0, 0};\n\tint i58[] = {0, 0, 0, 0, 0, 1};\n\tint i59[] = {0, 0, 0, 0, 1, 0};\n\tint i60[] = {0, 0, 0, 0, 1, 1};\n\tint i61[] = {0, 0, 0, 1, 0, 0};\n\tint i62[] = {0, 0, 0, 1, 0, 1};\n\tint i63[] = {0, 0, 0, 1, 1, 0};\n\tint i64[] = {0, 0, 0, 1, 1, 1};\n\tint i65[] = {0, 0, 1, 0, 0, 0};\n\tint i66[] = {0, 0, 1, 0, 0, 1};\n\tint i67[] = {0, 0, 1, 0, 1, 0};\n\tint i68[] = {0, 0, 1, 0, 1, 1};\n\tint i69[] = {0, 0, 1, 1, 0, 0};\n\tint i70[] = {0, 0, 1, 1, 0, 1};\n\tint i71[] = {0, 0, 1, 1, 1, 0};\n\tint i72[] = {0, 0, 1, 1, 1, 1};\n\tint i73[] = {0, 1, 0, 0, 0, 0};\n\tint i74[] = {0, 1, 0, 0, 0, 1};\n\tint i75[] = {0, 1, 0, 0, 1, 0};\n\tint i76[] = {0, 1, 0, 0, 1, 1};\n\tint i77[] = {0, 1, 0, 1, 0, 0};\n\tint i78[] = {0, 1, 0, 1, 0, 1};\n\tint i79[] = {0, 1, 0, 1, 1, 0};\n\tint i80[] = {0, 1, 0, 1, 1, 1};\n\tint i81[] = {0, 1, 1, 0, 0, 0};\n\tint i82[] = {0, 1, 1, 0, 0, 1};\n\tint i83[] = {0, 1, 1, 0, 1, 0};\n\tint i84[] = {0, 1, 1, 0, 1, 1};\n\tint i85[] = {0, 1, 1, 1, 0, 0};\n\tint i86[] = {0, 1, 1, 1, 0, 1};\n\tint i87[] = {0, 1, 1, 1, 1, 0};\n\tint i88[] = {0, 1, 1, 1, 1, 1};\n\tint i89[] = {1, 0, 0, 0, 0, 0};\n\tint i90[] = {1, 0, 0, 0, 0, 1};\n\tint i91[] = {1, 0, 0, 0, 1, 0};\n\tint i92[] = {1, 0, 0, 0, 1, 1};\n\tint i93[] = {1, 0, 0, 1, 0, 0};\n\tint i94[] = {1, 0, 0, 1, 0, 1};\n\tint i95[] = {1, 0, 0, 1, 1, 0};\n\tint i96[] = {1, 0, 0, 1, 1, 1};\n\tint i97[] = {1, 0, 1, 0, 0, 0};\n\tint i98[] = {1, 0, 1, 0, 0, 1};\n\tint i99[] = {1, 0, 1, 0, 1, 0};\n\tint i100[] = {1, 0, 1, 0, 1, 1};\n\tint i101[] = {1, 0, 1, 1, 0, 0};\n\tint i102[] = {1, 0, 1, 1, 0, 1};\n\tint i103[] = {1, 0, 1, 1, 1, 0};\n\tint i104[] = {1, 0, 1, 1, 1, 1};\n\tint i105[] = {1, 1, 0, 0, 0, 0};\n\tint i106[] = {1, 1, 0, 0, 0, 1};\n\tint i107[] = {1, 1, 0, 0, 1, 0};\n\tint i108[] = {1, 1, 0, 0, 1, 1};\n\tint i109[] = {1, 1, 0, 1, 0, 0};\n\tint i110[] = {1, 1, 0, 1, 0, 1};\n\tint i111[] = {1, 1, 0, 1, 1, 0};\n\tint i112[] = {1, 1, 0, 1, 1, 1};\n\tint i113[] = {1, 1, 1, 0, 0, 0};\n\tint i114[] = {1, 1, 1, 0, 0, 1};\n\tint i115[] = {1, 1, 1, 0, 1, 0};\n\tint i116[] = {1, 1, 1, 0, 1, 1};\n\tint i117[] = {1, 1, 1, 1, 0, 0};\n\tint i118[] = {1, 1, 1, 1, 0, 1};\n\tint i119[] = {1, 1, 1, 1, 1, 0};\n\tis_heap(i57, i57+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i57, i57+6, std::greater<int>()) == i57+6)); });\n\tis_heap(i58, i58+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i58, i58+6, std::greater<int>()) == i58+6)); });\n\tis_heap(i59, i59+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i59, i59+6, std::greater<int>()) == i59+6)); });\n\tis_heap(i60, i60+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i60, i60+6, std::greater<int>()) == i60+6)); });\n\tis_heap(i61, i61+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i61, i61+6, std::greater<int>()) == i61+6)); });\n\tis_heap(i62, i62+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i62, i62+6, std::greater<int>()) == i62+6)); });\n\tis_heap(i63, i63+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i63, i63+6, std::greater<int>()) == i63+6)); });\n\tis_heap(i64, i64+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i64, i64+6, std::greater<int>()) == i64+6)); });\n\tis_heap(i65, i65+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i65, i65+6, std::greater<int>()) == i65+6)); });\n\tis_heap(i66, i66+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i66, i66+6, std::greater<int>()) == i66+6)); });\n\tis_heap(i67, i67+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i67, i67+6, std::greater<int>()) == i67+6)); });\n\tis_heap(i68, i68+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i68, i68+6, std::greater<int>()) == i68+6)); });\n\tis_heap(i69, i69+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i69, i69+6, std::greater<int>()) == i69+6)); });\n\tis_heap(i70, i70+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i70, i70+6, std::greater<int>()) == i70+6)); });\n\tis_heap(i71, i71+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i71, i71+6, std::greater<int>()) == i71+6)); });\n\tis_heap(i72, i72+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i72, i72+6, std::greater<int>()) == i72+6)); });\n\tis_heap(i73, i73+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i73, i73+6, std::greater<int>()) == i73+6)); });\n\tis_heap(i74, i74+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i74, i74+6, std::greater<int>()) == i74+6)); });\n\tis_heap(i75, i75+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i75, i75+6, std::greater<int>()) == i75+6)); });\n\tis_heap(i76, i76+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i76, i76+6, std::greater<int>()) == i76+6)); });\n\tis_heap(i77, i77+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i77, i77+6, std::greater<int>()) == i77+6)); });\n\tis_heap(i78, i78+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i78, i78+6, std::greater<int>()) == i78+6)); });\n\tis_heap(i79, i79+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i79, i79+6, std::greater<int>()) == i79+6)); });\n\tis_heap(i80, i80+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i80, i80+6, std::greater<int>()) == i80+6)); });\n\tis_heap(i81, i81+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i81, i81+6, std::greater<int>()) == i81+6)); });\n\tis_heap(i82, i82+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i82, i82+6, std::greater<int>()) == i82+6)); });\n\tis_heap(i83, i83+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i83, i83+6, std::greater<int>()) == i83+6)); });\n\tis_heap(i84, i84+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i84, i84+6, std::greater<int>()) == i84+6)); });\n\tis_heap(i85, i85+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i85, i85+6, std::greater<int>()) == i85+6)); });\n\tis_heap(i86, i86+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i86, i86+6, std::greater<int>()) == i86+6)); });\n\tis_heap(i87, i87+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i87, i87+6, std::greater<int>()) == i87+6)); });\n\tis_heap(i88, i88+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i88, i88+6, std::greater<int>()) == i88+6)); });\n\tis_heap(i89, i89+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i89, i89+6, std::greater<int>()) == i89+6)); });\n\tis_heap(i90, i90+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i90, i90+6, std::greater<int>()) == i90+6)); });\n\tis_heap(i91, i91+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i91, i91+6, std::greater<int>()) == i91+6)); });\n\tis_heap(i92, i92+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i92, i92+6, std::greater<int>()) == i92+6)); });\n\tis_heap(i93, i93+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i93, i93+6, std::greater<int>()) == i93+6)); });\n\tis_heap(i94, i94+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i94, i94+6, std::greater<int>()) == i94+6)); });\n\tis_heap(i95, i95+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i95, i95+6, std::greater<int>()) == i95+6)); });\n\tis_heap(i96, i96+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i96, i96+6, std::greater<int>()) == i96+6)); });\n\tis_heap(i97, i97+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i97, i97+6, std::greater<int>()) == i97+6)); });\n\tis_heap(i98, i98+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i98, i98+6, std::greater<int>()) == i98+6)); });\n\tis_heap(i99, i99+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i99, i99+6, std::greater<int>()) == i99+6)); });\n\tis_heap(i100, i100+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i100, i100+6, std::greater<int>()) == i100+6)); });\n\tis_heap(i101, i101+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i101, i101+6, std::greater<int>()) == i101+6)); });\n\tis_heap(i102, i102+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i102, i102+6, std::greater<int>()) == i102+6)); });\n\tis_heap(i103, i103+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i103, i103+6, std::greater<int>()) == i103+6)); });\n\tis_heap(i104, i104+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i104, i104+6, std::greater<int>()) == i104+6)); });\n\tis_heap(i105, i105+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i105, i105+6, std::greater<int>()) == i105+6)); });\n\tis_heap(i106, i106+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i106, i106+6, std::greater<int>()) == i106+6)); });\n\tis_heap(i107, i107+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i107, i107+6, std::greater<int>()) == i107+6)); });\n\tis_heap(i108, i108+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i108, i108+6, std::greater<int>()) == i108+6)); });\n\tis_heap(i109, i109+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i109, i109+6, std::greater<int>()) == i109+6)); });\n\tis_heap(i110, i110+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i110, i110+6, std::greater<int>()) == i110+6)); });\n\tis_heap(i111, i111+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i111, i111+6, std::greater<int>()) == i111+6)); });\n\tis_heap(i112, i112+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i112, i112+6, std::greater<int>()) == i112+6)); });\n\tis_heap(i113, i113+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i113, i113+6, std::greater<int>()) == i113+6)); });\n\tis_heap(i114, i114+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i114, i114+6, std::greater<int>()) == i114+6)); });\n\tis_heap(i115, i115+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i115, i115+6, std::greater<int>()) == i115+6)); });\n\tis_heap(i116, i116+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i116, i116+6, std::greater<int>()) == i116+6)); });\n\tis_heap(i117, i117+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i117, i117+6, std::greater<int>()) == i117+6)); });\n\tis_heap(i118, i118+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i118, i118+6, std::greater<int>()) == i118+6)); });\n\tis_heap(i119, i119+6, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i119, i119+6, std::greater<int>()) == i119+6)); });\n#endif\n#ifdef IS_HEAP_4\n\tint i120[] = {0, 0, 0, 0, 0, 0, 0};\n\tint i121[] = {0, 0, 0, 0, 0, 0, 1};\n\tint i122[] = {0, 0, 0, 0, 0, 1, 0};\n\tint i123[] = {0, 0, 0, 0, 0, 1, 1};\n\tint i124[] = {0, 0, 0, 0, 1, 0, 0};\n\tint i125[] = {0, 0, 0, 0, 1, 0, 1};\n\tint i126[] = {0, 0, 0, 0, 1, 1, 0};\n\tint i127[] = {0, 0, 0, 0, 1, 1, 1};\n\tint i128[] = {0, 0, 0, 1, 0, 0, 0};\n\tint i129[] = {0, 0, 0, 1, 0, 0, 1};\n\tint i130[] = {0, 0, 0, 1, 0, 1, 0};\n\tint i131[] = {0, 0, 0, 1, 0, 1, 1};\n\tint i132[] = {0, 0, 0, 1, 1, 0, 0};\n\tint i133[] = {0, 0, 0, 1, 1, 0, 1};\n\tint i134[] = {0, 0, 0, 1, 1, 1, 0};\n\tint i135[] = {0, 0, 0, 1, 1, 1, 1};\n\tint i136[] = {0, 0, 1, 0, 0, 0, 0};\n\tint i137[] = {0, 0, 1, 0, 0, 0, 1};\n\tint i138[] = {0, 0, 1, 0, 0, 1, 0};\n\tint i139[] = {0, 0, 1, 0, 0, 1, 1};\n\tint i140[] = {0, 0, 1, 0, 1, 0, 0};\n\tint i141[] = {0, 0, 1, 0, 1, 0, 1};\n\tint i142[] = {0, 0, 1, 0, 1, 1, 0};\n\tint i143[] = {0, 0, 1, 0, 1, 1, 1};\n\tint i144[] = {0, 0, 1, 1, 0, 0, 0};\n\tint i145[] = {0, 0, 1, 1, 0, 0, 1};\n\tint i146[] = {0, 0, 1, 1, 0, 1, 0};\n\tint i147[] = {0, 0, 1, 1, 0, 1, 1};\n\tint i148[] = {0, 0, 1, 1, 1, 0, 0};\n\tint i149[] = {0, 0, 1, 1, 1, 0, 1};\n\tint i150[] = {0, 0, 1, 1, 1, 1, 0};\n\tint i151[] = {0, 0, 1, 1, 1, 1, 1};\n\tint i152[] = {0, 1, 0, 0, 0, 0, 0};\n\tint i153[] = {0, 1, 0, 0, 0, 0, 1};\n\tint i154[] = {0, 1, 0, 0, 0, 1, 0};\n\tint i155[] = {0, 1, 0, 0, 0, 1, 1};\n\tint i156[] = {0, 1, 0, 0, 1, 0, 0};\n\tint i157[] = {0, 1, 0, 0, 1, 0, 1};\n\tint i158[] = {0, 1, 0, 0, 1, 1, 0};\n\tint i159[] = {0, 1, 0, 0, 1, 1, 1};\n\tint i160[] = {0, 1, 0, 1, 0, 0, 0};\n\tint i161[] = {0, 1, 0, 1, 0, 0, 1};\n\tint i162[] = {0, 1, 0, 1, 0, 1, 0};\n\tint i163[] = {0, 1, 0, 1, 0, 1, 1};\n\tint i164[] = {0, 1, 0, 1, 1, 0, 0};\n\tint i165[] = {0, 1, 0, 1, 1, 0, 1};\n\tint i166[] = {0, 1, 0, 1, 1, 1, 0};\n\tint i167[] = {0, 1, 0, 1, 1, 1, 1};\n\tint i168[] = {0, 1, 1, 0, 0, 0, 0};\n\tint i169[] = {0, 1, 1, 0, 0, 0, 1};\n\tint i170[] = {0, 1, 1, 0, 0, 1, 0};\n\tint i171[] = {0, 1, 1, 0, 0, 1, 1};\n\tint i172[] = {0, 1, 1, 0, 1, 0, 0};\n\tint i173[] = {0, 1, 1, 0, 1, 0, 1};\n\tint i174[] = {0, 1, 1, 0, 1, 1, 0};\n\tint i175[] = {0, 1, 1, 0, 1, 1, 1};\n\tint i176[] = {0, 1, 1, 1, 0, 0, 0};\n\tint i177[] = {0, 1, 1, 1, 0, 0, 1};\n\tint i178[] = {0, 1, 1, 1, 0, 1, 0};\n\tint i179[] = {0, 1, 1, 1, 0, 1, 1};\n\tint i180[] = {0, 1, 1, 1, 1, 0, 0};\n\tint i181[] = {0, 1, 1, 1, 1, 0, 1};\n\tint i182[] = {0, 1, 1, 1, 1, 1, 0};\n\tint i183[] = {0, 1, 1, 1, 1, 1, 1};\n\tint i184[] = {1, 0, 0, 0, 0, 0, 0};\n\tint i185[] = {1, 0, 0, 0, 0, 0, 1};\n\tint i186[] = {1, 0, 0, 0, 0, 1, 0};\n\tint i187[] = {1, 0, 0, 0, 0, 1, 1};\n\tint i188[] = {1, 0, 0, 0, 1, 0, 0};\n\tint i189[] = {1, 0, 0, 0, 1, 0, 1};\n\tint i190[] = {1, 0, 0, 0, 1, 1, 0};\n\tint i191[] = {1, 0, 0, 0, 1, 1, 1};\n\tint i192[] = {1, 0, 0, 1, 0, 0, 0};\n\tint i193[] = {1, 0, 0, 1, 0, 0, 1};\n\tint i194[] = {1, 0, 0, 1, 0, 1, 0};\n\tint i195[] = {1, 0, 0, 1, 0, 1, 1};\n\tint i196[] = {1, 0, 0, 1, 1, 0, 0};\n\tint i197[] = {1, 0, 0, 1, 1, 0, 1};\n\tint i198[] = {1, 0, 0, 1, 1, 1, 0};\n\tint i199[] = {1, 0, 0, 1, 1, 1, 1};\n\tint i200[] = {1, 0, 1, 0, 0, 0, 0};\n\tint i201[] = {1, 0, 1, 0, 0, 0, 1};\n\tint i202[] = {1, 0, 1, 0, 0, 1, 0};\n\tint i203[] = {1, 0, 1, 0, 0, 1, 1};\n\tint i204[] = {1, 0, 1, 0, 1, 0, 0};\n\tint i205[] = {1, 0, 1, 0, 1, 0, 1};\n\tint i206[] = {1, 0, 1, 0, 1, 1, 0};\n\tint i207[] = {1, 0, 1, 0, 1, 1, 1};\n\tint i208[] = {1, 0, 1, 1, 0, 0, 0};\n\tint i209[] = {1, 0, 1, 1, 0, 0, 1};\n\tint i210[] = {1, 0, 1, 1, 0, 1, 0};\n\tint i211[] = {1, 0, 1, 1, 0, 1, 1};\n\tint i212[] = {1, 0, 1, 1, 1, 0, 0};\n\tint i213[] = {1, 0, 1, 1, 1, 0, 1};\n\tint i214[] = {1, 0, 1, 1, 1, 1, 0};\n\tint i215[] = {1, 0, 1, 1, 1, 1, 1};\n\tint i216[] = {1, 1, 0, 0, 0, 0, 0};\n\tint i217[] = {1, 1, 0, 0, 0, 0, 1};\n\tint i218[] = {1, 1, 0, 0, 0, 1, 0};\n\tint i219[] = {1, 1, 0, 0, 0, 1, 1};\n\tint i220[] = {1, 1, 0, 0, 1, 0, 0};\n\tint i221[] = {1, 1, 0, 0, 1, 0, 1};\n\tint i222[] = {1, 1, 0, 0, 1, 1, 0};\n\tint i223[] = {1, 1, 0, 0, 1, 1, 1};\n\tint i224[] = {1, 1, 0, 1, 0, 0, 0};\n\tint i225[] = {1, 1, 0, 1, 0, 0, 1};\n\tint i226[] = {1, 1, 0, 1, 0, 1, 0};\n\tint i227[] = {1, 1, 0, 1, 0, 1, 1};\n\tint i228[] = {1, 1, 0, 1, 1, 0, 0};\n\tint i229[] = {1, 1, 0, 1, 1, 0, 1};\n\tint i230[] = {1, 1, 0, 1, 1, 1, 0};\n\tint i231[] = {1, 1, 0, 1, 1, 1, 1};\n\tint i232[] = {1, 1, 1, 0, 0, 0, 0};\n\tint i233[] = {1, 1, 1, 0, 0, 0, 1};\n\tint i234[] = {1, 1, 1, 0, 0, 1, 0};\n\tint i235[] = {1, 1, 1, 0, 0, 1, 1};\n\tint i236[] = {1, 1, 1, 0, 1, 0, 0};\n\tint i237[] = {1, 1, 1, 0, 1, 0, 1};\n\tint i238[] = {1, 1, 1, 0, 1, 1, 0};\n\tint i239[] = {1, 1, 1, 0, 1, 1, 1};\n\tint i240[] = {1, 1, 1, 1, 0, 0, 0};\n\tint i241[] = {1, 1, 1, 1, 0, 0, 1};\n\tint i242[] = {1, 1, 1, 1, 0, 1, 0};\n\tint i243[] = {1, 1, 1, 1, 0, 1, 1};\n\tint i244[] = {1, 1, 1, 1, 1, 0, 0};\n\tint i245[] = {1, 1, 1, 1, 1, 0, 1};\n\tint i246[] = {1, 1, 1, 1, 1, 1, 0};\n\tis_heap(i120, i120+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i120, i120+7, std::greater<int>()) == i120+7)); });\n\tis_heap(i121, i121+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i121, i121+7, std::greater<int>()) == i121+7)); });\n\tis_heap(i122, i122+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i122, i122+7, std::greater<int>()) == i122+7)); });\n\tis_heap(i123, i123+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i123, i123+7, std::greater<int>()) == i123+7)); });\n\tis_heap(i124, i124+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i124, i124+7, std::greater<int>()) == i124+7)); });\n\tis_heap(i125, i125+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i125, i125+7, std::greater<int>()) == i125+7)); });\n\tis_heap(i126, i126+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i126, i126+7, std::greater<int>()) == i126+7)); });\n\tis_heap(i127, i127+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i127, i127+7, std::greater<int>()) == i127+7)); });\n\tis_heap(i128, i128+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i128, i128+7, std::greater<int>()) == i128+7)); });\n\tis_heap(i129, i129+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i129, i129+7, std::greater<int>()) == i129+7)); });\n\tis_heap(i130, i130+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i130, i130+7, std::greater<int>()) == i130+7)); });\n\tis_heap(i131, i131+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i131, i131+7, std::greater<int>()) == i131+7)); });\n\tis_heap(i132, i132+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i132, i132+7, std::greater<int>()) == i132+7)); });\n\tis_heap(i133, i133+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i133, i133+7, std::greater<int>()) == i133+7)); });\n\tis_heap(i134, i134+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i134, i134+7, std::greater<int>()) == i134+7)); });\n\tis_heap(i135, i135+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i135, i135+7, std::greater<int>()) == i135+7)); });\n\tis_heap(i136, i136+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i136, i136+7, std::greater<int>()) == i136+7)); });\n\tis_heap(i137, i137+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i137, i137+7, std::greater<int>()) == i137+7)); });\n\tis_heap(i138, i138+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i138, i138+7, std::greater<int>()) == i138+7)); });\n\tis_heap(i139, i139+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i139, i139+7, std::greater<int>()) == i139+7)); });\n\tis_heap(i140, i140+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i140, i140+7, std::greater<int>()) == i140+7)); });\n\tis_heap(i141, i141+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i141, i141+7, std::greater<int>()) == i141+7)); });\n\tis_heap(i142, i142+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i142, i142+7, std::greater<int>()) == i142+7)); });\n\tis_heap(i143, i143+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i143, i143+7, std::greater<int>()) == i143+7)); });\n\tis_heap(i144, i144+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i144, i144+7, std::greater<int>()) == i144+7)); });\n\tis_heap(i145, i145+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i145, i145+7, std::greater<int>()) == i145+7)); });\n\tis_heap(i146, i146+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i146, i146+7, std::greater<int>()) == i146+7)); });\n\tis_heap(i147, i147+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i147, i147+7, std::greater<int>()) == i147+7)); });\n\tis_heap(i148, i148+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i148, i148+7, std::greater<int>()) == i148+7)); });\n\tis_heap(i149, i149+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i149, i149+7, std::greater<int>()) == i149+7)); });\n\tis_heap(i150, i150+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i150, i150+7, std::greater<int>()) == i150+7)); });\n\tis_heap(i151, i151+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i151, i151+7, std::greater<int>()) == i151+7)); });\n\tis_heap(i152, i152+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i152, i152+7, std::greater<int>()) == i152+7)); });\n\tis_heap(i153, i153+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i153, i153+7, std::greater<int>()) == i153+7)); });\n\tis_heap(i154, i154+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i154, i154+7, std::greater<int>()) == i154+7)); });\n\tis_heap(i155, i155+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i155, i155+7, std::greater<int>()) == i155+7)); });\n\tis_heap(i156, i156+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i156, i156+7, std::greater<int>()) == i156+7)); });\n\tis_heap(i157, i157+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i157, i157+7, std::greater<int>()) == i157+7)); });\n\tis_heap(i158, i158+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i158, i158+7, std::greater<int>()) == i158+7)); });\n\tis_heap(i159, i159+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i159, i159+7, std::greater<int>()) == i159+7)); });\n\tis_heap(i160, i160+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i160, i160+7, std::greater<int>()) == i160+7)); });\n\tis_heap(i161, i161+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i161, i161+7, std::greater<int>()) == i161+7)); });\n\tis_heap(i162, i162+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i162, i162+7, std::greater<int>()) == i162+7)); });\n\tis_heap(i163, i163+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i163, i163+7, std::greater<int>()) == i163+7)); });\n\tis_heap(i164, i164+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i164, i164+7, std::greater<int>()) == i164+7)); });\n\tis_heap(i165, i165+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i165, i165+7, std::greater<int>()) == i165+7)); });\n\tis_heap(i166, i166+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i166, i166+7, std::greater<int>()) == i166+7)); });\n\tis_heap(i167, i167+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i167, i167+7, std::greater<int>()) == i167+7)); });\n\tis_heap(i168, i168+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i168, i168+7, std::greater<int>()) == i168+7)); });\n\tis_heap(i169, i169+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i169, i169+7, std::greater<int>()) == i169+7)); });\n\tis_heap(i170, i170+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i170, i170+7, std::greater<int>()) == i170+7)); });\n\tis_heap(i171, i171+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i171, i171+7, std::greater<int>()) == i171+7)); });\n\tis_heap(i172, i172+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i172, i172+7, std::greater<int>()) == i172+7)); });\n\tis_heap(i173, i173+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i173, i173+7, std::greater<int>()) == i173+7)); });\n\tis_heap(i174, i174+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i174, i174+7, std::greater<int>()) == i174+7)); });\n\tis_heap(i175, i175+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i175, i175+7, std::greater<int>()) == i175+7)); });\n\tis_heap(i176, i176+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i176, i176+7, std::greater<int>()) == i176+7)); });\n\tis_heap(i177, i177+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i177, i177+7, std::greater<int>()) == i177+7)); });\n\tis_heap(i178, i178+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i178, i178+7, std::greater<int>()) == i178+7)); });\n\tis_heap(i179, i179+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i179, i179+7, std::greater<int>()) == i179+7)); });\n\tis_heap(i180, i180+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i180, i180+7, std::greater<int>()) == i180+7)); });\n\tis_heap(i181, i181+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i181, i181+7, std::greater<int>()) == i181+7)); });\n\tis_heap(i182, i182+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i182, i182+7, std::greater<int>()) == i182+7)); });\n\tis_heap(i183, i183+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i183, i183+7, std::greater<int>()) == i183+7)); });\n\tis_heap(i184, i184+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i184, i184+7, std::greater<int>()) == i184+7)); });\n\tis_heap(i185, i185+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i185, i185+7, std::greater<int>()) == i185+7)); });\n\tis_heap(i186, i186+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i186, i186+7, std::greater<int>()) == i186+7)); });\n\tis_heap(i187, i187+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i187, i187+7, std::greater<int>()) == i187+7)); });\n\tis_heap(i188, i188+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i188, i188+7, std::greater<int>()) == i188+7)); });\n\tis_heap(i189, i189+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i189, i189+7, std::greater<int>()) == i189+7)); });\n\tis_heap(i190, i190+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i190, i190+7, std::greater<int>()) == i190+7)); });\n\tis_heap(i191, i191+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i191, i191+7, std::greater<int>()) == i191+7)); });\n\tis_heap(i192, i192+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i192, i192+7, std::greater<int>()) == i192+7)); });\n\tis_heap(i193, i193+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i193, i193+7, std::greater<int>()) == i193+7)); });\n\tis_heap(i194, i194+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i194, i194+7, std::greater<int>()) == i194+7)); });\n\tis_heap(i195, i195+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i195, i195+7, std::greater<int>()) == i195+7)); });\n\tis_heap(i196, i196+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i196, i196+7, std::greater<int>()) == i196+7)); });\n\tis_heap(i197, i197+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i197, i197+7, std::greater<int>()) == i197+7)); });\n\tis_heap(i198, i198+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i198, i198+7, std::greater<int>()) == i198+7)); });\n\tis_heap(i199, i199+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i199, i199+7, std::greater<int>()) == i199+7)); });\n\tis_heap(i200, i200+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i200, i200+7, std::greater<int>()) == i200+7)); });\n\tis_heap(i201, i201+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i201, i201+7, std::greater<int>()) == i201+7)); });\n\tis_heap(i202, i202+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i202, i202+7, std::greater<int>()) == i202+7)); });\n\tis_heap(i203, i203+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i203, i203+7, std::greater<int>()) == i203+7)); });\n\tis_heap(i204, i204+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i204, i204+7, std::greater<int>()) == i204+7)); });\n\tis_heap(i205, i205+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i205, i205+7, std::greater<int>()) == i205+7)); });\n\tis_heap(i206, i206+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i206, i206+7, std::greater<int>()) == i206+7)); });\n\tis_heap(i207, i207+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i207, i207+7, std::greater<int>()) == i207+7)); });\n\tis_heap(i208, i208+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i208, i208+7, std::greater<int>()) == i208+7)); });\n\tis_heap(i209, i209+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i209, i209+7, std::greater<int>()) == i209+7)); });\n\tis_heap(i210, i210+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i210, i210+7, std::greater<int>()) == i210+7)); });\n\tis_heap(i211, i211+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i211, i211+7, std::greater<int>()) == i211+7)); });\n\tis_heap(i212, i212+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i212, i212+7, std::greater<int>()) == i212+7)); });\n\tis_heap(i213, i213+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i213, i213+7, std::greater<int>()) == i213+7)); });\n\tis_heap(i214, i214+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i214, i214+7, std::greater<int>()) == i214+7)); });\n\tis_heap(i215, i215+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i215, i215+7, std::greater<int>()) == i215+7)); });\n\tis_heap(i216, i216+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i216, i216+7, std::greater<int>()) == i216+7)); });\n\tis_heap(i217, i217+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i217, i217+7, std::greater<int>()) == i217+7)); });\n\tis_heap(i218, i218+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i218, i218+7, std::greater<int>()) == i218+7)); });\n\tis_heap(i219, i219+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i219, i219+7, std::greater<int>()) == i219+7)); });\n\tis_heap(i220, i220+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i220, i220+7, std::greater<int>()) == i220+7)); });\n\tis_heap(i221, i221+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i221, i221+7, std::greater<int>()) == i221+7)); });\n\tis_heap(i222, i222+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i222, i222+7, std::greater<int>()) == i222+7)); });\n\tis_heap(i223, i223+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i223, i223+7, std::greater<int>()) == i223+7)); });\n\tis_heap(i224, i224+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i224, i224+7, std::greater<int>()) == i224+7)); });\n\tis_heap(i225, i225+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i225, i225+7, std::greater<int>()) == i225+7)); });\n\tis_heap(i226, i226+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i226, i226+7, std::greater<int>()) == i226+7)); });\n\tis_heap(i227, i227+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i227, i227+7, std::greater<int>()) == i227+7)); });\n\tis_heap(i228, i228+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i228, i228+7, std::greater<int>()) == i228+7)); });\n\tis_heap(i229, i229+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i229, i229+7, std::greater<int>()) == i229+7)); });\n\tis_heap(i230, i230+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i230, i230+7, std::greater<int>()) == i230+7)); });\n\tis_heap(i231, i231+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i231, i231+7, std::greater<int>()) == i231+7)); });\n\tis_heap(i232, i232+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i232, i232+7, std::greater<int>()) == i232+7)); });\n\tis_heap(i233, i233+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i233, i233+7, std::greater<int>()) == i233+7)); });\n\tis_heap(i234, i234+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i234, i234+7, std::greater<int>()) == i234+7)); });\n\tis_heap(i235, i235+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i235, i235+7, std::greater<int>()) == i235+7)); });\n\tis_heap(i236, i236+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i236, i236+7, std::greater<int>()) == i236+7)); });\n\tis_heap(i237, i237+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i237, i237+7, std::greater<int>()) == i237+7)); });\n\tis_heap(i238, i238+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i238, i238+7, std::greater<int>()) == i238+7)); });\n\tis_heap(i239, i239+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i239, i239+7, std::greater<int>()) == i239+7)); });\n\tis_heap(i240, i240+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i240, i240+7, std::greater<int>()) == i240+7)); });\n\tis_heap(i241, i241+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i241, i241+7, std::greater<int>()) == i241+7)); });\n\tis_heap(i242, i242+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i242, i242+7, std::greater<int>()) == i242+7)); });\n\tis_heap(i243, i243+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i243, i243+7, std::greater<int>()) == i243+7)); });\n\tis_heap(i244, i244+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i244, i244+7, std::greater<int>()) == i244+7)); });\n\tis_heap(i245, i245+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i245, i245+7, std::greater<int>()) == i245+7)); });\n\tis_heap(i246, i246+7, std::greater<int>()).check([&](bool r){ CHECK(r == (std::is_heap_until(i246, i246+7, std::greater<int>()) == i246+7)); });\n#endif\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest();\n\ttest_comp();\n\n\t// Test projections:\n\tS i183[] = {S{0}, S{1}, S{1}, S{1}, S{1}, S{1}, S{1}};\n\tCHECK(stl2::is_heap(i183, i183+7, std::greater<int>(), &S::i));\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/is_heap1.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_1\n#include \"./is_heap.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_heap2.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_2\n#include \"./is_heap.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_heap3.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_3\n#include \"./is_heap.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_heap4.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_4\n#include \"./is_heap.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_heap_until.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n// Implementation based on the code in libc++\n//   http://http://libcxx.llvm.org/\n\n#include <stl2/detail/algorithm/is_heap_until.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nvoid test()\n{\n#ifdef IS_HEAP_UNTIL_1\n\tauto is_heap_until = make_testable_1([](auto&&... args) {\n\t\treturn ranges::is_heap_until(std::forward<decltype(args)>(args)...);\n\t});\n\tint i1[] = {0, 0};\n\tis_heap_until(i1, i1).check([&](int*r){CHECK(r == i1);});\n\n\tis_heap_until(i1, i1).check([&](int *r){ CHECK(r == i1); });\n\tis_heap_until(i1, i1+1).check([&](int *r){ CHECK(r == i1+1); });\n\tint i2[] = {0, 1};\n\tint i3[] = {1, 0};\n\tis_heap_until(i1, i1+2).check([&](int *r){ CHECK(r == i1+2); });\n\tis_heap_until(i2, i2+2).check([&](int *r){ CHECK(r == i2+1); });\n\tis_heap_until(i3, i3+2).check([&](int *r){ CHECK(r == i3+2); });\n\tint i4[] = {0, 0, 0};\n\tint i5[] = {0, 0, 1};\n\tint i6[] = {0, 1, 0};\n\tint i7[] = {0, 1, 1};\n\tint i8[] = {1, 0, 0};\n\tint i9[] = {1, 0, 1};\n\tint i10[] = {1, 1, 0};\n\tis_heap_until(i4, i4+3).check([&](int *r){ CHECK(r == i4+3); });\n\tis_heap_until(i5, i5+3).check([&](int *r){ CHECK(r == i5+2); });\n\tis_heap_until(i6, i6+3).check([&](int *r){ CHECK(r == i6+1); });\n\tis_heap_until(i7, i7+3).check([&](int *r){ CHECK(r == i7+1); });\n\tis_heap_until(i8, i8+3).check([&](int *r){ CHECK(r == i8+3); });\n\tis_heap_until(i9, i9+3).check([&](int *r){ CHECK(r == i9+3); });\n\tis_heap_until(i10, i10+3).check([&](int *r){ CHECK(r == i10+3); });\n\tint i11[] = {0, 0, 0, 0};\n\tint i12[] = {0, 0, 0, 1};\n\tint i13[] = {0, 0, 1, 0};\n\tint i14[] = {0, 0, 1, 1};\n\tint i15[] = {0, 1, 0, 0};\n\tint i16[] = {0, 1, 0, 1};\n\tint i17[] = {0, 1, 1, 0};\n\tint i18[] = {0, 1, 1, 1};\n\tint i19[] = {1, 0, 0, 0};\n\tint i20[] = {1, 0, 0, 1};\n\tint i21[] = {1, 0, 1, 0};\n\tint i22[] = {1, 0, 1, 1};\n\tint i23[] = {1, 1, 0, 0};\n\tint i24[] = {1, 1, 0, 1};\n\tint i25[] = {1, 1, 1, 0};\n\tis_heap_until(i11, i11+4).check([&](int *r){ CHECK(r == i11+4); });\n\tis_heap_until(i12, i12+4).check([&](int *r){ CHECK(r == i12+3); });\n\tis_heap_until(i13, i13+4).check([&](int *r){ CHECK(r == i13+2); });\n\tis_heap_until(i14, i14+4).check([&](int *r){ CHECK(r == i14+2); });\n\tis_heap_until(i15, i15+4).check([&](int *r){ CHECK(r == i15+1); });\n\tis_heap_until(i16, i16+4).check([&](int *r){ CHECK(r == i16+1); });\n\tis_heap_until(i17, i17+4).check([&](int *r){ CHECK(r == i17+1); });\n\tis_heap_until(i18, i18+4).check([&](int *r){ CHECK(r == i18+1); });\n\tis_heap_until(i19, i19+4).check([&](int *r){ CHECK(r == i19+4); });\n\tis_heap_until(i20, i20+4).check([&](int *r){ CHECK(r == i20+3); });\n\tis_heap_until(i21, i21+4).check([&](int *r){ CHECK(r == i21+4); });\n\tis_heap_until(i22, i22+4).check([&](int *r){ CHECK(r == i22+3); });\n\tis_heap_until(i23, i23+4).check([&](int *r){ CHECK(r == i23+4); });\n\tis_heap_until(i24, i24+4).check([&](int *r){ CHECK(r == i24+4); });\n\tis_heap_until(i25, i25+4).check([&](int *r){ CHECK(r == i25+4); });\n\tint i26[] = {0, 0, 0, 0, 0};\n\tint i27[] = {0, 0, 0, 0, 1};\n\tint i28[] = {0, 0, 0, 1, 0};\n\tint i29[] = {0, 0, 0, 1, 1};\n\tint i30[] = {0, 0, 1, 0, 0};\n\tint i31[] = {0, 0, 1, 0, 1};\n\tint i32[] = {0, 0, 1, 1, 0};\n\tint i33[] = {0, 0, 1, 1, 1};\n\tint i34[] = {0, 1, 0, 0, 0};\n\tint i35[] = {0, 1, 0, 0, 1};\n\tint i36[] = {0, 1, 0, 1, 0};\n\tint i37[] = {0, 1, 0, 1, 1};\n\tint i38[] = {0, 1, 1, 0, 0};\n\tint i39[] = {0, 1, 1, 0, 1};\n\tint i40[] = {0, 1, 1, 1, 0};\n\tint i41[] = {0, 1, 1, 1, 1};\n\tint i42[] = {1, 0, 0, 0, 0};\n\tint i43[] = {1, 0, 0, 0, 1};\n\tint i44[] = {1, 0, 0, 1, 0};\n\tint i45[] = {1, 0, 0, 1, 1};\n\tint i46[] = {1, 0, 1, 0, 0};\n\tint i47[] = {1, 0, 1, 0, 1};\n\tint i48[] = {1, 0, 1, 1, 0};\n\tint i49[] = {1, 0, 1, 1, 1};\n\tint i50[] = {1, 1, 0, 0, 0};\n\tint i51[] = {1, 1, 0, 0, 1};\n\tint i52[] = {1, 1, 0, 1, 0};\n\tint i53[] = {1, 1, 0, 1, 1};\n\tint i54[] = {1, 1, 1, 0, 0};\n\tint i55[] = {1, 1, 1, 0, 1};\n\tint i56[] = {1, 1, 1, 1, 0};\n\tis_heap_until(i26, i26+5).check([&](int *r){ CHECK(r == i26+5); });\n\tis_heap_until(i27, i27+5).check([&](int *r){ CHECK(r == i27+4); });\n\tis_heap_until(i28, i28+5).check([&](int *r){ CHECK(r == i28+3); });\n\tis_heap_until(i29, i29+5).check([&](int *r){ CHECK(r == i29+3); });\n\tis_heap_until(i30, i30+5).check([&](int *r){ CHECK(r == i30+2); });\n\tis_heap_until(i31, i31+5).check([&](int *r){ CHECK(r == i31+2); });\n\tis_heap_until(i32, i32+5).check([&](int *r){ CHECK(r == i32+2); });\n\tis_heap_until(i33, i33+5).check([&](int *r){ CHECK(r == i33+2); });\n\tis_heap_until(i34, i34+5).check([&](int *r){ CHECK(r == i34+1); });\n\tis_heap_until(i35, i35+5).check([&](int *r){ CHECK(r == i35+1); });\n\tis_heap_until(i36, i36+5).check([&](int *r){ CHECK(r == i36+1); });\n\tis_heap_until(i37, i37+5).check([&](int *r){ CHECK(r == i37+1); });\n\tis_heap_until(i38, i38+5).check([&](int *r){ CHECK(r == i38+1); });\n\tis_heap_until(i39, i39+5).check([&](int *r){ CHECK(r == i39+1); });\n\tis_heap_until(i40, i40+5).check([&](int *r){ CHECK(r == i40+1); });\n\tis_heap_until(i41, i41+5).check([&](int *r){ CHECK(r == i41+1); });\n\tis_heap_until(i42, i42+5).check([&](int *r){ CHECK(r == i42+5); });\n\tis_heap_until(i43, i43+5).check([&](int *r){ CHECK(r == i43+4); });\n\tis_heap_until(i44, i44+5).check([&](int *r){ CHECK(r == i44+3); });\n\tis_heap_until(i45, i45+5).check([&](int *r){ CHECK(r == i45+3); });\n\tis_heap_until(i46, i46+5).check([&](int *r){ CHECK(r == i46+5); });\n\tis_heap_until(i47, i47+5).check([&](int *r){ CHECK(r == i47+4); });\n\tis_heap_until(i48, i48+5).check([&](int *r){ CHECK(r == i48+3); });\n\tis_heap_until(i49, i49+5).check([&](int *r){ CHECK(r == i49+3); });\n\tis_heap_until(i50, i50+5).check([&](int *r){ CHECK(r == i50+5); });\n\tis_heap_until(i51, i51+5).check([&](int *r){ CHECK(r == i51+5); });\n\tis_heap_until(i52, i52+5).check([&](int *r){ CHECK(r == i52+5); });\n\tis_heap_until(i53, i53+5).check([&](int *r){ CHECK(r == i53+5); });\n\tis_heap_until(i54, i54+5).check([&](int *r){ CHECK(r == i54+5); });\n\tis_heap_until(i55, i55+5).check([&](int *r){ CHECK(r == i55+5); });\n\tis_heap_until(i56, i56+5).check([&](int *r){ CHECK(r == i56+5); });\n\tint i57[] = {0, 0, 0, 0, 0, 0};\n\tint i58[] = {0, 0, 0, 0, 0, 1};\n\tint i59[] = {0, 0, 0, 0, 1, 0};\n\tint i60[] = {0, 0, 0, 0, 1, 1};\n\tint i61[] = {0, 0, 0, 1, 0, 0};\n\tint i62[] = {0, 0, 0, 1, 0, 1};\n\tint i63[] = {0, 0, 0, 1, 1, 0};\n\tint i64[] = {0, 0, 0, 1, 1, 1};\n\tint i65[] = {0, 0, 1, 0, 0, 0};\n\tint i66[] = {0, 0, 1, 0, 0, 1};\n\tint i67[] = {0, 0, 1, 0, 1, 0};\n\tint i68[] = {0, 0, 1, 0, 1, 1};\n\tint i69[] = {0, 0, 1, 1, 0, 0};\n\tint i70[] = {0, 0, 1, 1, 0, 1};\n\tint i71[] = {0, 0, 1, 1, 1, 0};\n\tint i72[] = {0, 0, 1, 1, 1, 1};\n\tint i73[] = {0, 1, 0, 0, 0, 0};\n\tint i74[] = {0, 1, 0, 0, 0, 1};\n\tint i75[] = {0, 1, 0, 0, 1, 0};\n\tint i76[] = {0, 1, 0, 0, 1, 1};\n\tint i77[] = {0, 1, 0, 1, 0, 0};\n\tint i78[] = {0, 1, 0, 1, 0, 1};\n\tint i79[] = {0, 1, 0, 1, 1, 0};\n\tint i80[] = {0, 1, 0, 1, 1, 1};\n\tint i81[] = {0, 1, 1, 0, 0, 0};\n\tint i82[] = {0, 1, 1, 0, 0, 1};\n\tint i83[] = {0, 1, 1, 0, 1, 0};\n\tint i84[] = {0, 1, 1, 0, 1, 1};\n\tint i85[] = {0, 1, 1, 1, 0, 0};\n\tint i86[] = {0, 1, 1, 1, 0, 1};\n\tint i87[] = {0, 1, 1, 1, 1, 0};\n\tint i88[] = {0, 1, 1, 1, 1, 1};\n\tint i89[] = {1, 0, 0, 0, 0, 0};\n\tint i90[] = {1, 0, 0, 0, 0, 1};\n\tint i91[] = {1, 0, 0, 0, 1, 0};\n\tint i92[] = {1, 0, 0, 0, 1, 1};\n\tint i93[] = {1, 0, 0, 1, 0, 0};\n\tint i94[] = {1, 0, 0, 1, 0, 1};\n\tint i95[] = {1, 0, 0, 1, 1, 0};\n\tint i96[] = {1, 0, 0, 1, 1, 1};\n\tint i97[] = {1, 0, 1, 0, 0, 0};\n\tint i98[] = {1, 0, 1, 0, 0, 1};\n\tint i99[] = {1, 0, 1, 0, 1, 0};\n\tint i100[] = {1, 0, 1, 0, 1, 1};\n\tint i101[] = {1, 0, 1, 1, 0, 0};\n\tint i102[] = {1, 0, 1, 1, 0, 1};\n\tint i103[] = {1, 0, 1, 1, 1, 0};\n\tint i104[] = {1, 0, 1, 1, 1, 1};\n\tint i105[] = {1, 1, 0, 0, 0, 0};\n\tint i106[] = {1, 1, 0, 0, 0, 1};\n\tint i107[] = {1, 1, 0, 0, 1, 0};\n\tint i108[] = {1, 1, 0, 0, 1, 1};\n\tint i109[] = {1, 1, 0, 1, 0, 0};\n\tint i110[] = {1, 1, 0, 1, 0, 1};\n\tint i111[] = {1, 1, 0, 1, 1, 0};\n\tint i112[] = {1, 1, 0, 1, 1, 1};\n\tint i113[] = {1, 1, 1, 0, 0, 0};\n\tint i114[] = {1, 1, 1, 0, 0, 1};\n\tint i115[] = {1, 1, 1, 0, 1, 0};\n\tint i116[] = {1, 1, 1, 0, 1, 1};\n\tint i117[] = {1, 1, 1, 1, 0, 0};\n\tint i118[] = {1, 1, 1, 1, 0, 1};\n\tint i119[] = {1, 1, 1, 1, 1, 0};\n\tis_heap_until(i57, i57+6).check([&](int *r){ CHECK(r == i57+6); });\n\tis_heap_until(i58, i58+6).check([&](int *r){ CHECK(r == i58+5); });\n\tis_heap_until(i59, i59+6).check([&](int *r){ CHECK(r == i59+4); });\n\tis_heap_until(i60, i60+6).check([&](int *r){ CHECK(r == i60+4); });\n\tis_heap_until(i61, i61+6).check([&](int *r){ CHECK(r == i61+3); });\n\tis_heap_until(i62, i62+6).check([&](int *r){ CHECK(r == i62+3); });\n\tis_heap_until(i63, i63+6).check([&](int *r){ CHECK(r == i63+3); });\n\tis_heap_until(i64, i64+6).check([&](int *r){ CHECK(r == i64+3); });\n\tis_heap_until(i65, i65+6).check([&](int *r){ CHECK(r == i65+2); });\n\tis_heap_until(i66, i66+6).check([&](int *r){ CHECK(r == i66+2); });\n\tis_heap_until(i67, i67+6).check([&](int *r){ CHECK(r == i67+2); });\n\tis_heap_until(i68, i68+6).check([&](int *r){ CHECK(r == i68+2); });\n\tis_heap_until(i69, i69+6).check([&](int *r){ CHECK(r == i69+2); });\n\tis_heap_until(i70, i70+6).check([&](int *r){ CHECK(r == i70+2); });\n\tis_heap_until(i71, i71+6).check([&](int *r){ CHECK(r == i71+2); });\n\tis_heap_until(i72, i72+6).check([&](int *r){ CHECK(r == i72+2); });\n\tis_heap_until(i73, i73+6).check([&](int *r){ CHECK(r == i73+1); });\n\tis_heap_until(i74, i74+6).check([&](int *r){ CHECK(r == i74+1); });\n\tis_heap_until(i75, i75+6).check([&](int *r){ CHECK(r == i75+1); });\n\tis_heap_until(i76, i76+6).check([&](int *r){ CHECK(r == i76+1); });\n\tis_heap_until(i77, i77+6).check([&](int *r){ CHECK(r == i77+1); });\n\tis_heap_until(i78, i78+6).check([&](int *r){ CHECK(r == i78+1); });\n\tis_heap_until(i79, i79+6).check([&](int *r){ CHECK(r == i79+1); });\n\tis_heap_until(i80, i80+6).check([&](int *r){ CHECK(r == i80+1); });\n\tis_heap_until(i81, i81+6).check([&](int *r){ CHECK(r == i81+1); });\n\tis_heap_until(i82, i82+6).check([&](int *r){ CHECK(r == i82+1); });\n\tis_heap_until(i83, i83+6).check([&](int *r){ CHECK(r == i83+1); });\n\tis_heap_until(i84, i84+6).check([&](int *r){ CHECK(r == i84+1); });\n\tis_heap_until(i85, i85+6).check([&](int *r){ CHECK(r == i85+1); });\n\tis_heap_until(i86, i86+6).check([&](int *r){ CHECK(r == i86+1); });\n\tis_heap_until(i87, i87+6).check([&](int *r){ CHECK(r == i87+1); });\n\tis_heap_until(i88, i88+6).check([&](int *r){ CHECK(r == i88+1); });\n\tis_heap_until(i89, i89+6).check([&](int *r){ CHECK(r == i89+6); });\n\tis_heap_until(i90, i90+6).check([&](int *r){ CHECK(r == i90+5); });\n\tis_heap_until(i91, i91+6).check([&](int *r){ CHECK(r == i91+4); });\n\tis_heap_until(i92, i92+6).check([&](int *r){ CHECK(r == i92+4); });\n\tis_heap_until(i93, i93+6).check([&](int *r){ CHECK(r == i93+3); });\n\tis_heap_until(i94, i94+6).check([&](int *r){ CHECK(r == i94+3); });\n\tis_heap_until(i95, i95+6).check([&](int *r){ CHECK(r == i95+3); });\n\tis_heap_until(i96, i96+6).check([&](int *r){ CHECK(r == i96+3); });\n\tis_heap_until(i97, i97+6).check([&](int *r){ CHECK(r == i97+6); });\n\tis_heap_until(i98, i98+6).check([&](int *r){ CHECK(r == i98+6); });\n\tis_heap_until(i99, i99+6).check([&](int *r){ CHECK(r == i99+4); });\n\tis_heap_until(i100, i100+6).check([&](int *r){ CHECK(r == i100+4); });\n\tis_heap_until(i101, i101+6).check([&](int *r){ CHECK(r == i101+3); });\n\tis_heap_until(i102, i102+6).check([&](int *r){ CHECK(r == i102+3); });\n\tis_heap_until(i103, i103+6).check([&](int *r){ CHECK(r == i103+3); });\n\tis_heap_until(i104, i104+6).check([&](int *r){ CHECK(r == i104+3); });\n\tis_heap_until(i105, i105+6).check([&](int *r){ CHECK(r == i105+6); });\n\tis_heap_until(i106, i106+6).check([&](int *r){ CHECK(r == i106+5); });\n\tis_heap_until(i107, i107+6).check([&](int *r){ CHECK(r == i107+6); });\n\tis_heap_until(i108, i108+6).check([&](int *r){ CHECK(r == i108+5); });\n\tis_heap_until(i109, i109+6).check([&](int *r){ CHECK(r == i109+6); });\n\tis_heap_until(i110, i110+6).check([&](int *r){ CHECK(r == i110+5); });\n\tis_heap_until(i111, i111+6).check([&](int *r){ CHECK(r == i111+6); });\n\tis_heap_until(i112, i112+6).check([&](int *r){ CHECK(r == i112+5); });\n\tis_heap_until(i113, i113+6).check([&](int *r){ CHECK(r == i113+6); });\n\tis_heap_until(i114, i114+6).check([&](int *r){ CHECK(r == i114+6); });\n\tis_heap_until(i115, i115+6).check([&](int *r){ CHECK(r == i115+6); });\n\tis_heap_until(i116, i116+6).check([&](int *r){ CHECK(r == i116+6); });\n\tis_heap_until(i117, i117+6).check([&](int *r){ CHECK(r == i117+6); });\n\tis_heap_until(i118, i118+6).check([&](int *r){ CHECK(r == i118+6); });\n\tis_heap_until(i119, i119+6).check([&](int *r){ CHECK(r == i119+6); });\n#endif\n#ifdef IS_HEAP_UNTIL_2\n\tauto is_heap_until = make_testable_1([](auto&&... args) {\n\t\treturn ranges::is_heap_until(std::forward<decltype(args)>(args)...);\n\t});\n\tint i120[] = {0, 0, 0, 0, 0, 0, 0};\n\tint i121[] = {0, 0, 0, 0, 0, 0, 1};\n\tint i122[] = {0, 0, 0, 0, 0, 1, 0};\n\tint i123[] = {0, 0, 0, 0, 0, 1, 1};\n\tint i124[] = {0, 0, 0, 0, 1, 0, 0};\n\tint i125[] = {0, 0, 0, 0, 1, 0, 1};\n\tint i126[] = {0, 0, 0, 0, 1, 1, 0};\n\tint i127[] = {0, 0, 0, 0, 1, 1, 1};\n\tint i128[] = {0, 0, 0, 1, 0, 0, 0};\n\tint i129[] = {0, 0, 0, 1, 0, 0, 1};\n\tint i130[] = {0, 0, 0, 1, 0, 1, 0};\n\tint i131[] = {0, 0, 0, 1, 0, 1, 1};\n\tint i132[] = {0, 0, 0, 1, 1, 0, 0};\n\tint i133[] = {0, 0, 0, 1, 1, 0, 1};\n\tint i134[] = {0, 0, 0, 1, 1, 1, 0};\n\tint i135[] = {0, 0, 0, 1, 1, 1, 1};\n\tint i136[] = {0, 0, 1, 0, 0, 0, 0};\n\tint i137[] = {0, 0, 1, 0, 0, 0, 1};\n\tint i138[] = {0, 0, 1, 0, 0, 1, 0};\n\tint i139[] = {0, 0, 1, 0, 0, 1, 1};\n\tint i140[] = {0, 0, 1, 0, 1, 0, 0};\n\tint i141[] = {0, 0, 1, 0, 1, 0, 1};\n\tint i142[] = {0, 0, 1, 0, 1, 1, 0};\n\tint i143[] = {0, 0, 1, 0, 1, 1, 1};\n\tint i144[] = {0, 0, 1, 1, 0, 0, 0};\n\tint i145[] = {0, 0, 1, 1, 0, 0, 1};\n\tint i146[] = {0, 0, 1, 1, 0, 1, 0};\n\tint i147[] = {0, 0, 1, 1, 0, 1, 1};\n\tint i148[] = {0, 0, 1, 1, 1, 0, 0};\n\tint i149[] = {0, 0, 1, 1, 1, 0, 1};\n\tint i150[] = {0, 0, 1, 1, 1, 1, 0};\n\tint i151[] = {0, 0, 1, 1, 1, 1, 1};\n\tint i152[] = {0, 1, 0, 0, 0, 0, 0};\n\tint i153[] = {0, 1, 0, 0, 0, 0, 1};\n\tint i154[] = {0, 1, 0, 0, 0, 1, 0};\n\tint i155[] = {0, 1, 0, 0, 0, 1, 1};\n\tint i156[] = {0, 1, 0, 0, 1, 0, 0};\n\tint i157[] = {0, 1, 0, 0, 1, 0, 1};\n\tint i158[] = {0, 1, 0, 0, 1, 1, 0};\n\tint i159[] = {0, 1, 0, 0, 1, 1, 1};\n\tint i160[] = {0, 1, 0, 1, 0, 0, 0};\n\tint i161[] = {0, 1, 0, 1, 0, 0, 1};\n\tint i162[] = {0, 1, 0, 1, 0, 1, 0};\n\tint i163[] = {0, 1, 0, 1, 0, 1, 1};\n\tint i164[] = {0, 1, 0, 1, 1, 0, 0};\n\tint i165[] = {0, 1, 0, 1, 1, 0, 1};\n\tint i166[] = {0, 1, 0, 1, 1, 1, 0};\n\tint i167[] = {0, 1, 0, 1, 1, 1, 1};\n\tint i168[] = {0, 1, 1, 0, 0, 0, 0};\n\tint i169[] = {0, 1, 1, 0, 0, 0, 1};\n\tint i170[] = {0, 1, 1, 0, 0, 1, 0};\n\tint i171[] = {0, 1, 1, 0, 0, 1, 1};\n\tint i172[] = {0, 1, 1, 0, 1, 0, 0};\n\tint i173[] = {0, 1, 1, 0, 1, 0, 1};\n\tint i174[] = {0, 1, 1, 0, 1, 1, 0};\n\tint i175[] = {0, 1, 1, 0, 1, 1, 1};\n\tint i176[] = {0, 1, 1, 1, 0, 0, 0};\n\tint i177[] = {0, 1, 1, 1, 0, 0, 1};\n\tint i178[] = {0, 1, 1, 1, 0, 1, 0};\n\tint i179[] = {0, 1, 1, 1, 0, 1, 1};\n\tint i180[] = {0, 1, 1, 1, 1, 0, 0};\n\tint i181[] = {0, 1, 1, 1, 1, 0, 1};\n\tint i182[] = {0, 1, 1, 1, 1, 1, 0};\n\tint i183[] = {0, 1, 1, 1, 1, 1, 1};\n\tint i184[] = {1, 0, 0, 0, 0, 0, 0};\n\tint i185[] = {1, 0, 0, 0, 0, 0, 1};\n\tint i186[] = {1, 0, 0, 0, 0, 1, 0};\n\tint i187[] = {1, 0, 0, 0, 0, 1, 1};\n\tint i188[] = {1, 0, 0, 0, 1, 0, 0};\n\tint i189[] = {1, 0, 0, 0, 1, 0, 1};\n\tint i190[] = {1, 0, 0, 0, 1, 1, 0};\n\tint i191[] = {1, 0, 0, 0, 1, 1, 1};\n\tint i192[] = {1, 0, 0, 1, 0, 0, 0};\n\tint i193[] = {1, 0, 0, 1, 0, 0, 1};\n\tint i194[] = {1, 0, 0, 1, 0, 1, 0};\n\tint i195[] = {1, 0, 0, 1, 0, 1, 1};\n\tint i196[] = {1, 0, 0, 1, 1, 0, 0};\n\tint i197[] = {1, 0, 0, 1, 1, 0, 1};\n\tint i198[] = {1, 0, 0, 1, 1, 1, 0};\n\tint i199[] = {1, 0, 0, 1, 1, 1, 1};\n\tint i200[] = {1, 0, 1, 0, 0, 0, 0};\n\tint i201[] = {1, 0, 1, 0, 0, 0, 1};\n\tint i202[] = {1, 0, 1, 0, 0, 1, 0};\n\tint i203[] = {1, 0, 1, 0, 0, 1, 1};\n\tint i204[] = {1, 0, 1, 0, 1, 0, 0};\n\tint i205[] = {1, 0, 1, 0, 1, 0, 1};\n\tint i206[] = {1, 0, 1, 0, 1, 1, 0};\n\tint i207[] = {1, 0, 1, 0, 1, 1, 1};\n\tint i208[] = {1, 0, 1, 1, 0, 0, 0};\n\tint i209[] = {1, 0, 1, 1, 0, 0, 1};\n\tint i210[] = {1, 0, 1, 1, 0, 1, 0};\n\tint i211[] = {1, 0, 1, 1, 0, 1, 1};\n\tint i212[] = {1, 0, 1, 1, 1, 0, 0};\n\tint i213[] = {1, 0, 1, 1, 1, 0, 1};\n\tint i214[] = {1, 0, 1, 1, 1, 1, 0};\n\tint i215[] = {1, 0, 1, 1, 1, 1, 1};\n\tint i216[] = {1, 1, 0, 0, 0, 0, 0};\n\tint i217[] = {1, 1, 0, 0, 0, 0, 1};\n\tint i218[] = {1, 1, 0, 0, 0, 1, 0};\n\tint i219[] = {1, 1, 0, 0, 0, 1, 1};\n\tint i220[] = {1, 1, 0, 0, 1, 0, 0};\n\tint i221[] = {1, 1, 0, 0, 1, 0, 1};\n\tint i222[] = {1, 1, 0, 0, 1, 1, 0};\n\tint i223[] = {1, 1, 0, 0, 1, 1, 1};\n\tint i224[] = {1, 1, 0, 1, 0, 0, 0};\n\tint i225[] = {1, 1, 0, 1, 0, 0, 1};\n\tint i226[] = {1, 1, 0, 1, 0, 1, 0};\n\tint i227[] = {1, 1, 0, 1, 0, 1, 1};\n\tint i228[] = {1, 1, 0, 1, 1, 0, 0};\n\tint i229[] = {1, 1, 0, 1, 1, 0, 1};\n\tint i230[] = {1, 1, 0, 1, 1, 1, 0};\n\tint i231[] = {1, 1, 0, 1, 1, 1, 1};\n\tint i232[] = {1, 1, 1, 0, 0, 0, 0};\n\tint i233[] = {1, 1, 1, 0, 0, 0, 1};\n\tint i234[] = {1, 1, 1, 0, 0, 1, 0};\n\tint i235[] = {1, 1, 1, 0, 0, 1, 1};\n\tint i236[] = {1, 1, 1, 0, 1, 0, 0};\n\tint i237[] = {1, 1, 1, 0, 1, 0, 1};\n\tint i238[] = {1, 1, 1, 0, 1, 1, 0};\n\tint i239[] = {1, 1, 1, 0, 1, 1, 1};\n\tint i240[] = {1, 1, 1, 1, 0, 0, 0};\n\tint i241[] = {1, 1, 1, 1, 0, 0, 1};\n\tint i242[] = {1, 1, 1, 1, 0, 1, 0};\n\tint i243[] = {1, 1, 1, 1, 0, 1, 1};\n\tint i244[] = {1, 1, 1, 1, 1, 0, 0};\n\tint i245[] = {1, 1, 1, 1, 1, 0, 1};\n\tint i246[] = {1, 1, 1, 1, 1, 1, 0};\n\tis_heap_until(i120, i120+7).check([&](int *r){ CHECK(r == i120+7); });\n\tis_heap_until(i121, i121+7).check([&](int *r){ CHECK(r == i121+6); });\n\tis_heap_until(i122, i122+7).check([&](int *r){ CHECK(r == i122+5); });\n\tis_heap_until(i123, i123+7).check([&](int *r){ CHECK(r == i123+5); });\n\tis_heap_until(i124, i124+7).check([&](int *r){ CHECK(r == i124+4); });\n\tis_heap_until(i125, i125+7).check([&](int *r){ CHECK(r == i125+4); });\n\tis_heap_until(i126, i126+7).check([&](int *r){ CHECK(r == i126+4); });\n\tis_heap_until(i127, i127+7).check([&](int *r){ CHECK(r == i127+4); });\n\tis_heap_until(i128, i128+7).check([&](int *r){ CHECK(r == i128+3); });\n\tis_heap_until(i129, i129+7).check([&](int *r){ CHECK(r == i129+3); });\n\tis_heap_until(i130, i130+7).check([&](int *r){ CHECK(r == i130+3); });\n\tis_heap_until(i131, i131+7).check([&](int *r){ CHECK(r == i131+3); });\n\tis_heap_until(i132, i132+7).check([&](int *r){ CHECK(r == i132+3); });\n\tis_heap_until(i133, i133+7).check([&](int *r){ CHECK(r == i133+3); });\n\tis_heap_until(i134, i134+7).check([&](int *r){ CHECK(r == i134+3); });\n\tis_heap_until(i135, i135+7).check([&](int *r){ CHECK(r == i135+3); });\n\tis_heap_until(i136, i136+7).check([&](int *r){ CHECK(r == i136+2); });\n\tis_heap_until(i137, i137+7).check([&](int *r){ CHECK(r == i137+2); });\n\tis_heap_until(i138, i138+7).check([&](int *r){ CHECK(r == i138+2); });\n\tis_heap_until(i139, i139+7).check([&](int *r){ CHECK(r == i139+2); });\n\tis_heap_until(i140, i140+7).check([&](int *r){ CHECK(r == i140+2); });\n\tis_heap_until(i141, i141+7).check([&](int *r){ CHECK(r == i141+2); });\n\tis_heap_until(i142, i142+7).check([&](int *r){ CHECK(r == i142+2); });\n\tis_heap_until(i143, i143+7).check([&](int *r){ CHECK(r == i143+2); });\n\tis_heap_until(i144, i144+7).check([&](int *r){ CHECK(r == i144+2); });\n\tis_heap_until(i145, i145+7).check([&](int *r){ CHECK(r == i145+2); });\n\tis_heap_until(i146, i146+7).check([&](int *r){ CHECK(r == i146+2); });\n\tis_heap_until(i147, i147+7).check([&](int *r){ CHECK(r == i147+2); });\n\tis_heap_until(i148, i148+7).check([&](int *r){ CHECK(r == i148+2); });\n\tis_heap_until(i149, i149+7).check([&](int *r){ CHECK(r == i149+2); });\n\tis_heap_until(i150, i150+7).check([&](int *r){ CHECK(r == i150+2); });\n\tis_heap_until(i151, i151+7).check([&](int *r){ CHECK(r == i151+2); });\n\tis_heap_until(i152, i152+7).check([&](int *r){ CHECK(r == i152+1); });\n\tis_heap_until(i153, i153+7).check([&](int *r){ CHECK(r == i153+1); });\n\tis_heap_until(i154, i154+7).check([&](int *r){ CHECK(r == i154+1); });\n\tis_heap_until(i155, i155+7).check([&](int *r){ CHECK(r == i155+1); });\n\tis_heap_until(i156, i156+7).check([&](int *r){ CHECK(r == i156+1); });\n\tis_heap_until(i157, i157+7).check([&](int *r){ CHECK(r == i157+1); });\n\tis_heap_until(i158, i158+7).check([&](int *r){ CHECK(r == i158+1); });\n\tis_heap_until(i159, i159+7).check([&](int *r){ CHECK(r == i159+1); });\n\tis_heap_until(i160, i160+7).check([&](int *r){ CHECK(r == i160+1); });\n\tis_heap_until(i161, i161+7).check([&](int *r){ CHECK(r == i161+1); });\n\tis_heap_until(i162, i162+7).check([&](int *r){ CHECK(r == i162+1); });\n\tis_heap_until(i163, i163+7).check([&](int *r){ CHECK(r == i163+1); });\n\tis_heap_until(i164, i164+7).check([&](int *r){ CHECK(r == i164+1); });\n\tis_heap_until(i165, i165+7).check([&](int *r){ CHECK(r == i165+1); });\n\tis_heap_until(i166, i166+7).check([&](int *r){ CHECK(r == i166+1); });\n\tis_heap_until(i167, i167+7).check([&](int *r){ CHECK(r == i167+1); });\n\tis_heap_until(i168, i168+7).check([&](int *r){ CHECK(r == i168+1); });\n\tis_heap_until(i169, i169+7).check([&](int *r){ CHECK(r == i169+1); });\n\tis_heap_until(i170, i170+7).check([&](int *r){ CHECK(r == i170+1); });\n\tis_heap_until(i171, i171+7).check([&](int *r){ CHECK(r == i171+1); });\n\tis_heap_until(i172, i172+7).check([&](int *r){ CHECK(r == i172+1); });\n\tis_heap_until(i173, i173+7).check([&](int *r){ CHECK(r == i173+1); });\n\tis_heap_until(i174, i174+7).check([&](int *r){ CHECK(r == i174+1); });\n\tis_heap_until(i175, i175+7).check([&](int *r){ CHECK(r == i175+1); });\n\tis_heap_until(i176, i176+7).check([&](int *r){ CHECK(r == i176+1); });\n\tis_heap_until(i177, i177+7).check([&](int *r){ CHECK(r == i177+1); });\n\tis_heap_until(i178, i178+7).check([&](int *r){ CHECK(r == i178+1); });\n\tis_heap_until(i179, i179+7).check([&](int *r){ CHECK(r == i179+1); });\n\tis_heap_until(i180, i180+7).check([&](int *r){ CHECK(r == i180+1); });\n\tis_heap_until(i181, i181+7).check([&](int *r){ CHECK(r == i181+1); });\n\tis_heap_until(i182, i182+7).check([&](int *r){ CHECK(r == i182+1); });\n\tis_heap_until(i183, i183+7).check([&](int *r){ CHECK(r == i183+1); });\n\tis_heap_until(i184, i184+7).check([&](int *r){ CHECK(r == i184+7); });\n\tis_heap_until(i185, i185+7).check([&](int *r){ CHECK(r == i185+6); });\n\tis_heap_until(i186, i186+7).check([&](int *r){ CHECK(r == i186+5); });\n\tis_heap_until(i187, i187+7).check([&](int *r){ CHECK(r == i187+5); });\n\tis_heap_until(i188, i188+7).check([&](int *r){ CHECK(r == i188+4); });\n\tis_heap_until(i189, i189+7).check([&](int *r){ CHECK(r == i189+4); });\n\tis_heap_until(i190, i190+7).check([&](int *r){ CHECK(r == i190+4); });\n\tis_heap_until(i191, i191+7).check([&](int *r){ CHECK(r == i191+4); });\n\tis_heap_until(i192, i192+7).check([&](int *r){ CHECK(r == i192+3); });\n\tis_heap_until(i193, i193+7).check([&](int *r){ CHECK(r == i193+3); });\n\tis_heap_until(i194, i194+7).check([&](int *r){ CHECK(r == i194+3); });\n\tis_heap_until(i195, i195+7).check([&](int *r){ CHECK(r == i195+3); });\n\tis_heap_until(i196, i196+7).check([&](int *r){ CHECK(r == i196+3); });\n\tis_heap_until(i197, i197+7).check([&](int *r){ CHECK(r == i197+3); });\n\tis_heap_until(i198, i198+7).check([&](int *r){ CHECK(r == i198+3); });\n\tis_heap_until(i199, i199+7).check([&](int *r){ CHECK(r == i199+3); });\n\tis_heap_until(i200, i200+7).check([&](int *r){ CHECK(r == i200+7); });\n\tis_heap_until(i201, i201+7).check([&](int *r){ CHECK(r == i201+7); });\n\tis_heap_until(i202, i202+7).check([&](int *r){ CHECK(r == i202+7); });\n\tis_heap_until(i203, i203+7).check([&](int *r){ CHECK(r == i203+7); });\n\tis_heap_until(i204, i204+7).check([&](int *r){ CHECK(r == i204+4); });\n\tis_heap_until(i205, i205+7).check([&](int *r){ CHECK(r == i205+4); });\n\tis_heap_until(i206, i206+7).check([&](int *r){ CHECK(r == i206+4); });\n\tis_heap_until(i207, i207+7).check([&](int *r){ CHECK(r == i207+4); });\n\tis_heap_until(i208, i208+7).check([&](int *r){ CHECK(r == i208+3); });\n\tis_heap_until(i209, i209+7).check([&](int *r){ CHECK(r == i209+3); });\n\tis_heap_until(i210, i210+7).check([&](int *r){ CHECK(r == i210+3); });\n\tis_heap_until(i211, i211+7).check([&](int *r){ CHECK(r == i211+3); });\n\tis_heap_until(i212, i212+7).check([&](int *r){ CHECK(r == i212+3); });\n\tis_heap_until(i213, i213+7).check([&](int *r){ CHECK(r == i213+3); });\n\tis_heap_until(i214, i214+7).check([&](int *r){ CHECK(r == i214+3); });\n\tis_heap_until(i215, i215+7).check([&](int *r){ CHECK(r == i215+3); });\n\tis_heap_until(i216, i216+7).check([&](int *r){ CHECK(r == i216+7); });\n\tis_heap_until(i217, i217+7).check([&](int *r){ CHECK(r == i217+6); });\n\tis_heap_until(i218, i218+7).check([&](int *r){ CHECK(r == i218+5); });\n\tis_heap_until(i219, i219+7).check([&](int *r){ CHECK(r == i219+5); });\n\tis_heap_until(i220, i220+7).check([&](int *r){ CHECK(r == i220+7); });\n\tis_heap_until(i221, i221+7).check([&](int *r){ CHECK(r == i221+6); });\n\tis_heap_until(i222, i222+7).check([&](int *r){ CHECK(r == i222+5); });\n\tis_heap_until(i223, i223+7).check([&](int *r){ CHECK(r == i223+5); });\n\tis_heap_until(i224, i224+7).check([&](int *r){ CHECK(r == i224+7); });\n\tis_heap_until(i225, i225+7).check([&](int *r){ CHECK(r == i225+6); });\n\tis_heap_until(i226, i226+7).check([&](int *r){ CHECK(r == i226+5); });\n\tis_heap_until(i227, i227+7).check([&](int *r){ CHECK(r == i227+5); });\n\tis_heap_until(i228, i228+7).check([&](int *r){ CHECK(r == i228+7); });\n\tis_heap_until(i229, i229+7).check([&](int *r){ CHECK(r == i229+6); });\n\tis_heap_until(i230, i230+7).check([&](int *r){ CHECK(r == i230+5); });\n\tis_heap_until(i231, i231+7).check([&](int *r){ CHECK(r == i231+5); });\n\tis_heap_until(i232, i232+7).check([&](int *r){ CHECK(r == i232+7); });\n\tis_heap_until(i233, i233+7).check([&](int *r){ CHECK(r == i233+7); });\n\tis_heap_until(i234, i234+7).check([&](int *r){ CHECK(r == i234+7); });\n\tis_heap_until(i235, i235+7).check([&](int *r){ CHECK(r == i235+7); });\n\tis_heap_until(i236, i236+7).check([&](int *r){ CHECK(r == i236+7); });\n\tis_heap_until(i237, i237+7).check([&](int *r){ CHECK(r == i237+7); });\n\tis_heap_until(i238, i238+7).check([&](int *r){ CHECK(r == i238+7); });\n\tis_heap_until(i239, i239+7).check([&](int *r){ CHECK(r == i239+7); });\n\tis_heap_until(i240, i240+7).check([&](int *r){ CHECK(r == i240+7); });\n\tis_heap_until(i241, i241+7).check([&](int *r){ CHECK(r == i241+7); });\n\tis_heap_until(i242, i242+7).check([&](int *r){ CHECK(r == i242+7); });\n\tis_heap_until(i243, i243+7).check([&](int *r){ CHECK(r == i243+7); });\n\tis_heap_until(i244, i244+7).check([&](int *r){ CHECK(r == i244+7); });\n\tis_heap_until(i245, i245+7).check([&](int *r){ CHECK(r == i245+7); });\n\tis_heap_until(i246, i246+7).check([&](int *r){ CHECK(r == i246+7); });\n#endif\n}\n\nvoid test_pred()\n{\n#ifdef IS_HEAP_UNTIL_3\n\tauto is_heap_until = make_testable_1([](auto&&... args) {\n\t\treturn ranges::is_heap_until(std::forward<decltype(args)>(args)...);\n\t});\n\tint i1[] = {0, 0};\n\tis_heap_until(i1, i1, std::greater<int>()).check([&](int *r){ CHECK(r == i1); });\n\tis_heap_until(i1, i1+1, std::greater<int>()).check([&](int *r){ CHECK(r == i1+1); });\n\tint i2[] = {0, 1};\n\tint i3[] = {1, 0};\n\tis_heap_until(i1, i1+2, std::greater<int>()).check([&](int *r){ CHECK(r == i1+2); });\n\tis_heap_until(i2, i2+2, std::greater<int>()).check([&](int *r){ CHECK(r == i2+2); });\n\tis_heap_until(i3, i3+2, std::greater<int>()).check([&](int *r){ CHECK(r == i3+1); });\n\tint i4[] = {0, 0, 0};\n\tint i5[] = {0, 0, 1};\n\tint i6[] = {0, 1, 0};\n\tint i7[] = {0, 1, 1};\n\tint i8[] = {1, 0, 0};\n\tint i9[] = {1, 0, 1};\n\tint i10[] = {1, 1, 0};\n\tis_heap_until(i4, i4+3, std::greater<int>()).check([&](int *r){ CHECK(r == i4+3); });\n\tis_heap_until(i5, i5+3, std::greater<int>()).check([&](int *r){ CHECK(r == i5+3); });\n\tis_heap_until(i6, i6+3, std::greater<int>()).check([&](int *r){ CHECK(r == i6+3); });\n\tis_heap_until(i7, i7+3, std::greater<int>()).check([&](int *r){ CHECK(r == i7+3); });\n\tis_heap_until(i8, i8+3, std::greater<int>()).check([&](int *r){ CHECK(r == i8+1); });\n\tis_heap_until(i9, i9+3, std::greater<int>()).check([&](int *r){ CHECK(r == i9+1); });\n\tis_heap_until(i10, i10+3, std::greater<int>()).check([&](int *r){ CHECK(r == i10+2); });\n\tint i11[] = {0, 0, 0, 0};\n\tint i12[] = {0, 0, 0, 1};\n\tint i13[] = {0, 0, 1, 0};\n\tint i14[] = {0, 0, 1, 1};\n\tint i15[] = {0, 1, 0, 0};\n\tint i16[] = {0, 1, 0, 1};\n\tint i17[] = {0, 1, 1, 0};\n\tint i18[] = {0, 1, 1, 1};\n\tint i19[] = {1, 0, 0, 0};\n\tint i20[] = {1, 0, 0, 1};\n\tint i21[] = {1, 0, 1, 0};\n\tint i22[] = {1, 0, 1, 1};\n\tint i23[] = {1, 1, 0, 0};\n\tint i24[] = {1, 1, 0, 1};\n\tint i25[] = {1, 1, 1, 0};\n\tis_heap_until(i11, i11+4, std::greater<int>()).check([&](int *r){ CHECK(r == i11+4); });\n\tis_heap_until(i12, i12+4, std::greater<int>()).check([&](int *r){ CHECK(r == i12+4); });\n\tis_heap_until(i13, i13+4, std::greater<int>()).check([&](int *r){ CHECK(r == i13+4); });\n\tis_heap_until(i14, i14+4, std::greater<int>()).check([&](int *r){ CHECK(r == i14+4); });\n\tis_heap_until(i15, i15+4, std::greater<int>()).check([&](int *r){ CHECK(r == i15+3); });\n\tis_heap_until(i16, i16+4, std::greater<int>()).check([&](int *r){ CHECK(r == i16+4); });\n\tis_heap_until(i17, i17+4, std::greater<int>()).check([&](int *r){ CHECK(r == i17+3); });\n\tis_heap_until(i18, i18+4, std::greater<int>()).check([&](int *r){ CHECK(r == i18+4); });\n\tis_heap_until(i19, i19+4, std::greater<int>()).check([&](int *r){ CHECK(r == i19+1); });\n\tis_heap_until(i20, i20+4, std::greater<int>()).check([&](int *r){ CHECK(r == i20+1); });\n\tis_heap_until(i21, i21+4, std::greater<int>()).check([&](int *r){ CHECK(r == i21+1); });\n\tis_heap_until(i22, i22+4, std::greater<int>()).check([&](int *r){ CHECK(r == i22+1); });\n\tis_heap_until(i23, i23+4, std::greater<int>()).check([&](int *r){ CHECK(r == i23+2); });\n\tis_heap_until(i24, i24+4, std::greater<int>()).check([&](int *r){ CHECK(r == i24+2); });\n\tis_heap_until(i25, i25+4, std::greater<int>()).check([&](int *r){ CHECK(r == i25+3); });\n\tint i26[] = {0, 0, 0, 0, 0};\n\tint i27[] = {0, 0, 0, 0, 1};\n\tint i28[] = {0, 0, 0, 1, 0};\n\tint i29[] = {0, 0, 0, 1, 1};\n\tint i30[] = {0, 0, 1, 0, 0};\n\tint i31[] = {0, 0, 1, 0, 1};\n\tint i32[] = {0, 0, 1, 1, 0};\n\tint i33[] = {0, 0, 1, 1, 1};\n\tint i34[] = {0, 1, 0, 0, 0};\n\tint i35[] = {0, 1, 0, 0, 1};\n\tint i36[] = {0, 1, 0, 1, 0};\n\tint i37[] = {0, 1, 0, 1, 1};\n\tint i38[] = {0, 1, 1, 0, 0};\n\tint i39[] = {0, 1, 1, 0, 1};\n\tint i40[] = {0, 1, 1, 1, 0};\n\tint i41[] = {0, 1, 1, 1, 1};\n\tint i42[] = {1, 0, 0, 0, 0};\n\tint i43[] = {1, 0, 0, 0, 1};\n\tint i44[] = {1, 0, 0, 1, 0};\n\tint i45[] = {1, 0, 0, 1, 1};\n\tint i46[] = {1, 0, 1, 0, 0};\n\tint i47[] = {1, 0, 1, 0, 1};\n\tint i48[] = {1, 0, 1, 1, 0};\n\tint i49[] = {1, 0, 1, 1, 1};\n\tint i50[] = {1, 1, 0, 0, 0};\n\tint i51[] = {1, 1, 0, 0, 1};\n\tint i52[] = {1, 1, 0, 1, 0};\n\tint i53[] = {1, 1, 0, 1, 1};\n\tint i54[] = {1, 1, 1, 0, 0};\n\tint i55[] = {1, 1, 1, 0, 1};\n\tint i56[] = {1, 1, 1, 1, 0};\n\tis_heap_until(i26, i26+5, std::greater<int>()).check([&](int *r){ CHECK(r == i26+5); });\n\tis_heap_until(i27, i27+5, std::greater<int>()).check([&](int *r){ CHECK(r == i27+5); });\n\tis_heap_until(i28, i28+5, std::greater<int>()).check([&](int *r){ CHECK(r == i28+5); });\n\tis_heap_until(i29, i29+5, std::greater<int>()).check([&](int *r){ CHECK(r == i29+5); });\n\tis_heap_until(i30, i30+5, std::greater<int>()).check([&](int *r){ CHECK(r == i30+5); });\n\tis_heap_until(i31, i31+5, std::greater<int>()).check([&](int *r){ CHECK(r == i31+5); });\n\tis_heap_until(i32, i32+5, std::greater<int>()).check([&](int *r){ CHECK(r == i32+5); });\n\tis_heap_until(i33, i33+5, std::greater<int>()).check([&](int *r){ CHECK(r == i33+5); });\n\tis_heap_until(i34, i34+5, std::greater<int>()).check([&](int *r){ CHECK(r == i34+3); });\n\tis_heap_until(i35, i35+5, std::greater<int>()).check([&](int *r){ CHECK(r == i35+3); });\n\tis_heap_until(i36, i36+5, std::greater<int>()).check([&](int *r){ CHECK(r == i36+4); });\n\tis_heap_until(i37, i37+5, std::greater<int>()).check([&](int *r){ CHECK(r == i37+5); });\n\tis_heap_until(i38, i38+5, std::greater<int>()).check([&](int *r){ CHECK(r == i38+3); });\n\tis_heap_until(i39, i39+5, std::greater<int>()).check([&](int *r){ CHECK(r == i39+3); });\n\tis_heap_until(i40, i40+5, std::greater<int>()).check([&](int *r){ CHECK(r == i40+4); });\n\tis_heap_until(i41, i41+5, std::greater<int>()).check([&](int *r){ CHECK(r == i41+5); });\n\tis_heap_until(i42, i42+5, std::greater<int>()).check([&](int *r){ CHECK(r == i42+1); });\n\tis_heap_until(i43, i43+5, std::greater<int>()).check([&](int *r){ CHECK(r == i43+1); });\n\tis_heap_until(i44, i44+5, std::greater<int>()).check([&](int *r){ CHECK(r == i44+1); });\n\tis_heap_until(i45, i45+5, std::greater<int>()).check([&](int *r){ CHECK(r == i45+1); });\n\tis_heap_until(i46, i46+5, std::greater<int>()).check([&](int *r){ CHECK(r == i46+1); });\n\tis_heap_until(i47, i47+5, std::greater<int>()).check([&](int *r){ CHECK(r == i47+1); });\n\tis_heap_until(i48, i48+5, std::greater<int>()).check([&](int *r){ CHECK(r == i48+1); });\n\tis_heap_until(i49, i49+5, std::greater<int>()).check([&](int *r){ CHECK(r == i49+1); });\n\tis_heap_until(i50, i50+5, std::greater<int>()).check([&](int *r){ CHECK(r == i50+2); });\n\tis_heap_until(i51, i51+5, std::greater<int>()).check([&](int *r){ CHECK(r == i51+2); });\n\tis_heap_until(i52, i52+5, std::greater<int>()).check([&](int *r){ CHECK(r == i52+2); });\n\tis_heap_until(i53, i53+5, std::greater<int>()).check([&](int *r){ CHECK(r == i53+2); });\n\tis_heap_until(i54, i54+5, std::greater<int>()).check([&](int *r){ CHECK(r == i54+3); });\n\tis_heap_until(i55, i55+5, std::greater<int>()).check([&](int *r){ CHECK(r == i55+3); });\n\tis_heap_until(i56, i56+5, std::greater<int>()).check([&](int *r){ CHECK(r == i56+4); });\n\tint i57[] = {0, 0, 0, 0, 0, 0};\n\tint i58[] = {0, 0, 0, 0, 0, 1};\n\tint i59[] = {0, 0, 0, 0, 1, 0};\n\tint i60[] = {0, 0, 0, 0, 1, 1};\n\tint i61[] = {0, 0, 0, 1, 0, 0};\n\tint i62[] = {0, 0, 0, 1, 0, 1};\n\tint i63[] = {0, 0, 0, 1, 1, 0};\n\tint i64[] = {0, 0, 0, 1, 1, 1};\n\tint i65[] = {0, 0, 1, 0, 0, 0};\n\tint i66[] = {0, 0, 1, 0, 0, 1};\n\tint i67[] = {0, 0, 1, 0, 1, 0};\n\tint i68[] = {0, 0, 1, 0, 1, 1};\n\tint i69[] = {0, 0, 1, 1, 0, 0};\n\tint i70[] = {0, 0, 1, 1, 0, 1};\n\tint i71[] = {0, 0, 1, 1, 1, 0};\n\tint i72[] = {0, 0, 1, 1, 1, 1};\n\tint i73[] = {0, 1, 0, 0, 0, 0};\n\tint i74[] = {0, 1, 0, 0, 0, 1};\n\tint i75[] = {0, 1, 0, 0, 1, 0};\n\tint i76[] = {0, 1, 0, 0, 1, 1};\n\tint i77[] = {0, 1, 0, 1, 0, 0};\n\tint i78[] = {0, 1, 0, 1, 0, 1};\n\tint i79[] = {0, 1, 0, 1, 1, 0};\n\tint i80[] = {0, 1, 0, 1, 1, 1};\n\tint i81[] = {0, 1, 1, 0, 0, 0};\n\tint i82[] = {0, 1, 1, 0, 0, 1};\n\tint i83[] = {0, 1, 1, 0, 1, 0};\n\tint i84[] = {0, 1, 1, 0, 1, 1};\n\tint i85[] = {0, 1, 1, 1, 0, 0};\n\tint i86[] = {0, 1, 1, 1, 0, 1};\n\tint i87[] = {0, 1, 1, 1, 1, 0};\n\tint i88[] = {0, 1, 1, 1, 1, 1};\n\tint i89[] = {1, 0, 0, 0, 0, 0};\n\tint i90[] = {1, 0, 0, 0, 0, 1};\n\tint i91[] = {1, 0, 0, 0, 1, 0};\n\tint i92[] = {1, 0, 0, 0, 1, 1};\n\tint i93[] = {1, 0, 0, 1, 0, 0};\n\tint i94[] = {1, 0, 0, 1, 0, 1};\n\tint i95[] = {1, 0, 0, 1, 1, 0};\n\tint i96[] = {1, 0, 0, 1, 1, 1};\n\tint i97[] = {1, 0, 1, 0, 0, 0};\n\tint i98[] = {1, 0, 1, 0, 0, 1};\n\tint i99[] = {1, 0, 1, 0, 1, 0};\n\tint i100[] = {1, 0, 1, 0, 1, 1};\n\tint i101[] = {1, 0, 1, 1, 0, 0};\n\tint i102[] = {1, 0, 1, 1, 0, 1};\n\tint i103[] = {1, 0, 1, 1, 1, 0};\n\tint i104[] = {1, 0, 1, 1, 1, 1};\n\tint i105[] = {1, 1, 0, 0, 0, 0};\n\tint i106[] = {1, 1, 0, 0, 0, 1};\n\tint i107[] = {1, 1, 0, 0, 1, 0};\n\tint i108[] = {1, 1, 0, 0, 1, 1};\n\tint i109[] = {1, 1, 0, 1, 0, 0};\n\tint i110[] = {1, 1, 0, 1, 0, 1};\n\tint i111[] = {1, 1, 0, 1, 1, 0};\n\tint i112[] = {1, 1, 0, 1, 1, 1};\n\tint i113[] = {1, 1, 1, 0, 0, 0};\n\tint i114[] = {1, 1, 1, 0, 0, 1};\n\tint i115[] = {1, 1, 1, 0, 1, 0};\n\tint i116[] = {1, 1, 1, 0, 1, 1};\n\tint i117[] = {1, 1, 1, 1, 0, 0};\n\tint i118[] = {1, 1, 1, 1, 0, 1};\n\tint i119[] = {1, 1, 1, 1, 1, 0};\n\tis_heap_until(i57, i57+6, std::greater<int>()).check([&](int *r){ CHECK(r == i57+6); });\n\tis_heap_until(i58, i58+6, std::greater<int>()).check([&](int *r){ CHECK(r == i58+6); });\n\tis_heap_until(i59, i59+6, std::greater<int>()).check([&](int *r){ CHECK(r == i59+6); });\n\tis_heap_until(i60, i60+6, std::greater<int>()).check([&](int *r){ CHECK(r == i60+6); });\n\tis_heap_until(i61, i61+6, std::greater<int>()).check([&](int *r){ CHECK(r == i61+6); });\n\tis_heap_until(i62, i62+6, std::greater<int>()).check([&](int *r){ CHECK(r == i62+6); });\n\tis_heap_until(i63, i63+6, std::greater<int>()).check([&](int *r){ CHECK(r == i63+6); });\n\tis_heap_until(i64, i64+6, std::greater<int>()).check([&](int *r){ CHECK(r == i64+6); });\n\tis_heap_until(i65, i65+6, std::greater<int>()).check([&](int *r){ CHECK(r == i65+5); });\n\tis_heap_until(i66, i66+6, std::greater<int>()).check([&](int *r){ CHECK(r == i66+6); });\n\tis_heap_until(i67, i67+6, std::greater<int>()).check([&](int *r){ CHECK(r == i67+5); });\n\tis_heap_until(i68, i68+6, std::greater<int>()).check([&](int *r){ CHECK(r == i68+6); });\n\tis_heap_until(i69, i69+6, std::greater<int>()).check([&](int *r){ CHECK(r == i69+5); });\n\tis_heap_until(i70, i70+6, std::greater<int>()).check([&](int *r){ CHECK(r == i70+6); });\n\tis_heap_until(i71, i71+6, std::greater<int>()).check([&](int *r){ CHECK(r == i71+5); });\n\tis_heap_until(i72, i72+6, std::greater<int>()).check([&](int *r){ CHECK(r == i72+6); });\n\tis_heap_until(i73, i73+6, std::greater<int>()).check([&](int *r){ CHECK(r == i73+3); });\n\tis_heap_until(i74, i74+6, std::greater<int>()).check([&](int *r){ CHECK(r == i74+3); });\n\tis_heap_until(i75, i75+6, std::greater<int>()).check([&](int *r){ CHECK(r == i75+3); });\n\tis_heap_until(i76, i76+6, std::greater<int>()).check([&](int *r){ CHECK(r == i76+3); });\n\tis_heap_until(i77, i77+6, std::greater<int>()).check([&](int *r){ CHECK(r == i77+4); });\n\tis_heap_until(i78, i78+6, std::greater<int>()).check([&](int *r){ CHECK(r == i78+4); });\n\tis_heap_until(i79, i79+6, std::greater<int>()).check([&](int *r){ CHECK(r == i79+6); });\n\tis_heap_until(i80, i80+6, std::greater<int>()).check([&](int *r){ CHECK(r == i80+6); });\n\tis_heap_until(i81, i81+6, std::greater<int>()).check([&](int *r){ CHECK(r == i81+3); });\n\tis_heap_until(i82, i82+6, std::greater<int>()).check([&](int *r){ CHECK(r == i82+3); });\n\tis_heap_until(i83, i83+6, std::greater<int>()).check([&](int *r){ CHECK(r == i83+3); });\n\tis_heap_until(i84, i84+6, std::greater<int>()).check([&](int *r){ CHECK(r == i84+3); });\n\tis_heap_until(i85, i85+6, std::greater<int>()).check([&](int *r){ CHECK(r == i85+4); });\n\tis_heap_until(i86, i86+6, std::greater<int>()).check([&](int *r){ CHECK(r == i86+4); });\n\tis_heap_until(i87, i87+6, std::greater<int>()).check([&](int *r){ CHECK(r == i87+5); });\n\tis_heap_until(i88, i88+6, std::greater<int>()).check([&](int *r){ CHECK(r == i88+6); });\n\tis_heap_until(i89, i89+6, std::greater<int>()).check([&](int *r){ CHECK(r == i89+1); });\n\tis_heap_until(i90, i90+6, std::greater<int>()).check([&](int *r){ CHECK(r == i90+1); });\n\tis_heap_until(i91, i91+6, std::greater<int>()).check([&](int *r){ CHECK(r == i91+1); });\n\tis_heap_until(i92, i92+6, std::greater<int>()).check([&](int *r){ CHECK(r == i92+1); });\n\tis_heap_until(i93, i93+6, std::greater<int>()).check([&](int *r){ CHECK(r == i93+1); });\n\tis_heap_until(i94, i94+6, std::greater<int>()).check([&](int *r){ CHECK(r == i94+1); });\n\tis_heap_until(i95, i95+6, std::greater<int>()).check([&](int *r){ CHECK(r == i95+1); });\n\tis_heap_until(i96, i96+6, std::greater<int>()).check([&](int *r){ CHECK(r == i96+1); });\n\tis_heap_until(i97, i97+6, std::greater<int>()).check([&](int *r){ CHECK(r == i97+1); });\n\tis_heap_until(i98, i98+6, std::greater<int>()).check([&](int *r){ CHECK(r == i98+1); });\n\tis_heap_until(i99, i99+6, std::greater<int>()).check([&](int *r){ CHECK(r == i99+1); });\n\tis_heap_until(i100, i100+6, std::greater<int>()).check([&](int *r){ CHECK(r == i100+1); });\n\tis_heap_until(i101, i101+6, std::greater<int>()).check([&](int *r){ CHECK(r == i101+1); });\n\tis_heap_until(i102, i102+6, std::greater<int>()).check([&](int *r){ CHECK(r == i102+1); });\n\tis_heap_until(i103, i103+6, std::greater<int>()).check([&](int *r){ CHECK(r == i103+1); });\n\tis_heap_until(i104, i104+6, std::greater<int>()).check([&](int *r){ CHECK(r == i104+1); });\n\tis_heap_until(i105, i105+6, std::greater<int>()).check([&](int *r){ CHECK(r == i105+2); });\n\tis_heap_until(i106, i106+6, std::greater<int>()).check([&](int *r){ CHECK(r == i106+2); });\n\tis_heap_until(i107, i107+6, std::greater<int>()).check([&](int *r){ CHECK(r == i107+2); });\n\tis_heap_until(i108, i108+6, std::greater<int>()).check([&](int *r){ CHECK(r == i108+2); });\n\tis_heap_until(i109, i109+6, std::greater<int>()).check([&](int *r){ CHECK(r == i109+2); });\n\tis_heap_until(i110, i110+6, std::greater<int>()).check([&](int *r){ CHECK(r == i110+2); });\n\tis_heap_until(i111, i111+6, std::greater<int>()).check([&](int *r){ CHECK(r == i111+2); });\n\tis_heap_until(i112, i112+6, std::greater<int>()).check([&](int *r){ CHECK(r == i112+2); });\n\tis_heap_until(i113, i113+6, std::greater<int>()).check([&](int *r){ CHECK(r == i113+3); });\n\tis_heap_until(i114, i114+6, std::greater<int>()).check([&](int *r){ CHECK(r == i114+3); });\n\tis_heap_until(i115, i115+6, std::greater<int>()).check([&](int *r){ CHECK(r == i115+3); });\n\tis_heap_until(i116, i116+6, std::greater<int>()).check([&](int *r){ CHECK(r == i116+3); });\n\tis_heap_until(i117, i117+6, std::greater<int>()).check([&](int *r){ CHECK(r == i117+4); });\n\tis_heap_until(i118, i118+6, std::greater<int>()).check([&](int *r){ CHECK(r == i118+4); });\n\tis_heap_until(i119, i119+6, std::greater<int>()).check([&](int *r){ CHECK(r == i119+5); });\n#endif\n#ifdef IS_HEAP_UNTIL_4\n\tauto is_heap_until = make_testable_1([](auto&&... args) {\n\t\treturn ranges::is_heap_until(std::forward<decltype(args)>(args)...);\n\t});\n\tint i120[] = {0, 0, 0, 0, 0, 0, 0};\n\tint i121[] = {0, 0, 0, 0, 0, 0, 1};\n\tint i122[] = {0, 0, 0, 0, 0, 1, 0};\n\tint i123[] = {0, 0, 0, 0, 0, 1, 1};\n\tint i124[] = {0, 0, 0, 0, 1, 0, 0};\n\tint i125[] = {0, 0, 0, 0, 1, 0, 1};\n\tint i126[] = {0, 0, 0, 0, 1, 1, 0};\n\tint i127[] = {0, 0, 0, 0, 1, 1, 1};\n\tint i128[] = {0, 0, 0, 1, 0, 0, 0};\n\tint i129[] = {0, 0, 0, 1, 0, 0, 1};\n\tint i130[] = {0, 0, 0, 1, 0, 1, 0};\n\tint i131[] = {0, 0, 0, 1, 0, 1, 1};\n\tint i132[] = {0, 0, 0, 1, 1, 0, 0};\n\tint i133[] = {0, 0, 0, 1, 1, 0, 1};\n\tint i134[] = {0, 0, 0, 1, 1, 1, 0};\n\tint i135[] = {0, 0, 0, 1, 1, 1, 1};\n\tint i136[] = {0, 0, 1, 0, 0, 0, 0};\n\tint i137[] = {0, 0, 1, 0, 0, 0, 1};\n\tint i138[] = {0, 0, 1, 0, 0, 1, 0};\n\tint i139[] = {0, 0, 1, 0, 0, 1, 1};\n\tint i140[] = {0, 0, 1, 0, 1, 0, 0};\n\tint i141[] = {0, 0, 1, 0, 1, 0, 1};\n\tint i142[] = {0, 0, 1, 0, 1, 1, 0};\n\tint i143[] = {0, 0, 1, 0, 1, 1, 1};\n\tint i144[] = {0, 0, 1, 1, 0, 0, 0};\n\tint i145[] = {0, 0, 1, 1, 0, 0, 1};\n\tint i146[] = {0, 0, 1, 1, 0, 1, 0};\n\tint i147[] = {0, 0, 1, 1, 0, 1, 1};\n\tint i148[] = {0, 0, 1, 1, 1, 0, 0};\n\tint i149[] = {0, 0, 1, 1, 1, 0, 1};\n\tint i150[] = {0, 0, 1, 1, 1, 1, 0};\n\tint i151[] = {0, 0, 1, 1, 1, 1, 1};\n\tint i152[] = {0, 1, 0, 0, 0, 0, 0};\n\tint i153[] = {0, 1, 0, 0, 0, 0, 1};\n\tint i154[] = {0, 1, 0, 0, 0, 1, 0};\n\tint i155[] = {0, 1, 0, 0, 0, 1, 1};\n\tint i156[] = {0, 1, 0, 0, 1, 0, 0};\n\tint i157[] = {0, 1, 0, 0, 1, 0, 1};\n\tint i158[] = {0, 1, 0, 0, 1, 1, 0};\n\tint i159[] = {0, 1, 0, 0, 1, 1, 1};\n\tint i160[] = {0, 1, 0, 1, 0, 0, 0};\n\tint i161[] = {0, 1, 0, 1, 0, 0, 1};\n\tint i162[] = {0, 1, 0, 1, 0, 1, 0};\n\tint i163[] = {0, 1, 0, 1, 0, 1, 1};\n\tint i164[] = {0, 1, 0, 1, 1, 0, 0};\n\tint i165[] = {0, 1, 0, 1, 1, 0, 1};\n\tint i166[] = {0, 1, 0, 1, 1, 1, 0};\n\tint i167[] = {0, 1, 0, 1, 1, 1, 1};\n\tint i168[] = {0, 1, 1, 0, 0, 0, 0};\n\tint i169[] = {0, 1, 1, 0, 0, 0, 1};\n\tint i170[] = {0, 1, 1, 0, 0, 1, 0};\n\tint i171[] = {0, 1, 1, 0, 0, 1, 1};\n\tint i172[] = {0, 1, 1, 0, 1, 0, 0};\n\tint i173[] = {0, 1, 1, 0, 1, 0, 1};\n\tint i174[] = {0, 1, 1, 0, 1, 1, 0};\n\tint i175[] = {0, 1, 1, 0, 1, 1, 1};\n\tint i176[] = {0, 1, 1, 1, 0, 0, 0};\n\tint i177[] = {0, 1, 1, 1, 0, 0, 1};\n\tint i178[] = {0, 1, 1, 1, 0, 1, 0};\n\tint i179[] = {0, 1, 1, 1, 0, 1, 1};\n\tint i180[] = {0, 1, 1, 1, 1, 0, 0};\n\tint i181[] = {0, 1, 1, 1, 1, 0, 1};\n\tint i182[] = {0, 1, 1, 1, 1, 1, 0};\n\tint i183[] = {0, 1, 1, 1, 1, 1, 1};\n\tint i184[] = {1, 0, 0, 0, 0, 0, 0};\n\tint i185[] = {1, 0, 0, 0, 0, 0, 1};\n\tint i186[] = {1, 0, 0, 0, 0, 1, 0};\n\tint i187[] = {1, 0, 0, 0, 0, 1, 1};\n\tint i188[] = {1, 0, 0, 0, 1, 0, 0};\n\tint i189[] = {1, 0, 0, 0, 1, 0, 1};\n\tint i190[] = {1, 0, 0, 0, 1, 1, 0};\n\tint i191[] = {1, 0, 0, 0, 1, 1, 1};\n\tint i192[] = {1, 0, 0, 1, 0, 0, 0};\n\tint i193[] = {1, 0, 0, 1, 0, 0, 1};\n\tint i194[] = {1, 0, 0, 1, 0, 1, 0};\n\tint i195[] = {1, 0, 0, 1, 0, 1, 1};\n\tint i196[] = {1, 0, 0, 1, 1, 0, 0};\n\tint i197[] = {1, 0, 0, 1, 1, 0, 1};\n\tint i198[] = {1, 0, 0, 1, 1, 1, 0};\n\tint i199[] = {1, 0, 0, 1, 1, 1, 1};\n\tint i200[] = {1, 0, 1, 0, 0, 0, 0};\n\tint i201[] = {1, 0, 1, 0, 0, 0, 1};\n\tint i202[] = {1, 0, 1, 0, 0, 1, 0};\n\tint i203[] = {1, 0, 1, 0, 0, 1, 1};\n\tint i204[] = {1, 0, 1, 0, 1, 0, 0};\n\tint i205[] = {1, 0, 1, 0, 1, 0, 1};\n\tint i206[] = {1, 0, 1, 0, 1, 1, 0};\n\tint i207[] = {1, 0, 1, 0, 1, 1, 1};\n\tint i208[] = {1, 0, 1, 1, 0, 0, 0};\n\tint i209[] = {1, 0, 1, 1, 0, 0, 1};\n\tint i210[] = {1, 0, 1, 1, 0, 1, 0};\n\tint i211[] = {1, 0, 1, 1, 0, 1, 1};\n\tint i212[] = {1, 0, 1, 1, 1, 0, 0};\n\tint i213[] = {1, 0, 1, 1, 1, 0, 1};\n\tint i214[] = {1, 0, 1, 1, 1, 1, 0};\n\tint i215[] = {1, 0, 1, 1, 1, 1, 1};\n\tint i216[] = {1, 1, 0, 0, 0, 0, 0};\n\tint i217[] = {1, 1, 0, 0, 0, 0, 1};\n\tint i218[] = {1, 1, 0, 0, 0, 1, 0};\n\tint i219[] = {1, 1, 0, 0, 0, 1, 1};\n\tint i220[] = {1, 1, 0, 0, 1, 0, 0};\n\tint i221[] = {1, 1, 0, 0, 1, 0, 1};\n\tint i222[] = {1, 1, 0, 0, 1, 1, 0};\n\tint i223[] = {1, 1, 0, 0, 1, 1, 1};\n\tint i224[] = {1, 1, 0, 1, 0, 0, 0};\n\tint i225[] = {1, 1, 0, 1, 0, 0, 1};\n\tint i226[] = {1, 1, 0, 1, 0, 1, 0};\n\tint i227[] = {1, 1, 0, 1, 0, 1, 1};\n\tint i228[] = {1, 1, 0, 1, 1, 0, 0};\n\tint i229[] = {1, 1, 0, 1, 1, 0, 1};\n\tint i230[] = {1, 1, 0, 1, 1, 1, 0};\n\tint i231[] = {1, 1, 0, 1, 1, 1, 1};\n\tint i232[] = {1, 1, 1, 0, 0, 0, 0};\n\tint i233[] = {1, 1, 1, 0, 0, 0, 1};\n\tint i234[] = {1, 1, 1, 0, 0, 1, 0};\n\tint i235[] = {1, 1, 1, 0, 0, 1, 1};\n\tint i236[] = {1, 1, 1, 0, 1, 0, 0};\n\tint i237[] = {1, 1, 1, 0, 1, 0, 1};\n\tint i238[] = {1, 1, 1, 0, 1, 1, 0};\n\tint i239[] = {1, 1, 1, 0, 1, 1, 1};\n\tint i240[] = {1, 1, 1, 1, 0, 0, 0};\n\tint i241[] = {1, 1, 1, 1, 0, 0, 1};\n\tint i242[] = {1, 1, 1, 1, 0, 1, 0};\n\tint i243[] = {1, 1, 1, 1, 0, 1, 1};\n\tint i244[] = {1, 1, 1, 1, 1, 0, 0};\n\tint i245[] = {1, 1, 1, 1, 1, 0, 1};\n\tint i246[] = {1, 1, 1, 1, 1, 1, 0};\n\tis_heap_until(i120, i120+7, std::greater<int>()).check([&](int *r){ CHECK(r == i120+7); });\n\tis_heap_until(i121, i121+7, std::greater<int>()).check([&](int *r){ CHECK(r == i121+7); });\n\tis_heap_until(i122, i122+7, std::greater<int>()).check([&](int *r){ CHECK(r == i122+7); });\n\tis_heap_until(i123, i123+7, std::greater<int>()).check([&](int *r){ CHECK(r == i123+7); });\n\tis_heap_until(i124, i124+7, std::greater<int>()).check([&](int *r){ CHECK(r == i124+7); });\n\tis_heap_until(i125, i125+7, std::greater<int>()).check([&](int *r){ CHECK(r == i125+7); });\n\tis_heap_until(i126, i126+7, std::greater<int>()).check([&](int *r){ CHECK(r == i126+7); });\n\tis_heap_until(i127, i127+7, std::greater<int>()).check([&](int *r){ CHECK(r == i127+7); });\n\tis_heap_until(i128, i128+7, std::greater<int>()).check([&](int *r){ CHECK(r == i128+7); });\n\tis_heap_until(i129, i129+7, std::greater<int>()).check([&](int *r){ CHECK(r == i129+7); });\n\tis_heap_until(i130, i130+7, std::greater<int>()).check([&](int *r){ CHECK(r == i130+7); });\n\tis_heap_until(i131, i131+7, std::greater<int>()).check([&](int *r){ CHECK(r == i131+7); });\n\tis_heap_until(i132, i132+7, std::greater<int>()).check([&](int *r){ CHECK(r == i132+7); });\n\tis_heap_until(i133, i133+7, std::greater<int>()).check([&](int *r){ CHECK(r == i133+7); });\n\tis_heap_until(i134, i134+7, std::greater<int>()).check([&](int *r){ CHECK(r == i134+7); });\n\tis_heap_until(i135, i135+7, std::greater<int>()).check([&](int *r){ CHECK(r == i135+7); });\n\tis_heap_until(i136, i136+7, std::greater<int>()).check([&](int *r){ CHECK(r == i136+5); });\n\tis_heap_until(i137, i137+7, std::greater<int>()).check([&](int *r){ CHECK(r == i137+5); });\n\tis_heap_until(i138, i138+7, std::greater<int>()).check([&](int *r){ CHECK(r == i138+6); });\n\tis_heap_until(i139, i139+7, std::greater<int>()).check([&](int *r){ CHECK(r == i139+7); });\n\tis_heap_until(i140, i140+7, std::greater<int>()).check([&](int *r){ CHECK(r == i140+5); });\n\tis_heap_until(i141, i141+7, std::greater<int>()).check([&](int *r){ CHECK(r == i141+5); });\n\tis_heap_until(i142, i142+7, std::greater<int>()).check([&](int *r){ CHECK(r == i142+6); });\n\tis_heap_until(i143, i143+7, std::greater<int>()).check([&](int *r){ CHECK(r == i143+7); });\n\tis_heap_until(i144, i144+7, std::greater<int>()).check([&](int *r){ CHECK(r == i144+5); });\n\tis_heap_until(i145, i145+7, std::greater<int>()).check([&](int *r){ CHECK(r == i145+5); });\n\tis_heap_until(i146, i146+7, std::greater<int>()).check([&](int *r){ CHECK(r == i146+6); });\n\tis_heap_until(i147, i147+7, std::greater<int>()).check([&](int *r){ CHECK(r == i147+7); });\n\tis_heap_until(i148, i148+7, std::greater<int>()).check([&](int *r){ CHECK(r == i148+5); });\n\tis_heap_until(i149, i149+7, std::greater<int>()).check([&](int *r){ CHECK(r == i149+5); });\n\tis_heap_until(i150, i150+7, std::greater<int>()).check([&](int *r){ CHECK(r == i150+6); });\n\tis_heap_until(i151, i151+7, std::greater<int>()).check([&](int *r){ CHECK(r == i151+7); });\n\tis_heap_until(i152, i152+7, std::greater<int>()).check([&](int *r){ CHECK(r == i152+3); });\n\tis_heap_until(i153, i153+7, std::greater<int>()).check([&](int *r){ CHECK(r == i153+3); });\n\tis_heap_until(i154, i154+7, std::greater<int>()).check([&](int *r){ CHECK(r == i154+3); });\n\tis_heap_until(i155, i155+7, std::greater<int>()).check([&](int *r){ CHECK(r == i155+3); });\n\tis_heap_until(i156, i156+7, std::greater<int>()).check([&](int *r){ CHECK(r == i156+3); });\n\tis_heap_until(i157, i157+7, std::greater<int>()).check([&](int *r){ CHECK(r == i157+3); });\n\tis_heap_until(i158, i158+7, std::greater<int>()).check([&](int *r){ CHECK(r == i158+3); });\n\tis_heap_until(i159, i159+7, std::greater<int>()).check([&](int *r){ CHECK(r == i159+3); });\n\tis_heap_until(i160, i160+7, std::greater<int>()).check([&](int *r){ CHECK(r == i160+4); });\n\tis_heap_until(i161, i161+7, std::greater<int>()).check([&](int *r){ CHECK(r == i161+4); });\n\tis_heap_until(i162, i162+7, std::greater<int>()).check([&](int *r){ CHECK(r == i162+4); });\n\tis_heap_until(i163, i163+7, std::greater<int>()).check([&](int *r){ CHECK(r == i163+4); });\n\tis_heap_until(i164, i164+7, std::greater<int>()).check([&](int *r){ CHECK(r == i164+7); });\n\tis_heap_until(i165, i165+7, std::greater<int>()).check([&](int *r){ CHECK(r == i165+7); });\n\tis_heap_until(i166, i166+7, std::greater<int>()).check([&](int *r){ CHECK(r == i166+7); });\n\tis_heap_until(i167, i167+7, std::greater<int>()).check([&](int *r){ CHECK(r == i167+7); });\n\tis_heap_until(i168, i168+7, std::greater<int>()).check([&](int *r){ CHECK(r == i168+3); });\n\tis_heap_until(i169, i169+7, std::greater<int>()).check([&](int *r){ CHECK(r == i169+3); });\n\tis_heap_until(i170, i170+7, std::greater<int>()).check([&](int *r){ CHECK(r == i170+3); });\n\tis_heap_until(i171, i171+7, std::greater<int>()).check([&](int *r){ CHECK(r == i171+3); });\n\tis_heap_until(i172, i172+7, std::greater<int>()).check([&](int *r){ CHECK(r == i172+3); });\n\tis_heap_until(i173, i173+7, std::greater<int>()).check([&](int *r){ CHECK(r == i173+3); });\n\tis_heap_until(i174, i174+7, std::greater<int>()).check([&](int *r){ CHECK(r == i174+3); });\n\tis_heap_until(i175, i175+7, std::greater<int>()).check([&](int *r){ CHECK(r == i175+3); });\n\tis_heap_until(i176, i176+7, std::greater<int>()).check([&](int *r){ CHECK(r == i176+4); });\n\tis_heap_until(i177, i177+7, std::greater<int>()).check([&](int *r){ CHECK(r == i177+4); });\n\tis_heap_until(i178, i178+7, std::greater<int>()).check([&](int *r){ CHECK(r == i178+4); });\n\tis_heap_until(i179, i179+7, std::greater<int>()).check([&](int *r){ CHECK(r == i179+4); });\n\tis_heap_until(i180, i180+7, std::greater<int>()).check([&](int *r){ CHECK(r == i180+5); });\n\tis_heap_until(i181, i181+7, std::greater<int>()).check([&](int *r){ CHECK(r == i181+5); });\n\tis_heap_until(i182, i182+7, std::greater<int>()).check([&](int *r){ CHECK(r == i182+6); });\n\tis_heap_until(i183, i183+7, std::greater<int>()).check([&](int *r){ CHECK(r == i183+7); });\n\tis_heap_until(i184, i184+7, std::greater<int>()).check([&](int *r){ CHECK(r == i184+1); });\n\tis_heap_until(i185, i185+7, std::greater<int>()).check([&](int *r){ CHECK(r == i185+1); });\n\tis_heap_until(i186, i186+7, std::greater<int>()).check([&](int *r){ CHECK(r == i186+1); });\n\tis_heap_until(i187, i187+7, std::greater<int>()).check([&](int *r){ CHECK(r == i187+1); });\n\tis_heap_until(i188, i188+7, std::greater<int>()).check([&](int *r){ CHECK(r == i188+1); });\n\tis_heap_until(i189, i189+7, std::greater<int>()).check([&](int *r){ CHECK(r == i189+1); });\n\tis_heap_until(i190, i190+7, std::greater<int>()).check([&](int *r){ CHECK(r == i190+1); });\n\tis_heap_until(i191, i191+7, std::greater<int>()).check([&](int *r){ CHECK(r == i191+1); });\n\tis_heap_until(i192, i192+7, std::greater<int>()).check([&](int *r){ CHECK(r == i192+1); });\n\tis_heap_until(i193, i193+7, std::greater<int>()).check([&](int *r){ CHECK(r == i193+1); });\n\tis_heap_until(i194, i194+7, std::greater<int>()).check([&](int *r){ CHECK(r == i194+1); });\n\tis_heap_until(i195, i195+7, std::greater<int>()).check([&](int *r){ CHECK(r == i195+1); });\n\tis_heap_until(i196, i196+7, std::greater<int>()).check([&](int *r){ CHECK(r == i196+1); });\n\tis_heap_until(i197, i197+7, std::greater<int>()).check([&](int *r){ CHECK(r == i197+1); });\n\tis_heap_until(i198, i198+7, std::greater<int>()).check([&](int *r){ CHECK(r == i198+1); });\n\tis_heap_until(i199, i199+7, std::greater<int>()).check([&](int *r){ CHECK(r == i199+1); });\n\tis_heap_until(i200, i200+7, std::greater<int>()).check([&](int *r){ CHECK(r == i200+1); });\n\tis_heap_until(i201, i201+7, std::greater<int>()).check([&](int *r){ CHECK(r == i201+1); });\n\tis_heap_until(i202, i202+7, std::greater<int>()).check([&](int *r){ CHECK(r == i202+1); });\n\tis_heap_until(i203, i203+7, std::greater<int>()).check([&](int *r){ CHECK(r == i203+1); });\n\tis_heap_until(i204, i204+7, std::greater<int>()).check([&](int *r){ CHECK(r == i204+1); });\n\tis_heap_until(i205, i205+7, std::greater<int>()).check([&](int *r){ CHECK(r == i205+1); });\n\tis_heap_until(i206, i206+7, std::greater<int>()).check([&](int *r){ CHECK(r == i206+1); });\n\tis_heap_until(i207, i207+7, std::greater<int>()).check([&](int *r){ CHECK(r == i207+1); });\n\tis_heap_until(i208, i208+7, std::greater<int>()).check([&](int *r){ CHECK(r == i208+1); });\n\tis_heap_until(i209, i209+7, std::greater<int>()).check([&](int *r){ CHECK(r == i209+1); });\n\tis_heap_until(i210, i210+7, std::greater<int>()).check([&](int *r){ CHECK(r == i210+1); });\n\tis_heap_until(i211, i211+7, std::greater<int>()).check([&](int *r){ CHECK(r == i211+1); });\n\tis_heap_until(i212, i212+7, std::greater<int>()).check([&](int *r){ CHECK(r == i212+1); });\n\tis_heap_until(i213, i213+7, std::greater<int>()).check([&](int *r){ CHECK(r == i213+1); });\n\tis_heap_until(i214, i214+7, std::greater<int>()).check([&](int *r){ CHECK(r == i214+1); });\n\tis_heap_until(i215, i215+7, std::greater<int>()).check([&](int *r){ CHECK(r == i215+1); });\n\tis_heap_until(i216, i216+7, std::greater<int>()).check([&](int *r){ CHECK(r == i216+2); });\n\tis_heap_until(i217, i217+7, std::greater<int>()).check([&](int *r){ CHECK(r == i217+2); });\n\tis_heap_until(i218, i218+7, std::greater<int>()).check([&](int *r){ CHECK(r == i218+2); });\n\tis_heap_until(i219, i219+7, std::greater<int>()).check([&](int *r){ CHECK(r == i219+2); });\n\tis_heap_until(i220, i220+7, std::greater<int>()).check([&](int *r){ CHECK(r == i220+2); });\n\tis_heap_until(i221, i221+7, std::greater<int>()).check([&](int *r){ CHECK(r == i221+2); });\n\tis_heap_until(i222, i222+7, std::greater<int>()).check([&](int *r){ CHECK(r == i222+2); });\n\tis_heap_until(i223, i223+7, std::greater<int>()).check([&](int *r){ CHECK(r == i223+2); });\n\tis_heap_until(i224, i224+7, std::greater<int>()).check([&](int *r){ CHECK(r == i224+2); });\n\tis_heap_until(i225, i225+7, std::greater<int>()).check([&](int *r){ CHECK(r == i225+2); });\n\tis_heap_until(i226, i226+7, std::greater<int>()).check([&](int *r){ CHECK(r == i226+2); });\n\tis_heap_until(i227, i227+7, std::greater<int>()).check([&](int *r){ CHECK(r == i227+2); });\n\tis_heap_until(i228, i228+7, std::greater<int>()).check([&](int *r){ CHECK(r == i228+2); });\n\tis_heap_until(i229, i229+7, std::greater<int>()).check([&](int *r){ CHECK(r == i229+2); });\n\tis_heap_until(i230, i230+7, std::greater<int>()).check([&](int *r){ CHECK(r == i230+2); });\n\tis_heap_until(i231, i231+7, std::greater<int>()).check([&](int *r){ CHECK(r == i231+2); });\n\tis_heap_until(i232, i232+7, std::greater<int>()).check([&](int *r){ CHECK(r == i232+3); });\n\tis_heap_until(i233, i233+7, std::greater<int>()).check([&](int *r){ CHECK(r == i233+3); });\n\tis_heap_until(i234, i234+7, std::greater<int>()).check([&](int *r){ CHECK(r == i234+3); });\n\tis_heap_until(i235, i235+7, std::greater<int>()).check([&](int *r){ CHECK(r == i235+3); });\n\tis_heap_until(i236, i236+7, std::greater<int>()).check([&](int *r){ CHECK(r == i236+3); });\n\tis_heap_until(i237, i237+7, std::greater<int>()).check([&](int *r){ CHECK(r == i237+3); });\n\tis_heap_until(i238, i238+7, std::greater<int>()).check([&](int *r){ CHECK(r == i238+3); });\n\tis_heap_until(i239, i239+7, std::greater<int>()).check([&](int *r){ CHECK(r == i239+3); });\n\tis_heap_until(i240, i240+7, std::greater<int>()).check([&](int *r){ CHECK(r == i240+4); });\n\tis_heap_until(i241, i241+7, std::greater<int>()).check([&](int *r){ CHECK(r == i241+4); });\n\tis_heap_until(i242, i242+7, std::greater<int>()).check([&](int *r){ CHECK(r == i242+4); });\n\tis_heap_until(i243, i243+7, std::greater<int>()).check([&](int *r){ CHECK(r == i243+4); });\n\tis_heap_until(i244, i244+7, std::greater<int>()).check([&](int *r){ CHECK(r == i244+5); });\n\tis_heap_until(i245, i245+7, std::greater<int>()).check([&](int *r){ CHECK(r == i245+5); });\n\tis_heap_until(i246, i246+7, std::greater<int>()).check([&](int *r){ CHECK(r == i246+6); });\n#endif\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest();\n\ttest_pred();\n\n\t// Test projections:\n\tS i185[] = {S{1}, S{0}, S{0}, S{0}, S{0}, S{0}, S{1}};\n\tauto is_heap_until = make_testable_1([](auto&&... args) {\n\t\treturn ranges::is_heap_until(std::forward<decltype(args)>(args)...);\n\t});\n\tis_heap_until(i185, i185+7, std::greater<int>(), &S::i)\n\t\t.check([&](S *r){ CHECK(r == i185+1); });\n\n\t// Test rvalue range\n\tauto res = ranges::is_heap_until(ranges::subrange(i185), std::greater<int>(), &S::i);\n\tCHECK(res == i185+1);\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/is_heap_until1.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_UNTIL_1\n#include \"./is_heap_until.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_heap_until2.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_UNTIL_2\n#include \"./is_heap_until.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_heap_until3.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_UNTIL_3\n#include \"./is_heap_until.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_heap_until4.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#define IS_HEAP_UNTIL_4\n#include \"./is_heap_until.hpp\"\n"
  },
  {
    "path": "test/algorithm/is_partitioned.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/is_partitioned.hpp>\n#include <memory>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nstruct is_odd\n{\n\tbool operator()(const int& i) const {return i & 1;}\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter()\n{\n\t{\n\t\tconst int ia[] = {1, 2, 3, 4, 5, 6};\n\t\tCHECK(!stl2::is_partitioned(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t  Sent(stl2::end(ia)),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6};\n\t\tCHECK( stl2::is_partitioned(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t  Sent(stl2::end(ia)),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {2, 4, 6, 1, 3, 5};\n\t\tCHECK(!stl2::is_partitioned(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t  Sent(stl2::end(ia)),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6, 7};\n\t\tCHECK(!stl2::is_partitioned(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t  Sent(stl2::end(ia)),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6, 7};\n\t\tCHECK( stl2::is_partitioned(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t  Sent(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_range()\n{\n\t{\n\t\tconst int ia[] = {1, 2, 3, 4, 5, 6};\n\t\tCHECK(!stl2::is_partitioned(stl2::subrange(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t\t\t\t\tSent(stl2::end(ia))),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6};\n\t\tCHECK( stl2::is_partitioned(stl2::subrange(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t\t\t\t\tSent(stl2::end(ia))),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {2, 4, 6, 1, 3, 5};\n\t\tCHECK(!stl2::is_partitioned(stl2::subrange(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t\t\t\t\tSent(stl2::end(ia))),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6, 7};\n\t\tCHECK(!stl2::is_partitioned(stl2::subrange(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t\t\t\t\tSent(stl2::end(ia))),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6, 7};\n\t\tCHECK( stl2::is_partitioned(stl2::subrange(Iter(stl2::begin(ia)),\n\t\t\t\t\t\t\t\t\t\t\t\t\tSent(stl2::begin(ia))),\n\t\t\t\t\t\t\t\t\t  is_odd()));\n\t}\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest_iter<input_iterator<const int*> >();\n\ttest_iter<input_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_range<input_iterator<const int*> >();\n\ttest_range<input_iterator<const int*>, sentinel<const int*>>();\n\n\t// Test projections\n\tconst S ia[] = {S{1}, S{3}, S{5}, S{2}, S{4}, S{6}};\n\tCHECK( stl2::is_partitioned(ia, is_odd(), &S::i) );\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/is_permutation.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/is_permutation.hpp>\n#include <stl2/utility.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nvoid test(const bool result,\n\tconst int* first1, const int* last1,\n\tconst int* first2, const int* last2)\n{\n\tusing ranges::is_permutation;\n\tusing ranges::subrange;\n\tusing I = forward_iterator<const int*>;\n\tusing S = sentinel<const int*>;\n\n\tCHECK(is_permutation(I{first1}, I{last1}, I{first2}, I{last2}) == result);\n\tCHECK(is_permutation(I{first1}, S{last1}, I{first2}, S{last2}) == result);\n\tCHECK(is_permutation(I{first1}, I{last1}, I{first2}, I{last2}, std::equal_to<int>{}) == result);\n\tCHECK(is_permutation(I{first1}, S{last1}, I{first2}, S{last2}, std::equal_to<int>{}) == result);\n\tCHECK(is_permutation(subrange{I{first1}, I{last1}}, subrange{I{first2}, I{last2}}) == result);\n\tCHECK(is_permutation(subrange{I{first1}, S{last1}}, subrange{I{first2}, S{last2}}) == result);\n\tCHECK(is_permutation(subrange{I{first1}, I{last1}}, subrange{I{first2}, I{last2}}, std::equal_to<int>{}) == result);\n\tCHECK(is_permutation(subrange{I{first1}, S{last1}}, subrange{I{first2}, S{last2}}, std::equal_to<int>{}) == result);\n}\n\nint comparison_count = 0;\n\ntemplate<typename T>\nbool counting_equals( T const &a, T const &b ) {\n\t++comparison_count;\n\treturn a == b;\n}\n\nstruct S {\n\tint i;\n};\n\nstruct T {\n\tint i;\n};\n\nint main() {\n\t{\n\t\tconst int ia[] = {0};\n\t\tconst int ib[] = {0};\n\t\ttest(true,  ia, ia + 0, ib, ib + 0);\n\t\ttest(true,  ia, ia + 1, ib, ib + 1);\n\t\ttest(false, ia, ia + 1, ib, ib + 0);\n\t}\n\t{\n\t\tconst int ia[] = {0};\n\t\tconst int ib[] = {1};\n\t\ttest(false, ia, ia + 1, ib, ib + 1);\n\t}\n\n\t{\n\t\tconst int ia[] = {0, 0};\n\t\tconst int ib[] = {0, 0};\n\t\ttest(true,  ia, ia + 2, ib, ib + 2);\n\t\ttest(false, ia, ia + 2, ib, ib + 1);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0};\n\t\tconst int ib[] = {0, 1};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0};\n\t\tconst int ib[] = {1, 0};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0};\n\t\tconst int ib[] = {1, 1};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1};\n\t\tconst int ib[] = {0, 0};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1};\n\t\tconst int ib[] = {0, 1};\n\t\ttest(true,  ia, ia + 2, ib, ib + 2);\n\t\ttest(false, ia, ia + 2, ib, ib + 1);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1};\n\t\tconst int ib[] = {1, 0};\n\t\ttest(true,  ia, ia + 2, ib, ib + 2);\n\t\ttest(false, ia, ia + 2, ib, ib + 1);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1};\n\t\tconst int ib[] = {1, 1};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {1, 0};\n\t\tconst int ib[] = {0, 0};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {1, 0};\n\t\tconst int ib[] = {0, 1};\n\t\ttest(true,  ia, ia + 2, ib, ib + 2);\n\t\ttest(false, ia, ia + 2, ib, ib + 1);\n\t}\n\t{\n\t\tconst int ia[] = {1, 0};\n\t\tconst int ib[] = {1, 0};\n\t\ttest(true,  ia, ia + 2, ib, ib + 2);\n\t\ttest(false, ia, ia + 2, ib, ib + 1);\n\t}\n\t{\n\t\tconst int ia[] = {1, 0};\n\t\tconst int ib[] = {1, 1};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {1, 1};\n\t\tconst int ib[] = {0, 0};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {1, 1};\n\t\tconst int ib[] = {0, 1};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {1, 1};\n\t\tconst int ib[] = {1, 0};\n\t\ttest(false, ia, ia + 2, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {1, 1};\n\t\tconst int ib[] = {1, 1};\n\t\ttest(true,  ia, ia + 2, ib, ib + 2);\n\t\ttest(false, ia, ia + 2, ib, ib + 1);\n\t}\n\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 0, 0};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 0, 1};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 0, 2};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 1, 0};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 1, 1};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 1, 2};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 2, 0};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 2, 1};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 0};\n\t\tconst int ib[] = {1, 2, 2};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 1};\n\t\tconst int ib[] = {1, 0, 0};\n\t\ttest(true,  ia, ia + 3, ib, ib + 3);\n\t\ttest(false, ia, ia + 3, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 1};\n\t\tconst int ib[] = {1, 0, 1};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1, 2};\n\t\tconst int ib[] = {1, 0, 2};\n\t\ttest(true,  ia, ia + 3, ib, ib + 3);\n\t\ttest(false, ia, ia + 3, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1, 2};\n\t\tconst int ib[] = {1, 2, 0};\n\t\ttest(true,  ia, ia + 3, ib, ib + 3);\n\t\ttest(false, ia, ia + 3, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1, 2};\n\t\tconst int ib[] = {2, 1, 0};\n\t\ttest(true,  ia, ia + 3, ib, ib + 3);\n\t\ttest(false, ia, ia + 3, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1, 2};\n\t\tconst int ib[] = {2, 0, 1};\n\t\ttest(true,  ia, ia + 3, ib, ib + 3);\n\t\ttest(false, ia, ia + 3, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 1};\n\t\tconst int ib[] = {1, 0, 1};\n\t\ttest(false, ia, ia + 3, ib, ib + 3);\n\t}\n\t{\n\t\tconst int ia[] = {0, 0, 1};\n\t\tconst int ib[] = {1, 0, 0};\n\t\ttest(true,  ia, ia + 3, ib, ib + 3);\n\t\ttest(false, ia, ia + 3, ib, ib + 2);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};\n\t\tconst int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 2};\n\t\tconstexpr auto sa = ranges::distance(ia);\n\t\tstatic_assert(sa == ranges::distance(ib));\n\n\t\ttest(true,  ia, ia + sa, ib, ib + sa);\n\t\ttest(false, ia, ia + sa, ib + 1, ib + sa);\n\t\ttest(false, ia, ia + sa, ib, ib + sa - 1);\n\n\t\tcomparison_count = 0;\n\t\tCHECK(ranges::is_permutation(\n\t\t\tforward_iterator(ia), forward_iterator(ia + sa),\n\t\t\tforward_iterator(ib), forward_iterator(ib + sa - 1),\n\t\t\tcounting_equals<const int>) == false);\n\t\tCHECK(comparison_count > 0);\n\n\t\tcomparison_count = 0;\n\t\tCHECK(ranges::is_permutation(\n\t\t\trandom_access_iterator(ia), random_access_iterator(ia + sa),\n\t\t\trandom_access_iterator(ib), random_access_iterator(ib + sa - 1),\n\t\t\tcounting_equals<const int>) == false);\n\t\tCHECK(comparison_count == 0);\n\t}\n\t{\n\t\tconst int ia[] = {0, 1, 2, 3, 0, 5, 6, 2, 4, 4};\n\t\tconst int ib[] = {4, 2, 3, 0, 1, 4, 0, 5, 6, 0};\n\t\tconstexpr auto sa = ranges::distance(ia);\n\t\tstatic_assert(sa == ranges::distance(ib));\n\t\ttest(false, ia, ia + sa, ib, ib + sa);\n\t}\n\n\t{\n\t\tconst S ia[] = {{0}, {1}, {2}, {3}, {0}, {5}, {6}, {2}, {4}, {4}};\n\t\tconst T ib[] = {{4}, {2}, {3}, {0}, {1}, {4}, {0}, {5}, {6}, {2}};\n\t\tconstexpr auto sa = ranges::distance(ia);\n\t\tstatic_assert(sa == ranges::distance(ib));\n\n\t\t// CommonView tests, with sentinels, with predicate and projections:\n\t\tCHECK(ranges::is_permutation(ia, ib, std::equal_to<int const>(), &S::i, &T::i) == true);\n\t\tCHECK(ranges::is_permutation(\n\t\t\tranges::subrange(forward_iterator<const S*>(ia), sentinel<const S*>(ia + sa)),\n\t\t\tranges::subrange(forward_iterator<const T*>(ib + 1), sentinel<const T*>(ib + sa)),\n\t\t\tstd::equal_to<int const>(), &S::i, &T::i) == false);\n\t\tCHECK(ranges::is_permutation(\n\t\t\tranges::subrange(forward_iterator<const S*>(ia), sentinel<const S*>(ia + sa)),\n\t\t\tranges::subrange(forward_iterator<const T*>(ib), sentinel<const T*>(ib + sa - 1)),\n\t\t\tstd::equal_to<int const>(), &S::i, &T::i) == false);\n\t\tCHECK(ranges::is_permutation(\n\t\t\tforward_iterator<const S*>(ia), sentinel<const S*>(ia + sa),\n\t\t\tforward_iterator<const T*>(ib), sentinel<const T*>(ib + sa),\n\t\t\tstd::equal_to<int const>(), &S::i, &T::i) == true);\n\n\t\t// Iterator tests, with sentinels, with predicate and projections:\n\t\tCHECK(ranges::is_permutation(\n\t\t\tforward_iterator<const S*>(ia), sentinel<const S*>(ia + sa),\n\t\t\tforward_iterator<const T*>(ib), sentinel<const T*>(ib + sa),\n\t\t\tstd::equal_to<int const>(), &S::i, &T::i) == true);\n\t\tCHECK(ranges::is_permutation(\n\t\t\tforward_iterator<const S*>(ia), sentinel<const S*>(ia + sa),\n\t\t\tforward_iterator<const T*>(ib + 1), sentinel<const T*>(ib + sa),\n\t\t\tstd::equal_to<int const>(), &S::i, &T::i) == false);\n\t\tCHECK(ranges::is_permutation(\n\t\t\tforward_iterator<const S*>(ia), sentinel<const S*>(ia + sa),\n\t\t\tforward_iterator<const T*>(ib), sentinel<const T*>(ib + sa - 1),\n\t\t\tstd::equal_to<int const>(), &S::i, &T::i) == false);\n\t}\n\n\t{\n\t\tconst int a[] = {0,1,2,3};\n\t\tconst int b[] = {2,3,1,0};\n\t\ttest(true, a, a + 4, b, b + 4);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/is_sorted.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Gonzalo Brito Gadeschi 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n// Implementation based on the code in libc++\n//   http://http://libcxx.llvm.org/\n\n#include <stl2/detail/algorithm/is_sorted.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\n/// Calls the iterator interface of the algorithm\ntemplate<class Iter>\nstruct iter_call\n{\n\tusing begin_t = Iter;\n\tusing sentinel_t = typename sentinel_type<Iter>::type;\n\n\ttemplate<class B, class E, class... Args>\n\trequires requires(B&& b, E&& e, Args&&... args) {\n\t\tranges::is_sorted(begin_t{b}, sentinel_t{e}, std::forward<Args>(args)...);\n\t}\n\tbool operator()(B&& b, E&& e, Args&&... args)\n\t{\n\t\treturn ranges::is_sorted(begin_t{b}, sentinel_t{e}, std::forward<Args>(args)...);\n\t}\n};\n\n/// Calls the range interface of the algorithm\ntemplate<class Iter>\nstruct range_call\n{\n\tusing begin_t = Iter;\n\tusing sentinel_t = typename sentinel_type<Iter>::type;\n\n\ttemplate<class B, class E, class...  Args>\n\trequires requires(B&& b, E&& e, Args&&... args) {\n\t\tranges::is_sorted(ranges::subrange(begin_t{b}, sentinel_t{e}),\n\t\t                  std::forward<Args>(args)...);\n\t}\n\tbool operator()(B&& b, E&& e, Args&&... args)\n\t{\n\t\treturn ranges::is_sorted(ranges::subrange(begin_t{b}, sentinel_t{e}),\n\t\t                         std::forward<Args>(args)...);\n\t}\n};\n\ntemplate<class Fun>\nvoid test()\n{\n\t{\n\t\tint a[] = {0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a));\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a));\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\n\t{\n\t\tint a[] = {0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(!Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()));\n\t}\n}\n\nstruct A { int a; };\n\nint main()\n{\n\ttest<iter_call<forward_iterator<const int *>>>();\n\ttest<iter_call<bidirectional_iterator<const int *>>>();\n\ttest<iter_call<random_access_iterator<const int *>>>();\n\ttest<iter_call<const int *>>();\n\n\ttest<range_call<forward_iterator<const int *>>>();\n\ttest<range_call<bidirectional_iterator<const int *>>>();\n\ttest<range_call<random_access_iterator<const int *>>>();\n\ttest<range_call<const int *>>();\n\n\t/// Projection test:\n\t{\n\t\tA as[] = {{0}, {1}, {2}, {3}, {4}};\n\t\tCHECK(ranges::is_sorted(as, std::less<int>{}, &A::a));\n\t\tCHECK(!ranges::is_sorted(as, std::greater<int>{}, &A::a));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/is_sorted_until.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Gonzalo Brito Gadeschi 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n// Implementation based on the code in libc++\n//   http://http://libcxx.llvm.org/\n\n#include <stl2/detail/algorithm/is_sorted_until.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\n/// Calls the iterator interface of the algorithm\ntemplate<class Iter>\nstruct iter_call {\n\tusing begin_t = Iter;\n\tusing sentinel_t = typename sentinel_type<Iter>::type;\n\n\ttemplate<class B, class E, class... Args>\n\trequires requires(B&& It, E&& e, Args&&... args) {\n\t\tranges::is_sorted_until(begin_t{It}, sentinel_t{e},\n\t\t                        std::forward<Args>(args)...);\n\t}\n\tbegin_t operator()(B&& It, E&& e, Args&&... args)\n\t{\n\t\treturn ranges::is_sorted_until(begin_t{It}, sentinel_t{e},\n\t\t                               std::forward<Args>(args)...);\n\t}\n};\n\n/// Calls the range interface of the algorithm\ntemplate<class Iter>\nstruct range_call {\n\tusing begin_t = Iter;\n\tusing sentinel_t = typename sentinel_type<Iter>::type;\n\n\ttemplate<class B, class E, class... Args>\n\trequires requires(B&& It, E&& e, Args&&... args) {\n\t\tranges::is_sorted_until(::as_lvalue(ranges::subrange(begin_t{It}, sentinel_t{e})),\n\t\t                        std::forward<Args>(args)...);\n\t}\n\tbegin_t operator()(B&& It, E&& e, Args&&... args) {\n\t\treturn ranges::is_sorted_until(::as_lvalue(ranges::subrange(begin_t{It}, sentinel_t{e})),\n\t\t                               std::forward<Args>(args)...);\n\t}\n};\n\ntemplate<class It, template<class> class FunT>\nvoid test() {\n\tusing Fun = FunT<It>;\n\n\t{\n\t\tint a[] = {0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a) == It(a));\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 3));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 3));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + 3));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa) == It(a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a, std::greater<int>()) == It(a));\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\n\t{\n\t\tint a[] = {0, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {0, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 3));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {0, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 1));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 0, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 3));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {1, 0, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 2));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 0, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + 3));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 0};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n\t{\n\t\tint a[] = {1, 1, 1, 1};\n\t\tunsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tCHECK(Fun{}(a, a + sa, std::greater<int>()) == It(a + sa));\n\t}\n}\n\nstruct A { int a; };\n\nint main() {\n\ttest<forward_iterator<const int*>, iter_call>();\n\ttest<bidirectional_iterator<const int*>, iter_call>();\n\ttest<random_access_iterator<const int*>, iter_call>();\n\ttest<const int*, iter_call>();\n\n\ttest<forward_iterator<const int*>, range_call>();\n\ttest<bidirectional_iterator<const int*>, range_call>();\n\ttest<random_access_iterator<const int*>, range_call>();\n\ttest<const int*, range_call>();\n\n\t/// Initializer list test:\n\t{\n\t\tstd::initializer_list<int> r = {0,1,2,3,4,5,6,7,8,9,10};\n\t\tCHECK(ranges::is_sorted_until(r) == ranges::end(r));\n\t}\n\n\t/// Projection test:\n\t{\n\t\tA as[] = {{0}, {1}, {2}, {3}, {4}};\n\t\tCHECK(ranges::is_sorted_until(as, std::less<int>{}, &A::a) == ranges::end(as));\n\t\tCHECK(ranges::is_sorted_until(as, std::greater<int>{}, &A::a) == ranges::next(ranges::begin(as),1));\n\t}\n\n\t/// Rvalue range test:\n\t{\n\t\tA as[] = {{0}, {1}, {2}, {3}, {4}};\n\t\tCHECK(ranges::is_sorted_until(ranges::subrange(as), std::less<int>{}, &A::a) == ranges::end(as));\n\t\tCHECK(ranges::is_sorted_until(ranges::subrange(as), std::greater<int>{}, &A::a) == ranges::next(ranges::begin(as),1));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/lexicographical_compare.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/lexicographical_compare.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter1, class Iter2, class Sent1 = Iter1, class Sent2 = Iter2>\nvoid test_iter1() {\n\tint ia[] = {1, 2, 3, 4};\n\tconstexpr auto sa = ranges::distance(ia);\n\tint ib[] = {1, 2, 3};\n\tCHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+2)));\n\tCHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+2), Iter2(ia), Sent2(ia+sa)));\n\tCHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+3)));\n\tCHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+3), Iter2(ia), Sent2(ia+sa)));\n\tCHECK(ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib+1), Sent2(ib+3)));\n\tCHECK(!ranges::lexicographical_compare(Iter1(ib+1), Sent1(ib+3), Iter2(ia), Sent2(ia+sa)));\n}\n\nvoid test_iter() {\n\tusing S = sentinel<const int*>;\n\n\ttest_iter1<input_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter1<input_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter1<input_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter1<input_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter1<input_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter1<input_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter1<input_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter1<input_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter1<input_iterator<const int*>, const int*>();\n\n\ttest_iter1<forward_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter1<forward_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter1<forward_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter1<forward_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter1<forward_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter1<forward_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter1<forward_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter1<forward_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter1<forward_iterator<const int*>, const int*>();\n\n\ttest_iter1<bidirectional_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter1<bidirectional_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter1<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter1<bidirectional_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter1<bidirectional_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter1<bidirectional_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter1<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter1<bidirectional_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter1<bidirectional_iterator<const int*>, const int*>();\n\n\ttest_iter1<random_access_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter1<random_access_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter1<random_access_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter1<random_access_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter1<random_access_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter1<random_access_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter1<random_access_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter1<random_access_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter1<random_access_iterator<const int*>, const int*>();\n\n\ttest_iter1<const int*, input_iterator<const int*>>();\n\ttest_iter1<const int*, forward_iterator<const int*>>();\n\ttest_iter1<const int*, bidirectional_iterator<const int*>>();\n\ttest_iter1<const int*, random_access_iterator<const int*>>();\n\ttest_iter1<const int*, input_iterator<const int*>, const int*, S>();\n\ttest_iter1<const int*, forward_iterator<const int*>, const int*, S>();\n\ttest_iter1<const int*, bidirectional_iterator<const int*>, const int*, S>();\n\ttest_iter1<const int*, random_access_iterator<const int*>, const int*, S>();\n\ttest_iter1<const int*, const int*>();\n}\n\ntemplate<class Iter1, class Iter2, class Sent1 = Iter1, class Sent2 = Iter2>\nvoid test_iter_comp1() {\n\tint ia[] = {1, 2, 3, 4};\n\tconstexpr auto sa = ranges::distance(ia);\n\tint ib[] = {1, 2, 3};\n\tstd::greater<int> c;\n\tCHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+2), c));\n\tCHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+2), Iter2(ia), Sent2(ia+sa), c));\n\tCHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib), Sent2(ib+3), c));\n\tCHECK(ranges::lexicographical_compare(Iter1(ib), Sent1(ib+3), Iter2(ia), Sent2(ia+sa), c));\n\tCHECK(!ranges::lexicographical_compare(Iter1(ia), Sent1(ia+sa), Iter2(ib+1), Sent2(ib+3), c));\n\tCHECK(ranges::lexicographical_compare(Iter1(ib+1), Sent1(ib+3), Iter2(ia), Sent2(ia+sa), c));\n}\n\nvoid test_iter_comp() {\n\tusing S = sentinel<const int*>;\n\n\ttest_iter_comp1<input_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter_comp1<input_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter_comp1<input_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter_comp1<input_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter_comp1<input_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter_comp1<input_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter_comp1<input_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter_comp1<input_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter_comp1<input_iterator<const int*>, const int*>();\n\n\ttest_iter_comp1<forward_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter_comp1<forward_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter_comp1<forward_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter_comp1<forward_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter_comp1<forward_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter_comp1<forward_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter_comp1<forward_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter_comp1<forward_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter_comp1<forward_iterator<const int*>, const int*>();\n\n\ttest_iter_comp1<bidirectional_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter_comp1<bidirectional_iterator<const int*>, const int*>();\n\n\ttest_iter_comp1<random_access_iterator<const int*>, input_iterator<const int*>>();\n\ttest_iter_comp1<random_access_iterator<const int*>, forward_iterator<const int*>>();\n\ttest_iter_comp1<random_access_iterator<const int*>, bidirectional_iterator<const int*>>();\n\ttest_iter_comp1<random_access_iterator<const int*>, random_access_iterator<const int*>>();\n\ttest_iter_comp1<random_access_iterator<const int*>, input_iterator<const int*>, S, S>();\n\ttest_iter_comp1<random_access_iterator<const int*>, forward_iterator<const int*>, S, S>();\n\ttest_iter_comp1<random_access_iterator<const int*>, bidirectional_iterator<const int*>, S, S>();\n\ttest_iter_comp1<random_access_iterator<const int*>, random_access_iterator<const int*>, S, S>();\n\ttest_iter_comp1<random_access_iterator<const int*>, const int*>();\n\n\ttest_iter_comp1<const int*, input_iterator<const int*>>();\n\ttest_iter_comp1<const int*, forward_iterator<const int*>>();\n\ttest_iter_comp1<const int*, bidirectional_iterator<const int*>>();\n\ttest_iter_comp1<const int*, random_access_iterator<const int*>>();\n\ttest_iter_comp1<const int*, input_iterator<const int*>, const int*, S>();\n\ttest_iter_comp1<const int*, forward_iterator<const int*>, const int*, S>();\n\ttest_iter_comp1<const int*, bidirectional_iterator<const int*>, const int*, S>();\n\ttest_iter_comp1<const int*, random_access_iterator<const int*>, const int*, S>();\n\ttest_iter_comp1<const int*, const int*>();\n}\n\nint main() {\n\ttest_iter();\n\ttest_iter_comp();\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/lower_bound.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n#include <stl2/detail/algorithm/lower_bound.hpp>\n#include <stl2/view/iota.hpp>\n#include <vector>\n#include <utility>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct my_int {\n\tint value;\n};\n\nbool compare(my_int lhs, my_int rhs) {\n\treturn lhs.value < rhs.value;\n}\n\nvoid not_totally_ordered() {\n\t// This better compile!\n\tstd::vector<my_int> vec;\n\tranges::lower_bound(vec, my_int{10}, compare);\n}\n\nint main() {\n\tusing ranges::begin;\n\tusing ranges::end;\n\tusing ranges::size;\n\tusing ranges::less;\n\n\tstd::pair<int, int> a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\tconst std::pair<int, int> c[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\n\tCHECK(ranges::ext::lower_bound_n(begin(a), size(a), a[0]) == &a[0]);\n\tCHECK(ranges::ext::lower_bound_n(begin(a), size(a), a[1], less()) == &a[1]);\n\tCHECK(ranges::ext::lower_bound_n(begin(a), size(a), 1, less(), &std::pair<int, int>::first) == &a[2]);\n\n\tCHECK(ranges::lower_bound(begin(a), end(a), a[0]) == &a[0]);\n\tCHECK(ranges::lower_bound(begin(a), end(a), a[1], less()) == &a[1]);\n\tCHECK(ranges::lower_bound(begin(a), end(a), 1, less(), &std::pair<int, int>::first) == &a[2]);\n\n\tCHECK(ranges::lower_bound(a, a[2]) == &a[2]);\n\tCHECK(ranges::lower_bound(c, c[3]) == &c[3]);\n\n\tCHECK(ranges::lower_bound(a, a[4], less()) == &a[4]);\n\tCHECK(ranges::lower_bound(c, c[5], less()) == &c[5]);\n\n\tCHECK(ranges::lower_bound(a, 1, less(), &std::pair<int, int>::first) == &a[2]);\n\tCHECK(ranges::lower_bound(c, 1, less(), &std::pair<int, int>::first) == &c[2]);\n\n\tCHECK(ranges::lower_bound(ranges::subrange(a), 1, less(), &std::pair<int, int>::first) == &a[2]);\n\tCHECK(ranges::lower_bound(ranges::subrange(c), 1, less(), &std::pair<int, int>::first) == &c[2]);\n\n\tCHECK(*ranges::lower_bound(ranges::iota_view<int>{}, 42) == 42);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/make_heap.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/make_heap.hpp>\n#include <memory>\n#include <random>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\nvoid test_1(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(ia, ia+N) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N));\n\tdelete [] ia;\n}\n\nvoid test_2(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(ia, sentinel<int*>(ia+N)) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N));\n\tdelete [] ia;\n}\n\nvoid test_3(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(::as_lvalue(stl2::subrange(ia, ia+N))) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N));\n\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(stl2::subrange(ia, ia+N)) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N));\n\n\tdelete [] ia;\n}\n\nvoid test_4(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(::as_lvalue(stl2::subrange(ia, sentinel<int*>(ia+N)))) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N));\n\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(stl2::subrange(ia, sentinel<int*>(ia+N))) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N));\n\n\tdelete [] ia;\n}\n\nvoid test_5(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(ia, ia+N, std::greater<int>()) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N, std::greater<int>()));\n\tdelete [] ia;\n}\n\nvoid test_6(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(ia, sentinel<int*>(ia+N), std::greater<int>()) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N, std::greater<int>()));\n\tdelete [] ia;\n}\n\nvoid test_7(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(::as_lvalue(stl2::subrange(ia, ia+N)), std::greater<int>()) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N, std::greater<int>()));\n\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(stl2::subrange(ia, ia+N), std::greater<int>()) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N, std::greater<int>()));\n\n\tdelete [] ia;\n}\n\nvoid test_8(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(::as_lvalue(stl2::subrange(ia, sentinel<int*>(ia+N))), std::greater<int>()) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N, std::greater<int>()));\n\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(stl2::subrange(ia, sentinel<int*>(ia+N)), std::greater<int>()) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N, std::greater<int>()));\n\n\tdelete [] ia;\n}\n\nstruct indirect_less\n{\n\ttemplate<class P>\n\tbool operator()(const P& x, const P& y) const\n\t\t{return *x < *y;}\n};\n\nvoid test_9(int N)\n{\n\tstd::unique_ptr<int>* ia = new std::unique_ptr<int> [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i].reset(new int(i));\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(ia, ia+N, indirect_less()) == ia+N);\n\tCHECK(std::is_heap(ia, ia+N, indirect_less()));\n\tdelete [] ia;\n}\n\nstruct S\n{\n\tint i;\n};\n\nvoid test_10(int N)\n{\n\tint* ia = new int [N];\n\tS* ib = new S [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tib[i].i = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tCHECK(stl2::make_heap(ib, ib+N, std::less<int>(), &S::i) == ib+N);\n\tstd::transform(ib, ib+N, ia, std::mem_fn(&S::i));\n\tCHECK(std::is_heap(ia, ia+N));\n\tdelete [] ia;\n\tdelete [] ib;\n}\n\nvoid test(int N)\n{\n\ttest_1(N);\n\ttest_2(N);\n\ttest_3(N);\n\ttest_4(N);\n\ttest_5(N);\n\ttest_6(N);\n\ttest_7(N);\n\ttest_8(N);\n}\n\nint main()\n{\n\ttest(0);\n\ttest(1);\n\ttest(2);\n\ttest(3);\n\ttest(10);\n\ttest(1000);\n\ttest_9(1000);\n\ttest_10(1000);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/max.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/max.hpp>\n#include <cassert>\n#include <memory>\n#include <numeric>\n#include <random>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(Iter first, Sent last)\n{\n\tassert(first != last);\n\tauto rng = stl2::subrange(first, last);\n\tauto v = stl2::max(rng);\n\tfor (Iter i = first; i != last; ++i)\n\t\tCHECK(!(v < *i));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(unsigned N)\n{\n\tassert(N > 0);\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter()\n{\n\ttest_iter<Iter, Sent>(1);\n\ttest_iter<Iter, Sent>(2);\n\ttest_iter<Iter, Sent>(3);\n\ttest_iter<Iter, Sent>(10);\n\ttest_iter<Iter, Sent>(1000);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(Iter first, Sent last)\n{\n\tassert(first != last);\n\tauto rng = stl2::subrange(first, last);\n\tauto comp = std::greater<int>();\n\tauto v = stl2::max(rng, comp);\n\tfor (Iter i = first; i != last; ++i)\n\t\tCHECK(!comp(v, *i));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(unsigned N)\n{\n\tassert(N > 0);\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter_comp(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp()\n{\n\ttest_iter_comp<Iter, Sent>(1);\n\ttest_iter_comp<Iter, Sent>(2);\n\ttest_iter_comp<Iter, Sent>(3);\n\ttest_iter_comp<Iter, Sent>(10);\n\ttest_iter_comp<Iter, Sent>(1000);\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest_iter<input_iterator<const int*> >();\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<input_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_iter_comp<input_iterator<const int*> >();\n\ttest_iter_comp<forward_iterator<const int*> >();\n\ttest_iter_comp<bidirectional_iterator<const int*> >();\n\ttest_iter_comp<random_access_iterator<const int*> >();\n\ttest_iter_comp<const int*>();\n\ttest_iter_comp<input_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\t// Works with projections?\n\tS s[] = {S{1},S{2},S{3},S{4},S{40},S{5},S{6},S{7},S{8},S{9}};\n\tS v = stl2::max(s, std::less<int>{}, &S::i);\n\tCHECK(v.i == 40);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/max_element.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/max_element.hpp>\n#include <memory>\n#include <numeric>\n#include <random>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(Iter first, Sent last)\n{\n\tIter i = stl2::max_element(first, last);\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!(*i < *j));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto rng = stl2::subrange(first, last);\n\ti = stl2::max_element(rng);\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!(*i < *j));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto j = stl2::max_element(std::move(rng));\n\tif (first != last)\n\t{\n\t\tfor (Iter k = first; k != last; ++k)\n\t\t\tCHECK(!(*j < *k));\n\t}\n\telse\n\t\tCHECK(j == last);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(unsigned N)\n{\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter()\n{\n\ttest_iter<Iter, Sent>(0);\n\ttest_iter<Iter, Sent>(1);\n\ttest_iter<Iter, Sent>(2);\n\ttest_iter<Iter, Sent>(3);\n\ttest_iter<Iter, Sent>(10);\n\ttest_iter<Iter, Sent>(1000);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(Iter first, Sent last)\n{\n\tIter i = stl2::max_element(first, last, std::greater<int>());\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!std::greater<int>()(*i, *j));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto rng = stl2::subrange(first, last);\n\ti = stl2::max_element(rng, std::greater<int>());\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!std::greater<int>()(*i, *j));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto res = stl2::max_element(std::move(rng), std::greater<int>());\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!std::greater<int>()(*res, *j));\n\t}\n\telse\n\t\tCHECK(res == last);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(unsigned N)\n{\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter_comp(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp()\n{\n\ttest_iter_comp<Iter, Sent>(0);\n\ttest_iter_comp<Iter, Sent>(1);\n\ttest_iter_comp<Iter, Sent>(2);\n\ttest_iter_comp<Iter, Sent>(3);\n\ttest_iter_comp<Iter, Sent>(10);\n\ttest_iter_comp<Iter, Sent>(1000);\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_iter_comp<forward_iterator<const int*> >();\n\ttest_iter_comp<bidirectional_iterator<const int*> >();\n\ttest_iter_comp<random_access_iterator<const int*> >();\n\ttest_iter_comp<const int*>();\n\ttest_iter_comp<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\t// Works with projections?\n\tS s[] = {S{1},S{2},S{3},S{4},S{40},S{5},S{6},S{7},S{8},S{9}};\n\tS const *ps = stl2::max_element(s, std::less<int>{}, &S::i);\n\tCHECK(ps->i == 40);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/merge.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n#include <stl2/detail/algorithm/merge.hpp>\n#include <algorithm>\n#include <memory>\n#include <utility>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main() {\n\t{\n\t\tunsigned N = 100000;\n\t\tstd::unique_ptr<int[]> ia{new int[N]};\n\t\tstd::unique_ptr<int[]> ib{new int[N]};\n\t\tstd::unique_ptr<int[]> ic{new int[2 * N]};\n\t\tfor(unsigned i = 0; i < N; ++i)\n\t\t\tia[i] = 2 * i;\n\t\tfor(unsigned i = 0; i < N; ++i)\n\t\t\tib[i] = 2 * i + 1;\n\t\tauto r = ranges::merge(ia.get(), ia.get() + N,\n\t\t\tib.get(), ib.get() + N, ic.get());\n\t\tCHECK(r.in1 == ia.get() + N);\n\t\tCHECK(r.in2 == ib.get() + N);\n\t\tCHECK(r.out == ic.get() + 2 * N);\n\t\tCHECK(ic[0] == 0);\n\t\tCHECK(ic[2 * N - 1] == (int)(2 * N - 1));\n\t\tCHECK(std::is_sorted(ic.get(), ic.get() + 2 * N));\n\t}\n\n\t{\n\t\tunsigned N = 100000;\n\t\tstd::unique_ptr<int[]> ia{new int[N]};\n\t\tstd::unique_ptr<int[]> ib{new int[N]};\n\t\tstd::unique_ptr<int[]> ic{new int[2 * N]};\n\t\tfor(unsigned i = 0; i < N; ++i)\n\t\t\tia[i] = 2 * i;\n\t\tfor(unsigned i = 0; i < N; ++i)\n\t\t\tib[i] = 2 * i + 1;\n\t\tauto r0 = ranges::subrange(ia.get(), ia.get() + N);\n\t\tauto r1 = ranges::subrange(ib.get(), ib.get() + N);\n\t\tauto r = ranges::merge(r0, r1, ic.get());\n\t\tCHECK(r.in1 == ia.get() + N);\n\t\tCHECK(r.in2 == ib.get() + N);\n\t\tCHECK(r.out == ic.get() + 2 * N);\n\t\tCHECK(ic[0] == 0);\n\t\tCHECK(ic[2 * N - 1] == (int)(2 * N - 1));\n\t\tCHECK(std::is_sorted(ic.get(), ic.get() + 2 * N));\n\t}\n\n\n\t{\n\t\tunsigned N = 100000;\n\t\tstd::unique_ptr<int[]> ia{new int[N]};\n\t\tstd::unique_ptr<int[]> ib{new int[N]};\n\t\tstd::unique_ptr<int[]> ic{new int[2 * N]};\n\t\tfor(unsigned i = 0; i < N; ++i)\n\t\t\tia[i] = 2 * i;\n\t\tfor(unsigned i = 0; i < N; ++i)\n\t\t\tib[i] = 2 * i + 1;\n\t\tauto r0 = ranges::subrange(ia.get(), ia.get() + N);\n\t\tauto r1 = ranges::subrange(ib.get(), ib.get() + N);\n\t\tauto r = ranges::merge(std::move(r0), std::move(r1), ic.get());\n\t\tCHECK(r.in1 == ia.get() + N);\n\t\tCHECK(r.in2 == ib.get() + N);\n\t\tCHECK(r.out == ic.get() + 2 * N);\n\t\tCHECK(ic[0] == 0);\n\t\tCHECK(ic[2 * N - 1] == (int)(2 * N - 1));\n\t\tCHECK(std::is_sorted(ic.get(), ic.get() + 2 * N));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/min.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/min.hpp>\n#include <cassert>\n#include <memory>\n#include <random>\n#include <numeric>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(Iter first, Sent last)\n{\n\tassert(first != last);\n\tauto rng = stl2::subrange(first, last);\n\tauto v1 = stl2::min(rng);\n\tfor (Iter i = first; i != last; ++i)\n\t\tCHECK(!(*i < v1));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(unsigned N)\n{\n\tassert(N > 0);\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter()\n{\n\ttest_iter<Iter, Sent>(1);\n\ttest_iter<Iter, Sent>(2);\n\ttest_iter<Iter, Sent>(3);\n\ttest_iter<Iter, Sent>(10);\n\ttest_iter<Iter, Sent>(1000);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(Iter first, Sent last)\n{\n\tassert(first != last);\n\tauto rng = stl2::subrange(first, last);\n\tauto v = stl2::min(rng, std::greater<int>());\n\tfor (Iter i = first; i != last; ++i)\n\t\tCHECK(!std::greater<int>()(*i, v));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(unsigned N)\n{\n\tassert(N > 0);\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter_comp(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp()\n{\n\ttest_iter_comp<Iter, Sent>(1);\n\ttest_iter_comp<Iter, Sent>(2);\n\ttest_iter_comp<Iter, Sent>(3);\n\ttest_iter_comp<Iter, Sent>(10);\n\ttest_iter_comp<Iter, Sent>(1000);\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest_iter<input_iterator<const int*> >();\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<input_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_iter_comp<input_iterator<const int*> >();\n\ttest_iter_comp<forward_iterator<const int*> >();\n\ttest_iter_comp<bidirectional_iterator<const int*> >();\n\ttest_iter_comp<random_access_iterator<const int*> >();\n\ttest_iter_comp<const int*>();\n\ttest_iter_comp<input_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\t// Works with projections?\n\tS s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{7},S{8},S{9}};\n\tS v = stl2::min(s, std::less<int>{}, &S::i);\n\tCHECK(v.i == -4);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/min_element.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/min_element.hpp>\n#include <memory>\n#include <random>\n#include <numeric>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(Iter first, Sent last)\n{\n\tIter i = stl2::min_element(first, last);\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!(*j < *i));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto rng = stl2::subrange(first, last);\n\ti = stl2::min_element(rng);\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!(*j < *i));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto res = stl2::min_element(std::move(rng));\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!(*j < *res));\n\t}\n\telse\n\t\tCHECK(res == last);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter(unsigned N)\n{\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter()\n{\n\ttest_iter<Iter, Sent>(0);\n\ttest_iter<Iter, Sent>(1);\n\ttest_iter<Iter, Sent>(2);\n\ttest_iter<Iter, Sent>(3);\n\ttest_iter<Iter, Sent>(10);\n\ttest_iter<Iter, Sent>(1000);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(Iter first, Sent last)\n{\n\tIter i = stl2::min_element(first, last, std::greater<int>());\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!std::greater<int>()(*j, *i));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto rng = stl2::subrange(first, last);\n\ti = stl2::min_element(rng, std::greater<int>());\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!std::greater<int>()(*j, *i));\n\t}\n\telse\n\t\tCHECK(i == last);\n\n\tauto res = stl2::min_element(std::move(rng), std::greater<int>());\n\tif (first != last)\n\t{\n\t\tfor (Iter j = first; j != last; ++j)\n\t\t\tCHECK(!std::greater<int>()(*j, *res));\n\t}\n\telse\n\t\tCHECK(res == last);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp(unsigned N)\n{\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter_comp(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_comp()\n{\n\ttest_iter_comp<Iter, Sent>(0);\n\ttest_iter_comp<Iter, Sent>(1);\n\ttest_iter_comp<Iter, Sent>(2);\n\ttest_iter_comp<Iter, Sent>(3);\n\ttest_iter_comp<Iter, Sent>(10);\n\ttest_iter_comp<Iter, Sent>(1000);\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_iter_comp<forward_iterator<const int*> >();\n\ttest_iter_comp<bidirectional_iterator<const int*> >();\n\ttest_iter_comp<random_access_iterator<const int*> >();\n\ttest_iter_comp<const int*>();\n\ttest_iter_comp<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter_comp<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\t// Works with projections?\n\tS s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{7},S{8},S{9}};\n\tS const *ps = stl2::min_element(s, std::less<int>{}, &S::i);\n\tCHECK(ps->i == -4);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/minmax.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/minmax.hpp>\n#include <cassert>\n#include <memory>\n#include <numeric>\n#include <random>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter(Iter first, Sent last) {\n\tassert(first != last);\n\tauto res = ranges::minmax(ranges::subrange(first, last));\n\tfor (Iter i = first; i != last; ++i) {\n\t\tCHECK(!(*i < res.min));\n\t\tCHECK(!(res.max < *i));\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter(unsigned N) {\n\tassert(N > 0);\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter() {\n\ttest_iter<Iter, Sent>(1);\n\ttest_iter<Iter, Sent>(2);\n\ttest_iter<Iter, Sent>(3);\n\ttest_iter<Iter, Sent>(10);\n\ttest_iter<Iter, Sent>(1000);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter_comp(Iter first, Sent last) {\n\tassert(first != last);\n\ttypedef std::greater<int> Compare;\n\tCompare comp;\n\tauto res = ranges::minmax(ranges::subrange(first, last), comp);\n\tfor (Iter i = first; i != last; ++i) {\n\t\tCHECK(!comp(*i, res.min));\n\t\tCHECK(!comp(res.max, *i));\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter_comp(unsigned N) {\n\tassert(N > 0);\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter_comp(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter_comp() {\n\ttest_iter_comp<Iter, Sent>(1);\n\ttest_iter_comp<Iter, Sent>(2);\n\ttest_iter_comp<Iter, Sent>(3);\n\ttest_iter_comp<Iter, Sent>(10);\n\ttest_iter_comp<Iter, Sent>(1000);\n}\n\nstruct S {\n\tint value;\n\tint index;\n};\n\nint main() {\n\ttest_iter<input_iterator<const int*> >();\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<input_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_iter<input_iterator<const int*> >();\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<input_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\t// Works with projections?\n\tS s[] = {S{1,0},S{2,1},S{3,2},S{4,3},S{-4,4},S{40,5},S{-4,6},S{40,7},S{7,8},S{8,9},S{9,10}};\n\tauto res = ranges::minmax(s, std::less<int>{}, &S::value);\n\tCHECK(res.min.value == -4);\n\tCHECK(res.min.index == 4);\n\tCHECK(res.max.value == 40);\n\tCHECK(res.max.index == 7);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/minmax_element.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/minmax_element.hpp>\n#include <memory>\n#include <numeric>\n#include <random>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter(Iter first, Sent last) {\n\tranges::minmax_result<Iter> p = ranges::minmax_element(first, last);\n\tif (first != last) {\n\t\tfor (Iter j = first; j != last; ++j) {\n\t\t\tCHECK(!(*j < *p.min));\n\t\t\tCHECK(!(*p.max < *j));\n\t\t}\n\t} else {\n\t\tCHECK(p.min == last);\n\t\tCHECK(p.max == last);\n\t}\n\n\tauto rng = ranges::subrange(first, last);\n\tp = ranges::minmax_element(rng);\n\tif (first != last) {\n\t\tfor (Iter j = first; j != last; ++j) {\n\t\t\tCHECK(!(*j < *p.min));\n\t\t\tCHECK(!(*p.max < *j));\n\t\t}\n\t} else {\n\t\tCHECK(p.min == last);\n\t\tCHECK(p.max == last);\n\t}\n\n\tauto res = ranges::minmax_element(std::move(rng));\n\tif (first != last) {\n\t\tfor (Iter j = first; j != last; ++j) {\n\t\t\tCHECK(!(*j < *res.min));\n\t\t\tCHECK(!(*p.max < *j));\n\t\t}\n\t} else {\n\t\tCHECK(res.min == last);\n\t\tCHECK(res.max == last);\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter(unsigned N) {\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter() {\n\ttest_iter<Iter, Sent>(0);\n\ttest_iter<Iter, Sent>(1);\n\ttest_iter<Iter, Sent>(2);\n\ttest_iter<Iter, Sent>(3);\n\ttest_iter<Iter, Sent>(10);\n\ttest_iter<Iter, Sent>(1000);\n\n\t{\n\t\tconst unsigned N = 100;\n\t\tstd::unique_ptr<int[]> a{new int[N]};\n\t\tstd::fill_n(a.get(), N, 5);\n\t\tstd::shuffle(a.get(), a.get()+N, gen);\n\t\tranges::minmax_result<Iter> p =\n\t\t\tranges::minmax_element(Iter(a.get()), Sent(a.get()+N));\n\t\tCHECK(base(p.min) == a.get());\n\t\tCHECK(base(p.max) == a.get()+N-1);\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter_comp(Iter first, Sent last) {\n\ttypedef std::greater<int> Compare;\n\tCompare comp;\n\tranges::minmax_result<Iter> p = ranges::minmax_element(first, last, comp);\n\tif (first != last) {\n\t\tfor (Iter j = first; j != last; ++j) {\n\t\t\tCHECK(!comp(*j, *p.min));\n\t\t\tCHECK(!comp(*p.max, *j));\n\t\t}\n\t} else {\n\t\tCHECK(p.min == last);\n\t\tCHECK(p.max == last);\n\t}\n\n\tauto rng = ranges::subrange(first, last);\n\tp = ranges::minmax_element(rng, comp);\n\tif (first != last) {\n\t\tfor (Iter j = first; j != last; ++j) {\n\t\t\tCHECK(!comp(*j, *p.min));\n\t\t\tCHECK(!comp(*p.max, *j));\n\t\t}\n\t} else {\n\t\tCHECK(p.min == last);\n\t\tCHECK(p.max == last);\n\t}\n\n\tauto res = ranges::minmax_element(std::move(rng), comp);\n\tif (first != last) {\n\t\tfor (Iter j = first; j != last; ++j) {\n\t\t\tCHECK(!comp(*j, *res.min));\n\t\t\tCHECK(!comp(*res.max, *j));\n\t\t}\n\t} else {\n\t\tCHECK(res.min == last);\n\t\tCHECK(res.max == last);\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter_comp(unsigned N) {\n\tstd::unique_ptr<int[]> a{new int[N]};\n\tstd::iota(a.get(), a.get()+N, 0);\n\tstd::shuffle(a.get(), a.get()+N, gen);\n\ttest_iter_comp(Iter(a.get()), Sent(a.get()+N));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter_comp() {\n\ttest_iter_comp<Iter, Sent>(0);\n\ttest_iter_comp<Iter, Sent>(1);\n\ttest_iter_comp<Iter, Sent>(2);\n\ttest_iter_comp<Iter, Sent>(3);\n\ttest_iter_comp<Iter, Sent>(10);\n\ttest_iter_comp<Iter, Sent>(1000);\n\n\t{\n\t\tconst unsigned N = 100;\n\t\tstd::unique_ptr<int[]> a{new int[N]};\n\t\tstd::fill_n(a.get(), N, 5);\n\t\tstd::shuffle(a.get(), a.get()+N, gen);\n\t\ttypedef std::greater<int> Compare;\n\t\tCompare comp;\n\t\tranges::minmax_result<Iter> p =\n\t\t\tranges::minmax_element(Iter(a.get()), Sent(a.get()+N), comp);\n\t\tCHECK(base(p.min) == a.get());\n\t\tCHECK(base(p.max) == a.get()+N-1);\n\t}\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<bidirectional_iterator<const int*> >();\n\ttest_iter<random_access_iterator<const int*> >();\n\ttest_iter<const int*>();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_iter<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\t// Works with projections?\n\tS s[] = {S{1},S{2},S{3},S{4},S{-4},S{5},S{6},S{40},S{7},S{8},S{9}};\n\tranges::minmax_result<S const *> ps =\n\t\tranges::minmax_element(s, std::less<int>{}, &S::i);\n\tCHECK(ps.min->i == -4);\n\tCHECK(ps.max->i == 40);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/mismatch.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/mismatch.hpp>\n#include <memory>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class I1, class I2>\n\tconstexpr bool operator==(mismatch_result<I1, I2> const& x, mismatch_result<I1, I2> const& y) {\n\t\treturn x.in1 == y.in1 && x.in2 == y.in2;\n\t}\n} STL2_CLOSE_NAMESPACE\n\nnamespace ranges = __stl2;\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_range() {\n\tusing S = ranges::subrange<Iter, Sent>;\n\tusing R = ranges::mismatch_result<Iter, Iter>;\n\n\tauto test = [](S&& r1, S&& r2, const R& result) {\n\t\tusing ranges::begin;\n\t\tusing ranges::end;\n\t\tusing ranges::mismatch;\n\n\t\tauto copy_of = [](const auto& x) { return x; };\n\n\t\tCHECK(mismatch(begin(r1), end(r1), begin(r2), end(r2)) == result);\n\t\tCHECK(mismatch(r1, r2) == result);\n\t\tCHECK(mismatch(r1, r2, std::equal_to<int>{}) == result);\n\t\tCHECK(mismatch(copy_of(r1), r2) == result);\n\t\tCHECK(mismatch(copy_of(r1), r2, std::equal_to<int>{}) == result);\n\t\tCHECK(mismatch(r1, copy_of(r2)) == result);\n\t\tCHECK(mismatch(r1, copy_of(r2), std::equal_to<int>{}) == result);\n\t\tCHECK(mismatch(copy_of(r1), copy_of(r2)) == result);\n\t\tCHECK(mismatch(copy_of(r1), copy_of(r2), std::equal_to<int>{}) == result);\n\t};\n\n\tconst int ia[] = {0, 1, 2, 2, 0, 1, 2, 3};\n\tconstexpr auto sa = ranges::distance(ia);\n\tconst int ib[] = {0, 1, 2, 3, 0, 1, 2, 3};\n\tstatic_assert(sa == ranges::distance(ib));\n\n\ttest(S{Iter(ia), Sent(ia + sa)}, S{Iter(ib), Sent(ib + sa)}, R{Iter(ia+3), Iter(ib+3)});\n\ttest(S{Iter(ia), Sent(ia + sa)}, S{Iter(ib), Sent(ib + 2)}, R{Iter(ia+2), Iter(ib+2)});\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest_range<input_iterator<const int*>>();\n\ttest_range<forward_iterator<const int*>>();\n\ttest_range<bidirectional_iterator<const int*>>();\n\ttest_range<random_access_iterator<const int*>>();\n\ttest_range<const int*>();\n\ttest_range<input_iterator<const int*>, sentinel<const int*>>();\n\ttest_range<forward_iterator<const int*>, sentinel<const int*>>();\n\ttest_range<bidirectional_iterator<const int*>, sentinel<const int*>>();\n\ttest_range<random_access_iterator<const int*>, sentinel<const int*>>();\n\n\t// Works with projections?\n\tS s1[] = {S{1}, S{2}, S{3}, S{4}, S{-4}, S{5}, S{6}, S{40}, S{7}, S{8}, S{9}};\n\tint const i1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};\n\t{\n\t\tranges::mismatch_result<S const*, int const*> ps1\n\t\t\t= ranges::mismatch(s1, i1, std::equal_to<int>(), &S::i);\n\t\tCHECK(ps1.in1->i == -4);\n\t\tCHECK(*ps1.in2 == 5);\n\t}\n\t{\n\t\tranges::mismatch_result<S const*, int const*> ps1\n\t\t\t= ranges::mismatch(ranges::begin(s1), ranges::end(s1),\n\t\t\t\tranges::begin(i1), ranges::end(i1), std::equal_to<int>(), &S::i);\n\t\tCHECK(ps1.in1->i == -4);\n\t\tCHECK(*ps1.in2 == 5);\n\t}\n\n\tS s2[] = {S{1}, S{2}, S{3}, S{4}, S{5}, S{6}, S{40}, S{7}, S{8}, S{9}};\n\t{\n\t\tranges::mismatch_result<S const*, S const*> ps2\n\t\t\t= ranges::mismatch(s1, s2, std::equal_to<int>(), &S::i, &S::i);\n\t\tCHECK(ps2.in1->i == -4);\n\t\tCHECK(ps2.in2->i == 5);\n\t}\n\t{\n\t\tranges::mismatch_result<S const*, S const*> ps2\n\t\t\t= ranges::mismatch(ranges::begin(s1), ranges::end(s1),\n\t\t\t\tranges::begin(s2), ranges::end(s2), std::equal_to<int>(), &S::i, &S::i);\n\t\tCHECK(ps2.in1->i == -4);\n\t\tCHECK(ps2.in2->i == 5);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/move.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/move.hpp>\n#include <stl2/view/subrange.hpp>\n#include <memory>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<typename InIter, typename OutIter, typename Sent = InIter>\nvoid test() {\n\t{\n\t\tconst int N = 1000;\n\t\tint ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i] = i;\n\t\tint ib[N] = {0};\n\n\t\tranges::move_result<InIter, OutIter> r =\n\t\t\tranges::move(InIter(ia), Sent(ia+N), OutIter(ib));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib+N);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tCHECK(ia[i] == ib[i]);\n\t}\n\n\t{\n\t\tconst int N = 1000;\n\t\tint ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i] = i;\n\t\tint ib[N] = {0};\n\n\t\tranges::move_result<InIter, OutIter> r =\n\t\t\tranges::move(as_lvalue(ranges::subrange(InIter(ia), Sent(ia+N))), OutIter(ib));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib+N);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tCHECK(ia[i] == ib[i]);\n\t}\n}\n\nstruct S {\n\tstd::unique_ptr<int> p;\n};\n\ntemplate<typename InIter, typename OutIter, typename Sent = InIter>\nvoid test1() {\n\t{\n\t\tconst int N = 100;\n\t\tstd::unique_ptr<int> ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i].reset(new int(i));\n\t\tstd::unique_ptr<int> ib[N];\n\n\t\tranges::move_result<InIter, OutIter> r =\n\t\t\tranges::move(InIter(ia), Sent(ia+N), OutIter(ib));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib+N);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t{\n\t\t\tCHECK(ia[i].get() == nullptr);\n\t\t\tCHECK(*ib[i] == i);\n\t\t}\n\t}\n\n\t{\n\t\tconst int N = 100;\n\t\tstd::unique_ptr<int> ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i].reset(new int(i));\n\t\tstd::unique_ptr<int> ib[N];\n\n\t\tranges::move_result<InIter, OutIter> r =\n\t\t\tranges::move(as_lvalue(ranges::subrange(InIter(ia), Sent(ia+N))), OutIter(ib));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib+N);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t{\n\t\t\tCHECK(ia[i].get() == nullptr);\n\t\t\tCHECK(*ib[i] == i);\n\t\t}\n\n\t\tranges::move(ib, ib+N, ia);\n\n\t\tauto r2 = ranges::move(ranges::subrange(InIter(ia), Sent(ia+N)), OutIter(ib));\n\t\tCHECK(base(r2.in) == ia+N);\n\t\tCHECK(base(r2.out) == ib+N);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t{\n\t\t\tCHECK(ia[i].get() == nullptr);\n\t\t\tCHECK(*ib[i] == i);\n\t\t}\n\t}\n}\n\nint main() {\n\ttest<input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*> >();\n\ttest<const int*, input_iterator<int*> >();\n\ttest<const int*, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<int*> >();\n\ttest<const int*, int*>();\n\n\ttest<input_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, input_iterator<int*>, sentinel<const int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<int*>, sentinel<const int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*> >();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*> >();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*> >();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*> >();\n\n\ttest1<input_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<forward_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<std::unique_ptr<int>*, output_iterator<std::unique_ptr<int>*> >();\n\ttest1<std::unique_ptr<int>*, input_iterator<std::unique_ptr<int>*> >();\n\ttest1<std::unique_ptr<int>*, forward_iterator<std::unique_ptr<int>*> >();\n\ttest1<std::unique_ptr<int>*, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<std::unique_ptr<int>*, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<std::unique_ptr<int>*, std::unique_ptr<int>*>();\n\n\ttest1<input_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<input_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<forward_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<forward_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, output_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, input_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*> >();\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/move_backward.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/move_backward.hpp>\n#include <memory>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<typename InIter, typename OutIter>\nvoid test() {\n\t{\n\t\tconst int N = 1000;\n\t\tint ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i] = i;\n\t\tint ib[N] = {0};\n\n\t\tranges::move_backward_result<InIter, OutIter> r =\n\t\t\tranges::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tCHECK(ia[i] == ib[i]);\n\t}\n\n\t{\n\t\tconst int N = 1000;\n\t\tint ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i] = i;\n\t\tint ib[N] = {0};\n\n\t\tranges::move_backward_result<InIter, OutIter> r =\n\t\t\tranges::move_backward(as_lvalue(ranges::subrange(InIter(ia), InIter(ia+N))), OutIter(ib+N));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tCHECK(ia[i] == ib[i]);\n\t}\n}\n\nstruct S {\n\tstd::unique_ptr<int> p;\n};\n\ntemplate<typename InIter, typename OutIter>\nvoid test1() {\n\t{\n\t\tconst int N = 100;\n\t\tstd::unique_ptr<int> ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i].reset(new int(i));\n\t\tstd::unique_ptr<int> ib[N];\n\n\t\tranges::move_backward_result<InIter, OutIter> r =\n\t\t\tranges::move_backward(InIter(ia), InIter(ia+N), OutIter(ib+N));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t{\n\t\t\tCHECK(ia[i].get() == nullptr);\n\t\t\tCHECK(*ib[i] == i);\n\t\t}\n\t}\n\n\t{\n\t\tconst int N = 100;\n\t\tstd::unique_ptr<int> ia[N];\n\t\tfor(int i = 0; i < N; ++i)\n\t\t\tia[i].reset(new int(i));\n\t\tstd::unique_ptr<int> ib[N];\n\n\t\tranges::move_backward_result<InIter, OutIter> r =\n\t\t\tranges::move_backward(as_lvalue(ranges::subrange(InIter(ia), InIter(ia+N))), OutIter(ib+N));\n\t\tCHECK(base(r.in) == ia+N);\n\t\tCHECK(base(r.out) == ib);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t{\n\t\t\tCHECK(ia[i].get() == nullptr);\n\t\t\tCHECK(*ib[i] == i);\n\t\t}\n\n\t\tranges::move_backward(ib, ib+N, ia+N);\n\n\t\tauto r2 = ranges::move_backward(ranges::subrange(InIter(ia), InIter(ia+N)), OutIter(ib+N));\n\t\tCHECK(base(r2.in) == ia+N);\n\t\tCHECK(base(r2.out) == ib);\n\t\tfor(int i = 0; i < N; ++i)\n\t\t{\n\t\t\tCHECK(ia[i].get() == nullptr);\n\t\t\tCHECK(*ib[i] == i);\n\t\t}\n\t}\n}\n\nint main() {\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<int*> >();\n\ttest<const int*, int*>();\n\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<bidirectional_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<random_access_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest1<std::unique_ptr<int>*, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest1<std::unique_ptr<int>*, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest1<std::unique_ptr<int>*, std::unique_ptr<int>*>();\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/next_permutation.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/next_permutation.hpp>\n#include <stl2/detail/concepts/fundamental.hpp>\n#include <cstring>\n#include <utility>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<ranges::integral T>\nconstexpr auto factorial(T x)\n{\n\tdecltype(x) r = 1;\n\tfor (; 1 < x; --x)\n\t\tr *= x;\n\treturn r;\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_iter()\n{\n\tint ia[] = {1, 2, 3, 4, 5, 6};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor (int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::next_permutation(Iter(ia), Sent(ia+e));\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif(x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));\n\t\t\t}\n\t\t\t++count;\n\t\t} while(x);\n\t\tCHECK(count == factorial(e));\n\t}\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_range()\n{\n\tint ia[] = {1, 2, 3, 4, 5, 6};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor (int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::next_permutation(ranges::subrange(Iter(ia), Sent(ia+e)));\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif(x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));\n\t\t\t}\n\t\t\t++count;\n\t\t} while(x);\n\t\tCHECK(count == factorial(e));\n\t}\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_iter_comp()\n{\n\ttypedef std::greater<int> C;\n\tint ia[] = {6, 5, 4, 3, 2, 1};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor(int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::next_permutation(Iter(ia), Sent(ia+e), C());\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif (x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));\n\t\t\t}\n\t\t\t++count;\n\t\t} while (x);\n\t\tCHECK(count == factorial(e));\n\t}\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_range_comp()\n{\n\ttypedef std::greater<int> C;\n\tint ia[] = {6, 5, 4, 3, 2, 1};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor(int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::next_permutation(ranges::subrange(Iter(ia), Sent(ia+e)), C());\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif (x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));\n\t\t\t}\n\t\t\t++count;\n\t\t} while (x);\n\t\t\tCHECK(count == factorial(e));\n\t}\n}\n\nstruct c_str\n{\n\tchar const * value;\n\n\tfriend bool operator==(c_str a, c_str b)\n\t{\n\t\treturn 0 == std::strcmp(a.value, b.value);\n\t}\n\n\tfriend bool operator!=(c_str a, c_str b)\n\t{\n\t\treturn !(a == b);\n\t}\n};\n\n// For debugging the projection test\nstd::ostream &operator<<(std::ostream& sout, std::pair<int, c_str> p)\n{\n\treturn sout << \"{\" << p.first << \",\" << p.second.value << \"}\";\n}\n\nint main()\n{\n\ttest_iter<bidirectional_iterator<int*> >();\n\ttest_iter<random_access_iterator<int*> >();\n\ttest_iter<int*>();\n\n\ttest_iter<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_iter<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_iter_comp<bidirectional_iterator<int*> >();\n\ttest_iter_comp<random_access_iterator<int*> >();\n\ttest_iter_comp<int*>();\n\n\ttest_iter_comp<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_iter_comp<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_range<bidirectional_iterator<int*> >();\n\ttest_range<random_access_iterator<int*> >();\n\ttest_range<int*>();\n\n\ttest_range<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_range<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_range_comp<bidirectional_iterator<int*> >();\n\ttest_range_comp<random_access_iterator<int*> >();\n\ttest_range_comp<int*>();\n\n\ttest_range_comp<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_range_comp<random_access_iterator<int*>, sentinel<int*> >();\n\n\t// Test projection\n\n\ttypedef std::greater<int> C;\n\tstd::pair<int, c_str> ia[] = {{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {3,{\"three\"}}, {2,{\"two\"}}, {1,{\"one\"}}};\n\tCHECK(ranges::next_permutation(ia, C(), &std::pair<int,c_str>::first));\n\tCHECK_EQUAL(ia, {std::pair<int, c_str>{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {3,{\"three\"}}, {1,{\"one\"}}, {2,{\"two\"}}});\n\tCHECK(ranges::next_permutation(ia, C(), &std::pair<int,c_str>::first));\n\tCHECK_EQUAL(ia, {std::pair<int, c_str>{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {2,{\"two\"}}, {3,{\"three\"}}, {1,{\"one\"}}});\n\tCHECK(ranges::next_permutation(ia, C(), &std::pair<int,c_str>::first));\n\tCHECK_EQUAL(ia, {std::pair<int, c_str>{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {2,{\"two\"}}, {1,{\"one\"}}, {3,{\"three\"}}});\n\t// etc..\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/none_of.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Andrew Sutton 2014\n//  Copyright Gonzalo Brito Gadeschi 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n#include <stl2/detail/algorithm/none_of.hpp>\n\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = std::experimental::ranges;\n\nbool even(int n) { return n % 2 == 0; }\n\nstruct S {\n\tS(bool p) : test(p) { }\n\n\tbool p() const { return test; }\n\n\tbool test;\n};\n\nint main()\n{\n\tstd::vector<int> all_even { 0, 2, 4, 6 };\n\tstd::vector<int> one_even { 1, 3, 4, 7 };\n\tstd::vector<int> none_even { 1, 3, 5, 7 };\n\tCHECK(!ranges::none_of(all_even.begin(), all_even.end(), even));\n\tCHECK(!ranges::none_of(one_even.begin(), one_even.end(), even));\n\tCHECK(ranges::none_of(none_even.begin(), none_even.end(), even));\n\n\tCHECK(!ranges::none_of(all_even, even));\n\tCHECK(!ranges::none_of(one_even, even));\n\tCHECK(ranges::none_of(none_even, even));\n\n\t{\n\t\tauto il = {0, 2, 4, 6};\n\t\tCHECK(!ranges::none_of(std::move(il), [](int n) { return n % 2 == 0; }));\n\t}\n\t{\n\t\tauto il = {1, 3, 4, 7};\n\t\tCHECK(!ranges::none_of(std::move(il), [](int n) { return n % 2 == 0; }));\n\t}\n\t{\n\t\tauto il = {1, 3, 5, 7};\n\t\tCHECK(ranges::none_of(std::move(il), [](int n) { return n % 2 == 0; }));\n\t}\n\n\tstd::vector<S> all_true { true, true, true };\n\tstd::vector<S> one_true { false, false, true };\n\tstd::vector<S> none_true { false, false, false };\n\tCHECK(!ranges::none_of(all_true.begin(), all_true.end(), &S::p));\n\tCHECK(!ranges::none_of(one_true.begin(), one_true.end(), &S::p));\n\tCHECK(ranges::none_of(none_true.begin(), none_true.end(), &S::p));\n\n\tCHECK(!ranges::none_of(all_true, &S::p));\n\tCHECK(!ranges::none_of(one_true, &S::p));\n\tCHECK(ranges::none_of(none_true, &S::p));\n\n\t{\n\t\tauto il = {S(true), S(true), S(true)};\n\t\tCHECK(!ranges::none_of(std::move(il), &S::p));\n\t}\n\t{\n\t\tauto il = {S(false), S(true), S(false)};\n\t\tCHECK(!ranges::none_of(std::move(il), &S::p));\n\t}\n\t{\n\t\tauto il = {S(false), S(false), S(false)};\n\t\tCHECK(ranges::none_of(std::move(il), &S::p));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/nth_element.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/nth_element.hpp>\n#include <cassert>\n#include <memory>\n#include <random>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\nvoid\ntest_one(unsigned N, unsigned M)\n{\n\tassert(N != 0);\n\tassert(M < N);\n\tstd::unique_ptr<int[]> array{new int[N]};\n\tfor (int i = 0; (unsigned)i < N; ++i)\n\t\tarray[i] = i;\n\tstd::shuffle(array.get(), array.get()+N, gen);\n\tCHECK(stl2::nth_element(array.get(), array.get()+M, array.get()+N) == array.get()+N);\n\tCHECK((unsigned)array[M] == M);\n\tstd::shuffle(array.get(), array.get()+N, gen);\n\tCHECK(stl2::nth_element(::as_lvalue(stl2::subrange(array.get(), array.get()+N)), array.get()+M) == array.get()+N);\n\tCHECK((unsigned)array[M] == M);\n\tstd::shuffle(array.get(), array.get()+N, gen);\n\tCHECK(stl2::nth_element(stl2::subrange(array.get(), array.get()+N), array.get()+M) == array.get()+N);\n\tCHECK((unsigned)array[M] == M);\n\tstl2::nth_element(array.get(), array.get()+N, array.get()+N); // begin, end, end\n}\n\nvoid\ntest(unsigned N)\n{\n\ttest_one(N, 0);\n\ttest_one(N, 1);\n\ttest_one(N, 2);\n\ttest_one(N, 3);\n\ttest_one(N, N/2-1);\n\ttest_one(N, N/2);\n\ttest_one(N, N/2+1);\n\ttest_one(N, N-3);\n\ttest_one(N, N-2);\n\ttest_one(N, N-1);\n}\n\nstruct S\n{\n\tint i,j;\n};\n\nint main()\n{\n\tint d = 0;\n\tstl2::nth_element(&d, &d, &d);\n\tCHECK(d == 0);\n\ttest(256);\n\ttest(257);\n\ttest(499);\n\ttest(500);\n\ttest(997);\n\ttest(1000);\n\ttest(1009);\n\n\t// Works with projections?\n\tconst int N = 257;\n\tconst int M = 56;\n\tS ia[N];\n\tfor(int i = 0; i < N; ++i)\n\t\tia[i].i = ia[i].j = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstl2::nth_element(ia, ia+M, std::less<int>(), &S::i);\n\tCHECK(ia[M].i == M);\n\tCHECK(ia[M].j == M);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/partial_sort.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/partial_sort.hpp>\n#include <cassert>\n#include <memory>\n#include <random>\n#include <algorithm>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\nstruct indirect_less\n{\n\ttemplate<class P>\n\tbool operator()(const P& x, const P& y) const { return *x < *y; }\n};\n\nvoid\ntest_larger_sorts(int N, int M)\n{\n\tassert(N > 0);\n\tassert(M >= 0 && M <= N);\n\tint* array = new int[N];\n\tfor(int i = 0; i < N; ++i)\n\t\tarray[i] = i;\n\n\tusing I = random_access_iterator<int*>;\n\tusing S = sentinel<int*>;\n\n\tstd::shuffle(array, array+N, gen);\n\tint *res = stl2::partial_sort(array, array+M, array+N);\n\tCHECK(res == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == i);\n\n\tstd::shuffle(array, array+N, gen);\n\tI res2 = stl2::partial_sort(I{array}, I{array+M}, S{array+N});\n\tCHECK(res2.base() == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == i);\n\n\tstd::shuffle(array, array+N, gen);\n\tres = stl2::partial_sort(::as_lvalue(stl2::subrange(array, array+N)), array+M);\n\tCHECK(res == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == i);\n\n\tstd::shuffle(array, array+N, gen);\n\tres2 = stl2::partial_sort(::as_lvalue(stl2::subrange(I{array}, S{array+N})), I{array+M});\n\tCHECK(res2.base() == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == i);\n\n\tstd::shuffle(array, array+N, gen);\n\tauto res3 = stl2::partial_sort(stl2::subrange(array, array+N), array+M);\n\tCHECK(res3 == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == i);\n\n\tstd::shuffle(array, array+N, gen);\n\tauto res4 = stl2::partial_sort(stl2::subrange(I{array}, S{array+N}), I{array+M});\n\tCHECK(res4.base() == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == i);\n\n\tstd::shuffle(array, array+N, gen);\n\tres = stl2::partial_sort(array, array+M, array+N, std::greater<int>());\n\tCHECK(res == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == N-i-1);\n\n\tstd::shuffle(array, array+N, gen);\n\tres2 = stl2::partial_sort(I{array}, I{array+M}, S{array+N}, std::greater<int>());\n\tCHECK(res2.base() == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == N-i-1);\n\n\tstd::shuffle(array, array+N, gen);\n\tres = stl2::partial_sort(::as_lvalue(stl2::subrange(array, array+N)), array+M, std::greater<int>());\n\tCHECK(res == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == N-i-1);\n\n\tstd::shuffle(array, array+N, gen);\n\tres2 = stl2::partial_sort(::as_lvalue(stl2::subrange(I{array}, S{array+N})), I{array+M}, std::greater<int>());\n\tCHECK(res2.base() == array+N);\n\tfor(int i = 0; i < M; ++i)\n\t\tCHECK(array[i] == N-i-1);\n\n\tdelete [] array;\n}\n\nvoid\ntest_larger_sorts(int N)\n{\n\ttest_larger_sorts(N, 0);\n\ttest_larger_sorts(N, 1);\n\ttest_larger_sorts(N, 2);\n\ttest_larger_sorts(N, 3);\n\ttest_larger_sorts(N, N/2-1);\n\ttest_larger_sorts(N, N/2);\n\ttest_larger_sorts(N, N/2+1);\n\ttest_larger_sorts(N, N-2);\n\ttest_larger_sorts(N, N-1);\n\ttest_larger_sorts(N, N);\n}\n\nstruct S\n{\n\tint i, j;\n};\n\nint main()\n{\n\tint i = 0;\n\tint * res = stl2::partial_sort(&i, &i, &i);\n\tCHECK(i == 0);\n\tCHECK(res == &i);\n\ttest_larger_sorts(10);\n\ttest_larger_sorts(256);\n\ttest_larger_sorts(257);\n\ttest_larger_sorts(499);\n\ttest_larger_sorts(500);\n\ttest_larger_sorts(997);\n\ttest_larger_sorts(1000);\n\ttest_larger_sorts(1009);\n\n\t// Check move-only types\n\t{\n\t\tstd::vector<std::unique_ptr<int> > v(1000);\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t\tv[i].reset(new int(v.size() - i - 1));\n\t\tstl2::partial_sort(v, v.begin() + v.size()/2, indirect_less());\n\t\tfor(int i = 0; (std::size_t)i < v.size()/2; ++i)\n\t\t\tCHECK(*v[i] == i);\n\t}\n\n\t// Check projections\n\t{\n\t\tstd::vector<S> v(1000, S{});\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tv[i].i = v.size() - i - 1;\n\t\t\tv[i].j = i;\n\t\t}\n\t\tstl2::partial_sort(v, v.begin() + v.size()/2, std::less<int>{}, &S::i);\n\t\tfor(int i = 0; (std::size_t)i < v.size()/2; ++i)\n\t\t{\n\t\t\tCHECK(v[i].i == i);\n\t\t\tCHECK((std::size_t)v[i].j == v.size() - i - 1);\n\t\t}\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/partial_sort_copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/partial_sort_copy.hpp>\n#include <cassert>\n#include <memory>\n#include <random>\n#include <vector>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace { std::mt19937 gen; }\n\ntemplate<class Iter>\nvoid\ntest_larger_sorts(int N, int M)\n{\n    auto partial_sort_copy = ::make_testable_2<true, false>([](auto&&... args) {\n        return ranges::partial_sort_copy(std::forward<decltype(args)>(args)...);\n    });\n    int* input = new int[N];\n    int* output = new int[M];\n    for (int i = 0; i < N; ++i)\n        input[i] = i;\n    std::shuffle(input, input+N, gen);\n    partial_sort_copy(Iter(input), Iter(input+N), output, output+M).check([&](int* r)\n    {\n        int* e = output + std::min(N, M);\n        CHECK(r == e);\n        int i = 0;\n        for (int* x = output; x < e; ++x, ++i)\n            CHECK(*x == i);\n        std::shuffle(input, input+N, gen);\n    });\n    partial_sort_copy(Iter(input), Iter(input+N), output, output+M, std::greater<int>()).check([&](int* r)\n    {\n        int* e = output + std::min(N, M);\n        CHECK(r == e);\n        int i = N-1;\n        for (int* x = output; x < e; ++x, --i)\n            CHECK(*x == i);\n        std::shuffle(input, input+N, gen);\n    });\n    delete [] output;\n    delete [] input;\n}\n\ntemplate<class Iter>\nvoid\ntest_larger_sorts(int N)\n{\n    test_larger_sorts<Iter>(N, 0);\n    test_larger_sorts<Iter>(N, 1);\n    test_larger_sorts<Iter>(N, 2);\n    test_larger_sorts<Iter>(N, 3);\n    test_larger_sorts<Iter>(N, N/2-1);\n    test_larger_sorts<Iter>(N, N/2);\n    test_larger_sorts<Iter>(N, N/2+1);\n    test_larger_sorts<Iter>(N, N-2);\n    test_larger_sorts<Iter>(N, N-1);\n    test_larger_sorts<Iter>(N, N);\n    test_larger_sorts<Iter>(N, N+1000);\n}\n\ntemplate<class Iter>\nvoid\ntest()\n{\n    test_larger_sorts<Iter>(0, 100);\n    test_larger_sorts<Iter>(10);\n    test_larger_sorts<Iter>(256);\n    test_larger_sorts<Iter>(257);\n    test_larger_sorts<Iter>(499);\n    test_larger_sorts<Iter>(500);\n    test_larger_sorts<Iter>(997);\n    test_larger_sorts<Iter>(1000);\n    test_larger_sorts<Iter>(1009);\n}\n\nstruct S\n{\n    int i;\n};\n\nstruct U\n{\n    int i;\n    U & operator=(S s)\n    {\n        i = s.i;\n        return *this;\n    }\n};\n\nint main()\n{\n    int i = 0;\n    int * r = ranges::partial_sort_copy(&i, &i, &i, &i+5);\n    CHECK(r == &i);\n    CHECK(i == 0);\n    test<input_iterator<const int*> >();\n    test<forward_iterator<const int*> >();\n    test<bidirectional_iterator<const int*> >();\n    test<random_access_iterator<const int*> >();\n    test<const int*>();\n\n    // Check projections\n    {\n        constexpr int N = 256;\n        constexpr int M = N/2-1;\n        S input[N];\n        U output[M];\n        for (int i = 0; i < N; ++i)\n            input[i].i = i;\n        std::shuffle(input, input+N, gen);\n        U* r = ranges::partial_sort_copy(input, output, std::less<int>(), &S::i, &U::i);\n        U* e = output + std::min(N, M);\n        CHECK(r == e);\n        int i = 0;\n        for (U* x = output; x < e; ++x, ++i)\n            CHECK(x->i == i);\n    }\n\n    // Check rvalue ranges\n    {\n        constexpr int N = 256;\n        constexpr int M = N/2-1;\n        S input[N];\n        U output[M];\n        for (int i = 0; i < N; ++i)\n            input[i].i = i;\n        std::shuffle(input, input+N, gen);\n        auto r = ranges::partial_sort_copy(input, std::move(output), std::less<int>(), &S::i, &U::i);\n        U* e = output + std::min(N, M);\n        static_assert(ranges::same_as<decltype(r), ranges::dangling>);\n        int i = 0;\n        for (U* x = output; x < e; ++x, ++i)\n            CHECK(x->i == i);\n    }\n\n    return ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/partition.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/partition.hpp>\n#include <memory>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct is_odd {\n\tbool operator()(const int& i) const {return i & 1;}\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter() {\n\t// check mixed\n\tint ia[] = {1, 2, 3, 4, 5, 6, 7, 8 ,9};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tIter r = ranges::partition(Iter(ia), Sent(ia + sa), is_odd());\n\tCHECK(base(r) == ia + 5);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check empty\n\tr = ranges::partition(Iter(ia), Sent(ia), is_odd());\n\tCHECK(base(r) == ia);\n\t// check all false\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i;\n\tr = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());\n\tCHECK(base(r) == ia);\n\t// check all true\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i+1;\n\tr = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());\n\tCHECK(base(r) == ia+sa);\n\t// check all true but last\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i+1;\n\tia[sa-1] = 10;\n\tr = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());\n\tCHECK(base(r) == ia+sa-1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check all true but first\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i+1;\n\tia[0] = 10;\n\tr = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());\n\tCHECK(base(r) == ia+sa-1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check all false but last\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i;\n\tia[sa-1] = 11;\n\tr = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());\n\tCHECK(base(r) == ia+1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check all false but first\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i;\n\tia[0] = 11;\n\tr = ranges::partition(Iter(ia), Sent(ia+sa), is_odd());\n\tCHECK(base(r) == ia+1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_range() {\n\t// check mixed\n\tint ia[] = {1, 2, 3, 4, 5, 6, 7, 8 ,9};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tIter r = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia + sa))), is_odd());\n\tCHECK(base(r) == ia + 5);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check empty\n\tr = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia))), is_odd());\n\tCHECK(base(r) == ia);\n\t// check all false\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i;\n\tr = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), is_odd());\n\tCHECK(base(r) == ia);\n\t// check all true\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i+1;\n\tr = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), is_odd());\n\tCHECK(base(r) == ia+sa);\n\t// check all true but last\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i+1;\n\tia[sa-1] = 10;\n\tr = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), is_odd());\n\tCHECK(base(r) == ia+sa-1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check all true but first\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i+1;\n\tia[0] = 10;\n\tr = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), is_odd());\n\tCHECK(base(r) == ia+sa-1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check all false but last\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i;\n\tia[sa-1] = 11;\n\tr = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), is_odd());\n\tCHECK(base(r) == ia+1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n\t// check all false but first\n\tfor (unsigned i = 0; i < sa; ++i)\n\t\tia[i] = 2*i;\n\tia[0] = 11;\n\tr = ranges::partition(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), is_odd());\n\tCHECK(base(r) == ia+1);\n\tfor (int* i = ia; i < base(r); ++i)\n\t\tCHECK(is_odd()(*i));\n\tfor (int* i = base(r); i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(*i));\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest_iter<forward_iterator<int*> >();\n\ttest_iter<bidirectional_iterator<int*> >();\n\ttest_iter<random_access_iterator<int*> >();\n\ttest_iter<int*>();\n\ttest_iter<forward_iterator<int*>, sentinel<int*> >();\n\ttest_iter<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_iter<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_range<forward_iterator<int*> >();\n\ttest_range<bidirectional_iterator<int*> >();\n\ttest_range<random_access_iterator<int*> >();\n\ttest_range<int*>();\n\ttest_range<forward_iterator<int*>, sentinel<int*> >();\n\ttest_range<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_range<random_access_iterator<int*>, sentinel<int*> >();\n\n\t// Test projections\n\tS ia[] = {S{1}, S{2}, S{3}, S{4}, S{5}, S{6}, S{7}, S{8} ,S{9}};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tS* r = ranges::partition(ia, is_odd(), &S::i);\n\tCHECK(r == ia + 5);\n\tfor (S* i = ia; i < r; ++i)\n\t\tCHECK(is_odd()(i->i));\n\tfor (S* i = r; i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(i->i));\n\n\t// Test rvalue range\n\tauto r2 = ranges::partition(ranges::subrange(ia), is_odd(), &S::i);\n\tCHECK(r2 == ia + 5);\n\tfor (S* i = ia; i < r2; ++i)\n\t\tCHECK(is_odd()(i->i));\n\tfor (S* i = r2; i < ia+sa; ++i)\n\t\tCHECK(!is_odd()(i->i));\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/partition_copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/partition_copy.hpp>\n#include <stl2/iterator.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct is_odd {\n\tconstexpr bool operator()(int i) const { return i & 1; }\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter() {\n\tconst int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};\n\tint r1[10] = {0};\n\tint r2[10] = {0};\n\tusing P = ranges::partition_copy_result<Iter, output_iterator<int*>, int*>;\n\tP p = ranges::partition_copy(Iter(std::begin(ia)),\n\t\t\t\t\t\t\t\t Sent(std::end(ia)),\n\t\t\t\t\t\t\t\t output_iterator<int*>(r1), r2, is_odd());\n\tCHECK(p.in == Iter(std::end(ia)));\n\tCHECK(p.out1.base() == r1 + 4);\n\tCHECK(r1[0] == 1);\n\tCHECK(r1[1] == 3);\n\tCHECK(r1[2] == 5);\n\tCHECK(r1[3] == 7);\n\tCHECK(p.out2 == r2 + 4);\n\tCHECK(r2[0] == 2);\n\tCHECK(r2[1] == 4);\n\tCHECK(r2[2] == 6);\n\tCHECK(r2[3] == 8);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_range() {\n\tconst int ia[] = {1, 2, 3, 4, 6, 8, 5, 7};\n\tint r1[10] = {0};\n\tint r2[10] = {0};\n\tusing P = ranges::partition_copy_result<Iter, output_iterator<int*>, int*>;\n\tauto s1 = ranges::subrange{Iter(std::begin(ia)), Sent(std::end(ia))};\n\tP p = ranges::partition_copy(s1, output_iterator<int*>(r1), r2, is_odd());\n\tCHECK(p.in == Iter(std::end(ia)));\n\tCHECK(p.out1.base() == r1 + 4);\n\tCHECK(r1[0] == 1);\n\tCHECK(r1[1] == 3);\n\tCHECK(r1[2] == 5);\n\tCHECK(r1[3] == 7);\n\tCHECK(p.out2 == r2 + 4);\n\tCHECK(r2[0] == 2);\n\tCHECK(r2[1] == 4);\n\tCHECK(r2[2] == 6);\n\tCHECK(r2[3] == 8);\n}\n\nstruct S {\n\tint i;\n};\n\nvoid test_proj() {\n\t// Test projections\n\tconst S ia[] = {S{1}, S{2}, S{3}, S{4}, S{6}, S{8}, S{5}, S{7}};\n\tS r1[10] = {S{0}};\n\tS r2[10] = {S{0}};\n\tusing P = ranges::partition_copy_result<S const*, S*, S*>;\n\tP p = ranges::partition_copy(ia, r1, r2, is_odd(), &S::i);\n\tCHECK(p.in == std::end(ia));\n\tCHECK(p.out1 == r1 + 4);\n\tCHECK(r1[0].i == 1);\n\tCHECK(r1[1].i == 3);\n\tCHECK(r1[2].i == 5);\n\tCHECK(r1[3].i == 7);\n\tCHECK(p.out2 == r2 + 4);\n\tCHECK(r2[0].i == 2);\n\tCHECK(r2[1].i == 4);\n\tCHECK(r2[2].i == 6);\n\tCHECK(r2[3].i == 8);\n}\n\nvoid test_rvalue() {\n\t// Test rvalue ranges\n\tconst S ia[] = {S{1}, S{2}, S{3}, S{4}, S{6}, S{8}, S{5}, S{7}};\n\tS r1[10] = {S{0}};\n\tS r2[10] = {S{0}};\n\tauto p = ranges::partition_copy(std::move(ia), r1, r2, is_odd(), &S::i);\n\tstatic_assert(ranges::same_as<decltype(p.in), ranges::dangling>);\n\tCHECK(p.out1 == r1 + 4);\n\tCHECK(r1[0].i == 1);\n\tCHECK(r1[1].i == 3);\n\tCHECK(r1[2].i == 5);\n\tCHECK(r1[3].i == 7);\n\tCHECK(p.out2 == r2 + 4);\n\tCHECK(r2[0].i == 2);\n\tCHECK(r2[1].i == 4);\n\tCHECK(r2[2].i == 6);\n\tCHECK(r2[3].i == 8);\n}\n\nint main() {\n\ttest_iter<input_iterator<const int*> >();\n\ttest_iter<input_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_range<input_iterator<const int*> >();\n\ttest_range<input_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_proj();\n\ttest_rvalue();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/partition_point.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/partition_point.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/view/iota.hpp>\n#include <memory>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct is_odd {\n\tconstexpr bool operator()(int i) const noexcept {\n\t\treturn i % 2 != 0;\n\t}\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter() {\n\t{\n\t\tconst int ia[] = {2, 4, 6, 8, 10};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)), is_odd()) == Iter(ia));\n\t}\n\t{\n\t\tconst int ia[] = {1, 2, 4, 6, 8};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)), is_odd()) == Iter(ia + 1));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 2, 4, 6};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)), is_odd()) == Iter(ia + 2));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)), is_odd()) == Iter(ia + 3));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 2, 4};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)), is_odd()) == Iter(ia + 4));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 9, 2};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)), is_odd()) == Iter(ia + 5));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 9, 11};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)), is_odd()) == Iter(ia + 6));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6, 7};\n\t\tCHECK(ranges::partition_point(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::begin(ia)), is_odd()) == Iter(ia));\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_range() {\n\t{\n\t\tconst int ia[] = {2, 4, 6, 8, 10};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)))), is_odd()) == Iter(ia));\n\t}\n\t{\n\t\tconst int ia[] = {1, 2, 4, 6, 8};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)))), is_odd()) == Iter(ia + 1));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 2, 4, 6};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)))), is_odd()) == Iter(ia + 2));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)))), is_odd()) == Iter(ia + 3));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 2, 4};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)))), is_odd()) == Iter(ia + 4));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 9, 2};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)))), is_odd()) == Iter(ia + 5));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 9, 11};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia)))), is_odd()) == Iter(ia + 6));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6, 7};\n\t\tCHECK(ranges::partition_point(::as_lvalue(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::begin(ia)))), is_odd()) == Iter(ia));\n\t}\n\n\t// An rvalue range\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 9, 2};\n\t\tCHECK(ranges::partition_point(ranges::subrange(Iter(ranges::begin(ia)),\n\t\t\tSent(ranges::end(ia))), is_odd()) == Iter(ia + 5));\n\t}\n}\n\ntemplate<ranges::input_or_output_iterator I>\nranges::subrange<ranges::counted_iterator<I>, ranges::default_sentinel_t>\nmake_counted_view(I i, ranges::iter_difference_t<I> n) {\n\treturn {ranges::counted_iterator{std::move(i), n}, {}};\n}\n\ntemplate<class Iter>\nvoid test_counted() {\n\t{\n\t\tconst int ia[] = {2, 4, 6, 8, 10};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\tranges::distance(ia))), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia),\n\t\t\tranges::distance(ia)));\n\t}\n\t{\n\t\tconst int ia[] = {1, 2, 4, 6, 8};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\tranges::distance(ia))), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 1),\n\t\t\tranges::distance(ia) - 1));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 2, 4, 6};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\tranges::distance(ia))), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 2),\n\t\t\tranges::distance(ia) - 2));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\tranges::distance(ia))), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 3),\n\t\t\tranges::distance(ia) - 3));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 2, 4};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\tranges::distance(ia))), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 4),\n\t\t\tranges::distance(ia) - 4));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 9, 2};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\tranges::distance(ia))), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 5),\n\t\t\tranges::distance(ia) - 5));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 7, 9, 11};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\tranges::distance(ia))), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia + 6),\n\t\t\tranges::distance(ia) - 6));\n\t}\n\t{\n\t\tconst int ia[] = {1, 3, 5, 2, 4, 6, 7};\n\t\tCHECK(ranges::partition_point(::as_lvalue(make_counted_view(Iter(ranges::begin(ia)),\n\t\t\t0)), is_odd()) == ranges::counted_iterator<Iter>(Iter(ia), 0));\n\t}\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest_iter<forward_iterator<const int*> >();\n\ttest_iter<forward_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_range<forward_iterator<const int*> >();\n\ttest_range<forward_iterator<const int*>, sentinel<const int*>>();\n\n\ttest_counted<forward_iterator<const int*> >();\n\n\t// Test projections\n\tconst S ia[] = {S{1}, S{3}, S{5}, S{2}, S{4}, S{6}};\n\tCHECK(ranges::partition_point(ia, is_odd(), &S::i) == ia + 3);\n\n\t// Test infinite ranges\n\tCHECK(*ranges::partition_point(ranges::iota_view<int>{0},\n\t\t[](int i){ return i < 42; }) == 42);\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/pop_heap.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/pop_heap.hpp>\n#include <memory>\n#include <random>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\nvoid test_1(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(ia, ia+i) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1));\n\t}\n\tCHECK(stl2::pop_heap(ia, ia) == ia);\n\tdelete [] ia;\n}\n\nvoid test_2(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(ia, sentinel<int*>(ia+i)) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1));\n\t}\n\tCHECK(stl2::pop_heap(ia, ia) == ia);\n\tdelete [] ia;\n}\n\nvoid test_3(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(::as_lvalue(stl2::subrange(ia, ia+i))) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1));\n\t}\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(stl2::subrange(ia, ia+i)) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1));\n\t}\n\tCHECK(stl2::pop_heap(ia, ia) == ia);\n\tdelete [] ia;\n}\n\nvoid test_4(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(::as_lvalue(stl2::subrange(ia, sentinel<int*>(ia+i)))) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1));\n\t}\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(stl2::subrange(ia, sentinel<int*>(ia+i))) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1));\n\t}\n\tCHECK(stl2::pop_heap(ia, ia) == ia);\n\tdelete [] ia;\n}\n\nvoid test_5(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(ia, ia+i, std::greater<int>()) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));\n\t}\n\tCHECK(stl2::pop_heap(ia, ia, std::greater<int>()) == ia);\n\tdelete [] ia;\n}\n\nvoid test_6(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(ia, sentinel<int*>(ia+i), std::greater<int>()) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));\n\t}\n\tCHECK(stl2::pop_heap(ia, sentinel<int*>(ia), std::greater<int>()) == ia);\n\tdelete [] ia;\n}\n\nvoid test_7(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(::as_lvalue(stl2::subrange(ia, ia+i)), std::greater<int>()) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));\n\t}\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(stl2::subrange(ia, ia+i), std::greater<int>()) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));\n\t}\n\tCHECK(stl2::pop_heap(ia, ia, std::greater<int>()) == ia);\n\tdelete [] ia;\n}\n\nvoid test_8(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(::as_lvalue(stl2::subrange(ia, sentinel<int*>(ia+i))), std::greater<int>()) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));\n\t}\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(stl2::subrange(ia, sentinel<int*>(ia+i)), std::greater<int>()) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1, std::greater<int>()));\n\t}\n\tCHECK(stl2::pop_heap(ia, sentinel<int*>(ia), std::greater<int>()) == ia);\n\tdelete [] ia;\n}\n\nstruct indirect_less\n{\n\ttemplate<class P>\n\tbool operator()(const P& x, const P& y) const\n\t\t{return *x < *y;}\n};\n\nvoid test_9(int N)\n{\n\tstd::unique_ptr<int>* ia = new std::unique_ptr<int> [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i].reset(new int(i));\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, indirect_less());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(ia, ia+i, indirect_less()) == ia+i);\n\t\tCHECK(std::is_heap(ia, ia+i-1, indirect_less()));\n\t}\n\tdelete [] ia;\n}\n\ntemplate<typename T>\nstruct construct\n{\n\ttemplate<typename ...Us>\n\tT operator()(Us &&... us) const\n\t{\n\t\treturn T{((Us &&)us)...};\n\t}\n};\n\nstruct S\n{\n\tint i;\n};\n\nvoid test_10(int N)\n{\n\tint* ia = new int [N];\n\tS* ib = new S [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tstd::transform(ia, ia+N, ib, construct<S>());\n\tfor (int i = N; i > 0; --i)\n\t{\n\t\tCHECK(stl2::pop_heap(ib, ib+i, std::less<int>(), &S::i) == ib+i);\n\t\tstd::transform(ib, ib+i, ia, std::mem_fn(&S::i));\n\t\tCHECK(std::is_heap(ia, ia+i-1));\n\t}\n\tCHECK(stl2::pop_heap(ib, ib, std::less<int>(), &S::i) == ib);\n\tdelete [] ia;\n\tdelete [] ib;\n}\n\nint main()\n{\n\ttest_1(1000);\n\ttest_2(1000);\n\ttest_3(1000);\n\ttest_4(1000);\n\ttest_5(1000);\n\ttest_6(1000);\n\ttest_7(1000);\n\ttest_8(1000);\n\ttest_9(1000);\n\ttest_10(1000);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/prev_permutation.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/prev_permutation.hpp>\n#include <cstring>\n#include <utility>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<ranges::integral T>\nconstexpr auto factorial(T x)\n{\n\tdecltype(x) r = 1;\n\tfor (; 1 < x; --x) {\n\t\tr *= x;\n\t}\n\treturn r;\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_iter()\n{\n\tint ia[] = {6, 5, 4, 3, 2, 1};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor (int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::prev_permutation(Iter(ia), Sent(ia+e));\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif(!x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));\n\t\t\t}\n\t\t\t++count;\n\t\t} while(x);\n\t\tCHECK(count == factorial(e));\n\t}\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_range()\n{\n\tint ia[] = {6, 5, 4, 3, 2, 1};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor (int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::prev_permutation(ranges::subrange(Iter(ia), Sent(ia+e)));\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif(!x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e));\n\t\t\t}\n\t\t\t++count;\n\t\t} while(x);\n\t\tCHECK(count == factorial(e));\n\t}\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_iter_comp()\n{\n\ttypedef std::greater<int> C;\n\tint ia[] = {1, 2, 3, 4, 5, 6};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor(int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::prev_permutation(Iter(ia), Sent(ia+e), C());\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif(!x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));\n\t\t\t}\n\t\t\t++count;\n\t\t} while (x);\n\t\tCHECK(count == factorial(e));\n\t}\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_range_comp()\n{\n\ttypedef std::greater<int> C;\n\tint ia[] = {1, 2, 3, 4, 5, 6};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint prev[sa];\n\tfor(int e = 0; e <= sa; ++e)\n\t{\n\t\tint count = 0;\n\t\tbool x;\n\t\tdo\n\t\t{\n\t\t\tstd::copy(ia, ia+e, prev);\n\t\t\tx = ranges::prev_permutation(ranges::subrange(Iter(ia), Sent(ia+e)), C());\n\t\t\tif(e > 1)\n\t\t\t{\n\t\t\t\tif(!x)\n\t\t\t\t\tCHECK(std::lexicographical_compare(prev, prev+e, ia, ia+e, C()));\n\t\t\t\telse\n\t\t\t\t\tCHECK(std::lexicographical_compare(ia, ia+e, prev, prev+e, C()));\n\t\t\t}\n\t\t\t++count;\n\t\t} while (x);\n\t\t\tCHECK(count == factorial(e));\n\t}\n}\n\nstruct c_str\n{\n\tchar const * value;\n\n\tfriend bool operator==(c_str a, c_str b)\n\t{\n\t\treturn 0 == std::strcmp(a.value, b.value);\n\t}\n\n\tfriend bool operator!=(c_str a, c_str b)\n\t{\n\t\treturn !(a == b);\n\t}\n};\n\n// For debugging the projection test\nstd::ostream &operator<<(std::ostream& sout, std::pair<int, c_str> p)\n{\n\treturn sout << \"{\" << p.first << \",\" << p.second.value << \"}\";\n}\n\nint main()\n{\n\ttest_iter<bidirectional_iterator<int*> >();\n\ttest_iter<random_access_iterator<int*> >();\n\ttest_iter<int*>();\n\n\ttest_iter<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_iter<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_iter_comp<bidirectional_iterator<int*> >();\n\ttest_iter_comp<random_access_iterator<int*> >();\n\ttest_iter_comp<int*>();\n\n\ttest_iter_comp<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_iter_comp<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_range<bidirectional_iterator<int*> >();\n\ttest_range<random_access_iterator<int*> >();\n\ttest_range<int*>();\n\n\ttest_range<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_range<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_range_comp<bidirectional_iterator<int*> >();\n\ttest_range_comp<random_access_iterator<int*> >();\n\ttest_range_comp<int*>();\n\n\ttest_range_comp<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_range_comp<random_access_iterator<int*>, sentinel<int*> >();\n\n\t// Test projection\n\n\ttypedef std::less<int> C;\n\tstd::pair<int, c_str> ia[] = {{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {3,{\"three\"}}, {2,{\"two\"}}, {1,{\"one\"}}};\n\tCHECK(ranges::prev_permutation(ia, C(), &std::pair<int,c_str>::first));\n\tCHECK_EQUAL(ia, {std::pair<int, c_str>{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {3,{\"three\"}}, {1,{\"one\"}}, {2,{\"two\"}}});\n\tCHECK(ranges::prev_permutation(ia, C(), &std::pair<int,c_str>::first));\n\tCHECK_EQUAL(ia, {std::pair<int, c_str>{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {2,{\"two\"}}, {3,{\"three\"}}, {1,{\"one\"}}});\n\tCHECK(ranges::prev_permutation(ia, C(), &std::pair<int,c_str>::first));\n\tCHECK_EQUAL(ia, {std::pair<int, c_str>{6, {\"six\"}}, {5,{\"five\"}}, {4,{\"four\"}}, {2,{\"two\"}}, {1,{\"one\"}}, {3,{\"three\"}}});\n\t// etc..\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/push_heap.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n// <algorithm>\n\n// template<random_access_iterator Iter>\n//   requires ShuffleIterator<Iter>\n//         && LessThanComparable<Iter::value_type>\n//   void\n//   push_heap(Iter first, Iter last);\n\n#include <stl2/detail/algorithm/push_heap.hpp>\n#include <memory>\n#include <random>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\nconst auto push_heap = make_testable_1([](auto&&... args) {\n\treturn stl2::push_heap(std::forward<decltype(args)>(args)...);\n});\n\nvoid test(int N)\n{\n\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tfor (int i = 0; i <= N; ++i)\n\t{\n\t\t::push_heap(ia, ia+i).check([&](int *r){CHECK(r == ia + i);});\n\t\tCHECK(std::is_heap(ia, ia+i));\n\t}\n\tdelete [] ia;\n}\n\nvoid test_comp(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tfor (int i = 0; i <= N; ++i)\n\t{\n\t\t::push_heap(ia, ia+i, std::greater<int>()).check([&](int *r){CHECK(r == ia+i);});\n\t\tCHECK(std::is_heap(ia, ia+i, std::greater<int>()));\n\t}\n\tdelete [] ia;\n}\n\nstruct S\n{\n\tint i;\n};\n\nvoid test_proj(int N)\n{\n\tS* ia = new S [N];\n\tint* ib = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i].i = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tfor (int i = 0; i <= N; ++i)\n\t{\n\t\t::push_heap(ia, ia+i, std::greater<int>(), &S::i).check([&](S *r){CHECK(r == ia+i);});\n\t\tstd::transform(ia, ia+i, ib, std::mem_fn(&S::i));\n\t\tCHECK(std::is_heap(ib, ib+i, std::greater<int>()));\n\t}\n\tdelete [] ia;\n\tdelete [] ib;\n}\n\nstruct indirect_less\n{\n\ttemplate<class P>\n\tbool operator()(const P& x, const P& y) const\n\t\t{return *x < *y;}\n};\n\nvoid test_move_only(int N)\n{\n\tstd::unique_ptr<int>* ia = new std::unique_ptr<int> [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i].reset(new int(i));\n\tstd::shuffle(ia, ia+N, gen);\n\tfor (int i = 0; i <= N; ++i)\n\t{\n\t\t::push_heap(ia, ia+i, indirect_less()).check([&](std::unique_ptr<int> *r){CHECK(r == ia+i);});\n\t\tCHECK(std::is_heap(ia, ia+i, indirect_less()));\n\t}\n\tdelete [] ia;\n}\n\nint main()\n{\n\ttest(1000);\n\ttest_comp(1000);\n\ttest_proj(1000);\n\ttest_move_only(1000);\n\n\t{\n\t\tint const N = 1000;\n\t\tS* ia = new S [N];\n\t\tint* ib = new int [N];\n\t\tfor (int i = 0; i < N; ++i)\n\t\t\tia[i].i = i;\n\t\tstd::shuffle(ia, ia+N, gen);\n\t\tfor (int i = 0; i <= N; ++i)\n\t\t{\n\t\t\tCHECK(stl2::push_heap(stl2::subrange(ia, ia+i), std::greater<int>(), &S::i) == ia+i);\n\t\t\tstd::transform(ia, ia+i, ib, std::mem_fn(&S::i));\n\t\t\tCHECK(std::is_heap(ib, ib+i, std::greater<int>()));\n\t\t}\n\t\tdelete [] ia;\n\t\tdelete [] ib;\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/remove.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/remove.hpp>\n#include <memory>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter() {\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tIter r = ranges::remove(Iter(ia), Sent(ia+sa), 2);\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 3);\n\tCHECK(ia[3] == 4);\n\tCHECK(ia[4] == 3);\n\tCHECK(ia[5] == 4);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_range() {\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tIter r = ranges::remove(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 2);\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 3);\n\tCHECK(ia[3] == 4);\n\tCHECK(ia[4] == 3);\n\tCHECK(ia[5] == 4);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_rvalue()\n{\n\tconstexpr unsigned sa = 9;\n\tstd::unique_ptr<int> ia[sa];\n\tia[0].reset(new int(0));\n\tia[1].reset(new int(1));\n\tia[3].reset(new int(3));\n\tia[4].reset(new int(4));\n\tia[6].reset(new int(3));\n\tia[7].reset(new int(4));\n\n\tIter r = ranges::remove(Iter(ia), Sent(ia+sa), std::unique_ptr<int>());\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(*ia[0] == 0);\n\tCHECK(*ia[1] == 1);\n\tCHECK(*ia[2] == 3);\n\tCHECK(*ia[3] == 4);\n\tCHECK(*ia[4] == 3);\n\tCHECK(*ia[5] == 4);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_range_rvalue()\n{\n\tconstexpr unsigned sa = 9;\n\tstd::unique_ptr<int> ia[sa];\n\tia[0].reset(new int(0));\n\tia[1].reset(new int(1));\n\tia[3].reset(new int(3));\n\tia[4].reset(new int(4));\n\tia[6].reset(new int(3));\n\tia[7].reset(new int(4));\n\tIter r = ranges::remove(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), std::unique_ptr<int>());\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(*ia[0] == 0);\n\tCHECK(*ia[1] == 1);\n\tCHECK(*ia[2] == 3);\n\tCHECK(*ia[3] == 4);\n\tCHECK(*ia[4] == 3);\n\tCHECK(*ia[5] == 4);\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest_iter<forward_iterator<int*> >();\n\ttest_iter<bidirectional_iterator<int*> >();\n\ttest_iter<random_access_iterator<int*> >();\n\ttest_iter<int*>();\n\ttest_iter<forward_iterator<int*>, sentinel<int*>>();\n\ttest_iter<bidirectional_iterator<int*>, sentinel<int*>>();\n\ttest_iter<random_access_iterator<int*>, sentinel<int*>>();\n\n\ttest_range<forward_iterator<int*> >();\n\ttest_range<bidirectional_iterator<int*> >();\n\ttest_range<random_access_iterator<int*> >();\n\ttest_range<int*>();\n\ttest_range<forward_iterator<int*>, sentinel<int*>>();\n\ttest_range<bidirectional_iterator<int*>, sentinel<int*>>();\n\ttest_range<random_access_iterator<int*>, sentinel<int*>>();\n\n\ttest_iter_rvalue<forward_iterator<std::unique_ptr<int>*> >();\n\ttest_iter_rvalue<bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_iter_rvalue<random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_iter_rvalue<std::unique_ptr<int>*>();\n\ttest_iter_rvalue<forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_iter_rvalue<bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_iter_rvalue<random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\n\ttest_range_rvalue<forward_iterator<std::unique_ptr<int>*> >();\n\ttest_range_rvalue<bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_range_rvalue<random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_range_rvalue<std::unique_ptr<int>*>();\n\ttest_range_rvalue<forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_range_rvalue<bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_range_rvalue<random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\n\t// Check projection\n\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tS* r = ranges::remove(ia, 2, &S::i);\n\tCHECK(r == ia + sa-3);\n\tCHECK(ia[0].i == 0);\n\tCHECK(ia[1].i == 1);\n\tCHECK(ia[2].i == 3);\n\tCHECK(ia[3].i == 4);\n\tCHECK(ia[4].i == 3);\n\tCHECK(ia[5].i == 4);\n\n\t// Check rvalue range\n\tS ia2[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\tauto r2 = ranges::remove(std::move(ia2), 2, &S::i);\n\tstatic_assert(ranges::same_as<decltype(r2), ranges::dangling>);\n\tCHECK(ia2[0].i == 0);\n\tCHECK(ia2[1].i == 1);\n\tCHECK(ia2[2].i == 3);\n\tCHECK(ia2[3].i == 4);\n\tCHECK(ia2[4].i == 3);\n\tCHECK(ia2[5].i == 4);\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/remove_copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/remove_copy.hpp>\n#include <memory>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_iter() {\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tint ib[sa];\n\tranges::remove_copy_result<InIter, OutIter> r =\n\t\tranges::remove_copy(InIter(ia), Sent(ia+sa), OutIter(ib), 2);\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa-3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 3);\n\tCHECK(ib[3] == 4);\n\tCHECK(ib[4] == 3);\n\tCHECK(ib[5] == 4);\n}\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_range() {\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tint ib[sa];\n\tauto s = ranges::subrange(InIter(ia), Sent(ia+sa));\n\tranges::remove_copy_result<InIter, OutIter> r =\n\t\tranges::remove_copy(s, OutIter(ib), 2);\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa-3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 3);\n\tCHECK(ib[3] == 4);\n\tCHECK(ib[4] == 3);\n\tCHECK(ib[5] == 4);\n}\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test() {\n\ttest_iter<InIter, OutIter, Sent>();\n\ttest_range<InIter, OutIter, Sent>();\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest<input_iterator<const int*>, output_iterator<int*>>();\n\ttest<input_iterator<const int*>, forward_iterator<int*>>();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<input_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*>>();\n\ttest<forward_iterator<const int*>, forward_iterator<int*>>();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*>>();\n\ttest<const int*, forward_iterator<int*>>();\n\ttest<const int*, bidirectional_iterator<int*>>();\n\ttest<const int*, random_access_iterator<int*>>();\n\ttest<const int*, int*>();\n\n\ttest<input_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, int*, sentinel<const int*>>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, int*, sentinel<const int*>>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, int*, sentinel<const int*>>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, int*, sentinel<const int*>>();\n\n\t// Check projection\n\t{\n\t\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\t\tconstexpr unsigned sa = ranges::size(ia);\n\t\tS ib[sa];\n\t\tranges::remove_copy_result<S*, S*> r = ranges::remove_copy(ia, ib, 2, &S::i);\n\t\tCHECK(r.in == ia + sa);\n\t\tCHECK(r.out == ib + sa-3);\n\t\tCHECK(ib[0].i == 0);\n\t\tCHECK(ib[1].i == 1);\n\t\tCHECK(ib[2].i == 3);\n\t\tCHECK(ib[3].i == 4);\n\t\tCHECK(ib[4].i == 3);\n\t\tCHECK(ib[5].i == 4);\n\t}\n\n\t// Check rvalue range\n\t{\n\t\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\t\tconstexpr unsigned sa = ranges::size(ia);\n\t\tS ib[sa];\n\t\tauto r = ranges::remove_copy(std::move(ia), ib, 2, &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(r.in), ranges::dangling>);\n\t\tCHECK(r.out == ib + sa-3);\n\t\tCHECK(ib[0].i == 0);\n\t\tCHECK(ib[1].i == 1);\n\t\tCHECK(ib[2].i == 3);\n\t\tCHECK(ib[3].i == 4);\n\t\tCHECK(ib[4].i == 3);\n\t\tCHECK(ib[5].i == 4);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/remove_copy_if.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/remove_copy_if.hpp>\n#include <memory>\n#include <utility>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_iter() {\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tint ib[sa];\n\tranges::remove_copy_if_result<InIter, OutIter> r =\n\t\tranges::remove_copy_if(InIter(ia), Sent(ia+sa), OutIter(ib), [](int i){return i == 2;});\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa-3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 3);\n\tCHECK(ib[3] == 4);\n\tCHECK(ib[4] == 3);\n\tCHECK(ib[5] == 4);\n}\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_range() {\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tint ib[sa];\n\tauto s = ranges::subrange(InIter(ia), Sent(ia + sa));\n\tranges::remove_copy_if_result<InIter, OutIter> r =\n\t\tranges::remove_copy_if(s, OutIter(ib), [](int i){ return i == 2; });\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa-3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 3);\n\tCHECK(ib[3] == 4);\n\tCHECK(ib[4] == 3);\n\tCHECK(ib[5] == 4);\n}\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test() {\n\ttest_iter<InIter, OutIter, Sent>();\n\ttest_range<InIter, OutIter, Sent>();\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest<input_iterator<const int*>, output_iterator<int*>>();\n\ttest<input_iterator<const int*>, forward_iterator<int*>>();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<input_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*>>();\n\ttest<forward_iterator<const int*>, forward_iterator<int*>>();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*>>();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*>>();\n\ttest<const int*, forward_iterator<int*>>();\n\ttest<const int*, bidirectional_iterator<int*>>();\n\ttest<const int*, random_access_iterator<int*>>();\n\ttest<const int*, int*>();\n\n\ttest<input_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<input_iterator<const int*>, int*, sentinel<const int*>>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<forward_iterator<const int*>, int*, sentinel<const int*>>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<bidirectional_iterator<const int*>, int*, sentinel<const int*>>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*>>();\n\ttest<random_access_iterator<const int*>, int*, sentinel<const int*>>();\n\n\t// Check projection\n\t{\n\t\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\t\tconstexpr unsigned sa = ranges::size(ia);\n\t\tS ib[sa];\n\t\tranges::remove_copy_if_result<S*, S*> r =\n\t\t\tranges::remove_copy_if(ia, ib, [](int i){ return i == 2; }, &S::i);\n\t\tCHECK(r.in == ia + sa);\n\t\tCHECK(r.out == ib + sa - 3);\n\t\tCHECK(ib[0].i == 0);\n\t\tCHECK(ib[1].i == 1);\n\t\tCHECK(ib[2].i == 3);\n\t\tCHECK(ib[3].i == 4);\n\t\tCHECK(ib[4].i == 3);\n\t\tCHECK(ib[5].i == 4);\n\t}\n\n\t// Check rvalue range\n\t{\n\t\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\t\tconstexpr unsigned sa = ranges::size(ia);\n\t\tS ib[sa];\n\t\tauto r = ranges::remove_copy_if(std::move(ia), ib, [](int i){ return i == 2; }, &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(r.in), ranges::dangling>);\n\t\tCHECK(r.out == ib + sa-3);\n\t\tCHECK(ib[0].i == 0);\n\t\tCHECK(ib[1].i == 1);\n\t\tCHECK(ib[2].i == 3);\n\t\tCHECK(ib[3].i == 4);\n\t\tCHECK(ib[4].i == 3);\n\t\tCHECK(ib[5].i == 4);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/remove_if.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/remove_if.hpp>\n#include <iostream>\n#include <memory>\n#include <utility>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter()\n{\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tusing namespace std::placeholders;\n\tIter r = ranges::remove_if(Iter(ia), Sent(ia+sa), std::bind(std::equal_to<int>(), _1, 2));\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 3);\n\tCHECK(ia[3] == 4);\n\tCHECK(ia[4] == 3);\n\tCHECK(ia[5] == 4);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_range()\n{\n\tint ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2};\n\tconstexpr unsigned sa = ranges::size(ia);\n\tusing namespace std::placeholders;\n\tIter r = ranges::remove_if(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), std::bind(std::equal_to<int>(), _1, 2));\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 3);\n\tCHECK(ia[3] == 4);\n\tCHECK(ia[4] == 3);\n\tCHECK(ia[5] == 4);\n}\n\nstruct pred\n{\n\tbool operator()(const std::unique_ptr<int>& i) {return *i == 2;}\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_iter_rvalue()\n{\n\tconstexpr unsigned sa = 9;\n\tstd::unique_ptr<int> ia[sa];\n\tia[0].reset(new int(0));\n\tia[1].reset(new int(1));\n\tia[2].reset(new int(2));\n\tia[3].reset(new int(3));\n\tia[4].reset(new int(4));\n\tia[5].reset(new int(2));\n\tia[6].reset(new int(3));\n\tia[7].reset(new int(4));\n\tia[8].reset(new int(2));\n\tIter r = ranges::remove_if(Iter(ia), Sent(ia+sa), pred());\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(*ia[0] == 0);\n\tCHECK(*ia[1] == 1);\n\tCHECK(*ia[2] == 3);\n\tCHECK(*ia[3] == 4);\n\tCHECK(*ia[4] == 3);\n\tCHECK(*ia[5] == 4);\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid\ntest_range_rvalue()\n{\n\tconstexpr unsigned sa = 9;\n\tstd::unique_ptr<int> ia[sa];\n\tia[0].reset(new int(0));\n\tia[1].reset(new int(1));\n\tia[2].reset(new int(2));\n\tia[3].reset(new int(3));\n\tia[4].reset(new int(4));\n\tia[5].reset(new int(2));\n\tia[6].reset(new int(3));\n\tia[7].reset(new int(4));\n\tia[8].reset(new int(2));\n\tIter r = ranges::remove_if(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), pred());\n\tCHECK(base(r) == ia + sa-3);\n\tCHECK(*ia[0] == 0);\n\tCHECK(*ia[1] == 1);\n\tCHECK(*ia[2] == 3);\n\tCHECK(*ia[3] == 4);\n\tCHECK(*ia[4] == 3);\n\tCHECK(*ia[5] == 4);\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest_iter<forward_iterator<int*> >();\n\ttest_iter<bidirectional_iterator<int*> >();\n\ttest_iter<random_access_iterator<int*> >();\n\ttest_iter<int*>();\n\ttest_iter<forward_iterator<int*>, sentinel<int*>>();\n\ttest_iter<bidirectional_iterator<int*>, sentinel<int*>>();\n\ttest_iter<random_access_iterator<int*>, sentinel<int*>>();\n\n\ttest_range<forward_iterator<int*> >();\n\ttest_range<bidirectional_iterator<int*> >();\n\ttest_range<random_access_iterator<int*> >();\n\ttest_range<int*>();\n\ttest_range<forward_iterator<int*>, sentinel<int*>>();\n\ttest_range<bidirectional_iterator<int*>, sentinel<int*>>();\n\ttest_range<random_access_iterator<int*>, sentinel<int*>>();\n\n\ttest_iter_rvalue<forward_iterator<std::unique_ptr<int>*> >();\n\ttest_iter_rvalue<bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_iter_rvalue<random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_iter_rvalue<std::unique_ptr<int>*>();\n\ttest_iter_rvalue<forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_iter_rvalue<bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_iter_rvalue<random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\n\ttest_range_rvalue<forward_iterator<std::unique_ptr<int>*> >();\n\ttest_range_rvalue<bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_range_rvalue<random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_range_rvalue<std::unique_ptr<int>*>();\n\ttest_range_rvalue<forward_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_range_rvalue<bidirectional_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\ttest_range_rvalue<random_access_iterator<std::unique_ptr<int>*>, sentinel<std::unique_ptr<int>*>>();\n\n\t{\n\t\t// Check projection\n\t\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\t\tconstexpr unsigned sa = ranges::size(ia);\n\t\tusing namespace std::placeholders;\n\t\tS* r = ranges::remove_if(ia, std::bind(std::equal_to<int>(), _1, 2), &S::i);\n\t\tCHECK(r == ia + sa-3);\n\t\tCHECK(ia[0].i == 0);\n\t\tCHECK(ia[1].i == 1);\n\t\tCHECK(ia[2].i == 3);\n\t\tCHECK(ia[3].i == 4);\n\t\tCHECK(ia[4].i == 3);\n\t\tCHECK(ia[5].i == 4);\n\t}\n\n\t{\n\t\t// Check rvalue range\n\t\tS ia[] = {S{0}, S{1}, S{2}, S{3}, S{4}, S{2}, S{3}, S{4}, S{2}};\n\t\tusing namespace std::placeholders;\n\t\tauto r = ranges::remove_if(std::move(ia), std::bind(std::equal_to<int>(), _1, 2), &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(r), ranges::dangling>);\n\t\tCHECK(ia[0].i == 0);\n\t\tCHECK(ia[1].i == 1);\n\t\tCHECK(ia[2].i == 3);\n\t\tCHECK(ia[3].i == 4);\n\t\tCHECK(ia[4].i == 3);\n\t\tCHECK(ia[5].i == 4);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/replace.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/replace.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_iter()\n{\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tIter i = ranges::replace(Iter(ia), Sent(ia+sa), 2, 5);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 5);\n\tCHECK(ia[3] == 3);\n\tCHECK(ia[4] == 4);\n\tCHECK(base(i) == ia + sa);\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_rng()\n{\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tauto rng = ranges::subrange(Iter(ia), Sent(ia+sa));\n\tIter i = ranges::replace(rng, 2, 5);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 5);\n\tCHECK(ia[3] == 3);\n\tCHECK(ia[4] == 4);\n\tCHECK(base(i) == ia + sa);\n}\n\nint main()\n{\n\ttest_iter<input_iterator<int*> >();\n\ttest_iter<forward_iterator<int*> >();\n\ttest_iter<bidirectional_iterator<int*> >();\n\ttest_iter<random_access_iterator<int*> >();\n\ttest_iter<int*>();\n\n\ttest_iter<input_iterator<int*>, sentinel<int*> >();\n\ttest_iter<forward_iterator<int*>, sentinel<int*> >();\n\ttest_iter<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_iter<random_access_iterator<int*>, sentinel<int*> >();\n\n\ttest_rng<input_iterator<int*> >();\n\ttest_rng<forward_iterator<int*> >();\n\ttest_rng<bidirectional_iterator<int*> >();\n\ttest_rng<random_access_iterator<int*> >();\n\ttest_rng<int*>();\n\n\ttest_rng<input_iterator<int*>, sentinel<int*> >();\n\ttest_rng<forward_iterator<int*>, sentinel<int*> >();\n\ttest_rng<bidirectional_iterator<int*>, sentinel<int*> >();\n\ttest_rng<random_access_iterator<int*>, sentinel<int*> >();\n\n\t// test projection\n\t{\n\t\tusing P = std::pair<int,std::string>;\n\t\tP ia[] = {{0,\"0\"}, {1,\"1\"}, {2,\"2\"}, {3,\"3\"}, {4,\"4\"}};\n\t\tP *i = ranges::replace(ia, 2, std::make_pair(42,\"42\"), &std::pair<int,std::string>::first);\n\t\tCHECK(ia[0] == P{0,\"0\"});\n\t\tCHECK(ia[1] == P{1,\"1\"});\n\t\tCHECK(ia[2] == P{42,\"42\"});\n\t\tCHECK(ia[3] == P{3,\"3\"});\n\t\tCHECK(ia[4] == P{4,\"4\"});\n\t\tCHECK(i == ranges::end(ia));\n\t}\n\n\t// test rvalue range\n\t{\n\t\tusing P = std::pair<int,std::string>;\n\t\tP ia[] = {{0,\"0\"}, {1,\"1\"}, {2,\"2\"}, {3,\"3\"}, {4,\"4\"}};\n\t\tauto i = ranges::replace(std::move(ia), 2, std::make_pair(42,\"42\"), &std::pair<int,std::string>::first);\n\t\tstatic_assert(ranges::same_as<decltype(i), ranges::dangling>);\n\t\tCHECK(ia[0] == P{0,\"0\"});\n\t\tCHECK(ia[1] == P{1,\"1\"});\n\t\tCHECK(ia[2] == P{42,\"42\"});\n\t\tCHECK(ia[3] == P{3,\"3\"});\n\t\tCHECK(ia[4] == P{4,\"4\"});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/replace_copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/replace_copy.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_iter() {\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[sa] = {0};\n\tranges::replace_copy_result<InIter, OutIter> r =\n\t\tranges::replace_copy(InIter(ia), Sent(ia+sa), OutIter(ib), 2, 5);\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 5);\n\tCHECK(ib[3] == 3);\n\tCHECK(ib[4] == 4);\n}\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_rng() {\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[sa] = {0};\n\tauto rng = ranges::subrange(InIter(ia), Sent(ia+sa));\n\tranges::replace_copy_result<InIter, OutIter> r =\n\t\tranges::replace_copy(rng, OutIter(ib), 2, 5);\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 5);\n\tCHECK(ib[3] == 3);\n\tCHECK(ib[4] == 4);\n}\n\ntemplate<class InIter, class OutIter>\nvoid test() {\n\tusing Sent = typename sentinel_type<InIter>::type;\n\ttest_iter<InIter, OutIter>();\n\ttest_iter<InIter, OutIter>();\n\ttest_rng<InIter, OutIter, Sent>();\n\ttest_rng<InIter, OutIter, Sent>();\n}\n\nint main() {\n\ttest<input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<int*> >();\n\ttest<const int*, int*>();\n\n\t// Test projection\n\t{\n\t\tusing P = std::pair<int, std::string>;\n\t\tP in[] = {{0, \"0\"}, {1, \"1\"}, {2, \"2\"}, {3, \"3\"}, {4, \"4\"}};\n\t\tP out[ranges::size(in)] = {};\n\t\tranges::replace_copy_result<P*, P*> r =\n\t\t\tranges::replace_copy(in, out, 2, P{5, \"5\"}, &P::first);\n\t\tCHECK(r.in == ranges::end(in));\n\t\tCHECK(r.out == ranges::end(out));\n\t\tCHECK(out[0] == P{0, \"0\"});\n\t\tCHECK(out[1] == P{1, \"1\"});\n\t\tCHECK(out[2] == P{5, \"5\"});\n\t\tCHECK(out[3] == P{3, \"3\"});\n\t\tCHECK(out[4] == P{4, \"4\"});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/replace_copy_if.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/replace_copy_if.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_iter() {\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[sa] = {0};\n\tranges::replace_copy_if_result<InIter, OutIter> r =\n\t\tranges::replace_copy_if(InIter(ia), Sent(ia+sa), OutIter(ib),\n\t\t                        [](int i){ return 2 == i; }, 5);\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 5);\n\tCHECK(ib[3] == 3);\n\tCHECK(ib[4] == 4);\n}\n\ntemplate<class InIter, class OutIter, class Sent = InIter>\nvoid test_rng() {\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[sa] = {0};\n\tauto rng = ranges::subrange(InIter(ia), Sent(ia+sa));\n\tranges::replace_copy_if_result<InIter, OutIter> r =\n\t\tranges::replace_copy_if(rng, OutIter(ib), [](int i){ return 2 == i; }, 5);\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ib + sa);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 5);\n\tCHECK(ib[3] == 3);\n\tCHECK(ib[4] == 4);\n}\n\ntemplate<class InIter, class OutIter>\nvoid test() {\n\tusing Sent = typename sentinel_type<InIter>::type;\n\ttest_iter<InIter, OutIter>();\n\ttest_iter<InIter, OutIter>();\n\ttest_rng<InIter, OutIter, Sent>();\n\ttest_rng<InIter, OutIter, Sent>();\n}\n\nint main() {\n\ttest<input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<int*> >();\n\ttest<const int*, int*>();\n\n\t// Test projection\n\t{\n\t\tusing P = std::pair<int, std::string>;\n\t\tP in[] = {{0, \"0\"}, {1, \"1\"}, {2, \"2\"}, {3, \"3\"}, {4, \"4\"}};\n\t\tP out[ranges::size(in)] = {};\n\t\tranges::replace_copy_if_result<P*, P*> r =\n\t\t\tranges::replace_copy_if(in, out, [](int i){ return 2==i; }, P{5, \"5\"}, &P::first);\n\t\tCHECK(r.in == ranges::end(in));\n\t\tCHECK(r.out == ranges::end(out));\n\t\tCHECK(out[0] == P{0, \"0\"});\n\t\tCHECK(out[1] == P{1, \"1\"});\n\t\tCHECK(out[2] == P{5, \"5\"});\n\t\tCHECK(out[3] == P{3, \"3\"});\n\t\tCHECK(out[4] == P{4, \"4\"});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/replace_if.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/replace_if.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_iter()\n{\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tIter i = ranges::replace_if(Iter(ia), Sent(ia+sa), [](int i){return i==2;}, 5);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 5);\n\tCHECK(ia[3] == 3);\n\tCHECK(ia[4] == 4);\n\tCHECK(base(i) == ia + sa);\n}\n\ntemplate<typename Iter, typename Sent = Iter>\nvoid test_rng()\n{\n\tint ia[] = {0, 1, 2, 3, 4};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tauto rng = ranges::subrange(Iter(ia), Sent(ia+sa));\n\tIter i = ranges::replace_if(rng, [](int i){return i==2;}, 5);\n\tCHECK(ia[0] == 0);\n\tCHECK(ia[1] == 1);\n\tCHECK(ia[2] == 5);\n\tCHECK(ia[3] == 3);\n\tCHECK(ia[4] == 4);\n\tCHECK(base(i) == ia + sa);\n}\n\nint main()\n{\n\ttest_iter<input_iterator<int*>>();\n\ttest_iter<forward_iterator<int*>>();\n\ttest_iter<bidirectional_iterator<int*>>();\n\ttest_iter<random_access_iterator<int*>>();\n\ttest_iter<int*>();\n\n\ttest_iter<input_iterator<int*>, sentinel<int*>>();\n\ttest_iter<forward_iterator<int*>, sentinel<int*>>();\n\ttest_iter<bidirectional_iterator<int*>, sentinel<int*>>();\n\ttest_iter<random_access_iterator<int*>, sentinel<int*>>();\n\n\ttest_rng<input_iterator<int*>>();\n\ttest_rng<forward_iterator<int*>>();\n\ttest_rng<bidirectional_iterator<int*>>();\n\ttest_rng<random_access_iterator<int*>>();\n\ttest_rng<int*>();\n\n\ttest_rng<input_iterator<int*>, sentinel<int*>>();\n\ttest_rng<forward_iterator<int*>, sentinel<int*>>();\n\ttest_rng<bidirectional_iterator<int*>, sentinel<int*>>();\n\ttest_rng<random_access_iterator<int*>, sentinel<int*>>();\n\n\t// test projection\n\t{\n\t\tusing P = std::pair<int,std::string>;\n\t\tP ia[] = {{0,\"0\"}, {1,\"1\"}, {2,\"2\"}, {3,\"3\"}, {4,\"4\"}};\n\t\tP *i = ranges::replace_if(ia, [](int i){return i==2;}, std::make_pair(42,\"42\"),\n\t\t\t&std::pair<int,std::string>::first);\n\t\tCHECK(ia[0] == P{0,\"0\"});\n\t\tCHECK(ia[1] == P{1,\"1\"});\n\t\tCHECK(ia[2] == P{42,\"42\"});\n\t\tCHECK(ia[3] == P{3,\"3\"});\n\t\tCHECK(ia[4] == P{4,\"4\"});\n\t\tCHECK(i == ranges::end(ia));\n\t}\n\n\t// test rvalue range\n\t{\n\t\tusing P = std::pair<int,std::string>;\n\t\tP ia[] = {{0,\"0\"}, {1,\"1\"}, {2,\"2\"}, {3,\"3\"}, {4,\"4\"}};\n\t\tauto i = ranges::replace_if(std::move(ia), [](int i){return i==2;}, std::make_pair(42,\"42\"),\n\t\t\t&std::pair<int,std::string>::first);\n\t\tstatic_assert(ranges::same_as<decltype(i), ranges::dangling>);\n\t\tCHECK(ia[0] == P{0,\"0\"});\n\t\tCHECK(ia[1] == P{1,\"1\"});\n\t\tCHECK(ia[2] == P{42,\"42\"});\n\t\tCHECK(ia[3] == P{3,\"3\"});\n\t\tCHECK(ia[4] == P{4,\"4\"});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/reverse.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/reverse.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter, class Sent = Iter>\nvoid test() {\n\t// iterators\n\t{\n\t\tint ia[] = {0};\n\t\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\t\tIter i0 = ranges::reverse(Iter(ia), Sent(ia));\n\t\tCHECK_EQUAL(ia, {0});\n\t\tCHECK(i0 == Iter(ia));\n\t\tIter i1 = ranges::reverse(Iter(ia), Sent(ia+sa));\n\t\tCHECK_EQUAL(ia, {0});\n\t\tCHECK(i1 == Iter(ia+sa));\n\n\t\tint ib[] = {0, 1};\n\t\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\t\tIter i2 = ranges::reverse(Iter(ib), Sent(ib+sb));\n\t\tCHECK_EQUAL(ib, {1, 0});\n\t\tCHECK(i2 == Iter(ib+sb));\n\n\t\tint ic[] = {0, 1, 2};\n\t\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\t\tIter i3 = ranges::reverse(Iter(ic), Sent(ic+sc));\n\t\tCHECK_EQUAL(ic, {2, 1, 0});\n\t\tCHECK(i3 == Iter(ic+sc));\n\n\t\tint id[] = {0, 1, 2, 3};\n\t\tconst unsigned sd = sizeof(id)/sizeof(id[0]);\n\t\tIter i4 = ranges::reverse(Iter(id), Sent(id+sd));\n\t\tCHECK_EQUAL(id, {3, 2, 1, 0});\n\t\tCHECK(i4 == Iter(id+sd));\n\t}\n\n\t// ranges\n\t{\n\t\tint ia[] = {0};\n\t\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\t\tIter i0 = ranges::reverse(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia))));\n\t\tCHECK_EQUAL(ia, {0});\n\t\tCHECK(i0 == Iter(ia));\n\t\tIter i1 = ranges::reverse(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))));\n\t\tCHECK_EQUAL(ia, {0});\n\t\tCHECK(i1 == Iter(ia+sa));\n\n\t\tint ib[] = {0, 1};\n\t\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\t\tIter i2 = ranges::reverse(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))));\n\t\tCHECK_EQUAL(ib, {1, 0});\n\t\tCHECK(i2 == Iter(ib+sb));\n\n\t\tint ic[] = {0, 1, 2};\n\t\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\t\tIter i3 = ranges::reverse(::as_lvalue(ranges::subrange(Iter(ic), Sent(ic+sc))));\n\t\tCHECK_EQUAL(ic, {2, 1, 0});\n\t\tCHECK(i3 == Iter(ic+sc));\n\n\t\tint id[] = {0, 1, 2, 3};\n\t\tconst unsigned sd = sizeof(id)/sizeof(id[0]);\n\t\tIter i4 = ranges::reverse(::as_lvalue(ranges::subrange(Iter(id), Sent(id+sd))));\n\t\tCHECK_EQUAL(id, {3, 2, 1, 0});\n\t\tCHECK(i4 == Iter(id+sd));\n\n\t\t// rvalue range\n\t\tauto i5 = ranges::reverse(ranges::subrange(Iter(id), Sent(id+sd)));\n\t\tCHECK_EQUAL(id, {0, 1, 2, 3});\n\t\tCHECK(i5 == Iter(id+sd));\n\t}\n}\n\nint main() {\n\ttest<bidirectional_iterator<int *>>();\n\ttest<random_access_iterator<int *>>();\n\ttest<int*>();\n\n\ttest<bidirectional_iterator<int *>, sentinel<int*>>();\n\ttest<random_access_iterator<int *>, sentinel<int*>>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/reverse_copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/reverse_copy.hpp>\n#include <cstring>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter, class OutIter, class Sent = Iter>\nvoid test() {\n\tusing R = ranges::reverse_copy_result<Iter, OutIter>;\n\t// iterators\n\t{\n\t\tconst int ia[] = {0};\n\t\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\t\tint ja[sa] = {-1};\n\t\tR p0 = ranges::reverse_copy(Iter(ia), Sent(ia), OutIter(ja));\n\t\tCHECK_EQUAL(ja, {-1});\n\t\tCHECK(p0.in == Iter(ia));\n\t\tCHECK(base(p0.out) == ja);\n\t\tR p1 = ranges::reverse_copy(Iter(ia), Sent(ia+sa), OutIter(ja));\n\t\tCHECK_EQUAL(ja, {0});\n\t\tCHECK(p1.in == Iter(ia+sa));\n\t\tCHECK(base(p1.out) == ja+sa);\n\n\t\tconst int ib[] = {0, 1};\n\t\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\t\tint jb[sb] = {-1};\n\t\tR p2 = ranges::reverse_copy(Iter(ib), Sent(ib+sb), OutIter(jb));\n\t\tCHECK_EQUAL(jb, {1, 0});\n\t\tCHECK(p2.in == Iter(ib+sb));\n\t\tCHECK(base(p2.out) == jb+sb);\n\n\t\tconst int ic[] = {0, 1, 2};\n\t\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\t\tint jc[sc] = {-1};\n\t\tR p3 = ranges::reverse_copy(Iter(ic), Sent(ic+sc), OutIter(jc));\n\t\tCHECK_EQUAL(jc, {2, 1, 0});\n\t\tCHECK(p3.in == Iter(ic+sc));\n\t\tCHECK(base(p3.out) == jc+sc);\n\n\t\tconst int id[] = {0, 1, 2, 3};\n\t\tconst unsigned sd = sizeof(id)/sizeof(id[0]);\n\t\tint jd[sd] = {-1};\n\t\tR p4 = ranges::reverse_copy(Iter(id), Sent(id+sd), OutIter(jd));\n\t\tCHECK_EQUAL(jd, {3, 2, 1, 0});\n\t\tCHECK(p4.in == Iter(id+sd));\n\t\tCHECK(base(p4.out) == jd+sd);\n\t}\n\n\t// ranges\n\t{\n\t\tconst int ia[] = {0};\n\t\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\t\tint ja[sa] = {-1};\n\t\tR p0 = ranges::reverse_copy(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia))), OutIter(ja));\n\t\tCHECK_EQUAL(ja, {-1});\n\t\tCHECK(p0.in == Iter(ia));\n\t\tCHECK(base(p0.out) == ja);\n\t\tR p1 = ranges::reverse_copy(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), OutIter(ja));\n\t\tCHECK_EQUAL(ja, {0});\n\t\tCHECK(p1.in == Iter(ia+sa));\n\t\tCHECK(base(p1.out) == ja+sa);\n\n\t\tconst int ib[] = {0, 1};\n\t\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\t\tint jb[sb] = {-1};\n\t\tR p2 = ranges::reverse_copy(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), OutIter(jb));\n\t\tCHECK_EQUAL(jb, {1, 0});\n\t\tCHECK(p2.in == Iter(ib+sb));\n\t\tCHECK(base(p2.out) == jb+sb);\n\n\t\tconst int ic[] = {0, 1, 2};\n\t\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\t\tint jc[sc] = {-1};\n\t\tR p3 = ranges::reverse_copy(::as_lvalue(ranges::subrange(Iter(ic), Sent(ic+sc))), OutIter(jc));\n\t\tCHECK_EQUAL(jc, {2, 1, 0});\n\t\tCHECK(p3.in == Iter(ic+sc));\n\t\tCHECK(base(p3.out) == jc+sc);\n\n\t\tconst int id[] = {0, 1, 2, 3};\n\t\tconst unsigned sd = sizeof(id)/sizeof(id[0]);\n\t\tint jd[sd] = {-1};\n\t\tR p4 = ranges::reverse_copy(::as_lvalue(ranges::subrange(Iter(id), Sent(id+sd))), OutIter(jd));\n\t\tCHECK_EQUAL(jd, {3, 2, 1, 0});\n\t\tCHECK(p4.in == Iter(id+sd));\n\t\tCHECK(base(p4.out) == jd+sd);\n\n\t\t// test rvalue ranges\n\t\tstd::memset(jd, 0, sizeof(jd));\n\t\tauto p5 = ranges::reverse_copy(ranges::subrange(Iter(id), Sent(id+sd)), OutIter(jd));\n\t\tCHECK_EQUAL(jd, {3, 2, 1, 0});\n\t\tCHECK(p5.in == Iter(id+sd));\n\t\tCHECK(base(p4.out) == jd+sd);\n\t}\n}\n\nint main() {\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<int*> >();\n\ttest<const int*, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*>, sentinel<const int *> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*>, sentinel<const int *> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int *> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*>, sentinel<const int *> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*>, sentinel<const int *> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*>, sentinel<const int *> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int *> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*>, sentinel<const int *> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*>, sentinel<const int *> >();\n\ttest<const int*, forward_iterator<int*>, sentinel<const int *> >();\n\ttest<const int*, bidirectional_iterator<int*>, sentinel<const int *> >();\n\ttest<const int*, random_access_iterator<int*>, sentinel<const int *> >();\n\ttest<const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/rotate.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/rotate.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter, class Sent = Iter>\nvoid test()\n{\n\tusing namespace ranges;\n\n\tint ia[] = {0};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tauto r = rotate(Iter(ia), Iter(ia), Sent(ia));\n\tCHECK(base(r.begin()) == ia);\n\tCHECK(base(r.end()) == ia);\n\tCHECK(ia[0] == 0);\n\tr = rotate(Iter(ia), Iter(ia), Sent(ia+sa));\n\tCHECK(base(r.begin()) == ia+sa);\n\tCHECK(base(r.end()) == ia+sa);\n\tCHECK(ia[0] == 0);\n\tr = rotate(Iter(ia), Iter(ia+sa), Sent(ia+sa));\n\tCHECK(base(r.begin()) == ia);\n\tCHECK(base(r.end()) == ia+sa);\n\tCHECK(ia[0] == 0);\n\n\tint ib[] = {0, 1};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tr = rotate(Iter(ib), Iter(ib), Sent(ib+sb));\n\tCHECK(base(r.begin()) == ib+sb);\n\tCHECK(base(r.end()) == ib+sb);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tr = rotate(Iter(ib), Iter(ib+1), Sent(ib+sb));\n\tCHECK(base(r.end()) == ib+sb);\n\tCHECK(base(r.begin()) == ib+1);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 0);\n\tr = rotate(Iter(ib), Iter(ib+sb), Sent(ib+sb));\n\tCHECK(base(r.end()) == ib+sb);\n\tCHECK(base(r.begin()) == ib);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 0);\n\n\tint ic[] = {0, 1, 2};\n\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\tr = rotate(Iter(ic), Iter(ic), Sent(ic+sc));\n\tCHECK(base(r.begin()) == ic+sc);\n\tCHECK(base(r.end()) == ic+sc);\n\tCHECK(ic[0] == 0);\n\tCHECK(ic[1] == 1);\n\tCHECK(ic[2] == 2);\n\tr = rotate(Iter(ic), Iter(ic+1), Sent(ic+sc));\n\tCHECK(base(r.begin()) == ic+2);\n\tCHECK(base(r.end()) == ic+sc);\n\tCHECK(ic[0] == 1);\n\tCHECK(ic[1] == 2);\n\tCHECK(ic[2] == 0);\n\tr = rotate(Iter(ic), Iter(ic+2), Sent(ic+sc));\n\tCHECK(base(r.begin()) == ic+1);\n\tCHECK(base(r.end()) == ic+sc);\n\tCHECK(ic[0] == 0);\n\tCHECK(ic[1] == 1);\n\tCHECK(ic[2] == 2);\n\tr = rotate(Iter(ic), Iter(ic+sc), Sent(ic+sc));\n\tCHECK(base(r.begin()) == ic);\n\tCHECK(base(r.end()) == ic+sc);\n\tCHECK(ic[0] == 0);\n\tCHECK(ic[1] == 1);\n\tCHECK(ic[2] == 2);\n\n\tint id[] = {0, 1, 2, 3};\n\tconst unsigned sd = sizeof(id)/sizeof(id[0]);\n\tr = rotate(Iter(id), Iter(id), Sent(id+sd));\n\tCHECK(base(r.begin()) == id+sd);\n\tCHECK(base(r.end()) == id+sd);\n\tCHECK(id[0] == 0);\n\tCHECK(id[1] == 1);\n\tCHECK(id[2] == 2);\n\tCHECK(id[3] == 3);\n\tr = rotate(Iter(id), Iter(id+1), Sent(id+sd));\n\tCHECK(base(r.begin()) == id+3);\n\tCHECK(base(r.end()) == id+sd);\n\tCHECK(id[0] == 1);\n\tCHECK(id[1] == 2);\n\tCHECK(id[2] == 3);\n\tCHECK(id[3] == 0);\n\tr = rotate(Iter(id), Iter(id+2), Sent(id+sd));\n\tCHECK(base(r.begin()) == id+2);\n\tCHECK(base(r.end()) == id+sd);\n\tCHECK(id[0] == 3);\n\tCHECK(id[1] == 0);\n\tCHECK(id[2] == 1);\n\tCHECK(id[3] == 2);\n\tr = rotate(Iter(id), Iter(id+3), Sent(id+sd));\n\tCHECK(base(r.begin()) == id+1);\n\tCHECK(base(r.end()) == id+sd);\n\tCHECK(id[0] == 2);\n\tCHECK(id[1] == 3);\n\tCHECK(id[2] == 0);\n\tCHECK(id[3] == 1);\n\tr = rotate(Iter(id), Iter(id+sd), Sent(id+sd));\n\tCHECK(base(r.begin()) == id);\n\tCHECK(base(r.end()) == id+sd);\n\tCHECK(id[0] == 2);\n\tCHECK(id[1] == 3);\n\tCHECK(id[2] == 0);\n\tCHECK(id[3] == 1);\n\n\tint ie[] = {0, 1, 2, 3, 4};\n\tconst unsigned se = sizeof(ie)/sizeof(ie[0]);\n\tr = rotate(Iter(ie), Iter(ie), Sent(ie+se));\n\tCHECK(base(r.begin()) == ie+se);\n\tCHECK(base(r.end()) == ie+se);\n\tCHECK(ie[0] == 0);\n\tCHECK(ie[1] == 1);\n\tCHECK(ie[2] == 2);\n\tCHECK(ie[3] == 3);\n\tCHECK(ie[4] == 4);\n\tr = rotate(Iter(ie), Iter(ie+1), Sent(ie+se));\n\tCHECK(base(r.begin()) == ie+4);\n\tCHECK(base(r.end()) == ie+se);\n\tCHECK(ie[0] == 1);\n\tCHECK(ie[1] == 2);\n\tCHECK(ie[2] == 3);\n\tCHECK(ie[3] == 4);\n\tCHECK(ie[4] == 0);\n\tr = rotate(Iter(ie), Iter(ie+2), Sent(ie+se));\n\tCHECK(base(r.begin()) == ie+3);\n\tCHECK(base(r.end()) == ie+se);\n\tCHECK(ie[0] == 3);\n\tCHECK(ie[1] == 4);\n\tCHECK(ie[2] == 0);\n\tCHECK(ie[3] == 1);\n\tCHECK(ie[4] == 2);\n\tr = rotate(Iter(ie), Iter(ie+3), Sent(ie+se));\n\tCHECK(base(r.begin()) == ie+2);\n\tCHECK(base(r.end()) == ie+se);\n\tCHECK(ie[0] == 1);\n\tCHECK(ie[1] == 2);\n\tCHECK(ie[2] == 3);\n\tCHECK(ie[3] == 4);\n\tCHECK(ie[4] == 0);\n\tr = rotate(Iter(ie), Iter(ie+4), Sent(ie+se));\n\tCHECK(base(r.begin()) == ie+1);\n\tCHECK(base(r.end()) == ie+se);\n\tCHECK(ie[0] == 0);\n\tCHECK(ie[1] == 1);\n\tCHECK(ie[2] == 2);\n\tCHECK(ie[3] == 3);\n\tCHECK(ie[4] == 4);\n\tr = rotate(Iter(ie), Iter(ie+se), Sent(ie+se));\n\tCHECK(base(r.begin()) == ie);\n\tCHECK(base(r.end()) == ie+se);\n\tCHECK(ie[0] == 0);\n\tCHECK(ie[1] == 1);\n\tCHECK(ie[2] == 2);\n\tCHECK(ie[3] == 3);\n\tCHECK(ie[4] == 4);\n\n\tint ig[] = {0, 1, 2, 3, 4, 5};\n\tconst unsigned sg = sizeof(ig)/sizeof(ig[0]);\n\tr = rotate(Iter(ig), Iter(ig), Sent(ig+sg));\n\tCHECK(base(r.begin()) == ig+sg);\n\tCHECK(base(r.end()) == ig+sg);\n\tCHECK(ig[0] == 0);\n\tCHECK(ig[1] == 1);\n\tCHECK(ig[2] == 2);\n\tCHECK(ig[3] == 3);\n\tCHECK(ig[4] == 4);\n\tCHECK(ig[5] == 5);\n\tr = rotate(Iter(ig), Iter(ig+1), Sent(ig+sg));\n\tCHECK(base(r.begin()) == ig+5);\n\tCHECK(base(r.end()) == ig+sg);\n\tCHECK(ig[0] == 1);\n\tCHECK(ig[1] == 2);\n\tCHECK(ig[2] == 3);\n\tCHECK(ig[3] == 4);\n\tCHECK(ig[4] == 5);\n\tCHECK(ig[5] == 0);\n\tr = rotate(Iter(ig), Iter(ig+2), Sent(ig+sg));\n\tCHECK(base(r.begin()) == ig+4);\n\tCHECK(base(r.end()) == ig+sg);\n\tCHECK(ig[0] == 3);\n\tCHECK(ig[1] == 4);\n\tCHECK(ig[2] == 5);\n\tCHECK(ig[3] == 0);\n\tCHECK(ig[4] == 1);\n\tCHECK(ig[5] == 2);\n\tr = rotate(Iter(ig), Iter(ig+3), Sent(ig+sg));\n\tCHECK(base(r.begin()) == ig+3);\n\tCHECK(base(r.end()) == ig+sg);\n\tCHECK(ig[0] == 0);\n\tCHECK(ig[1] == 1);\n\tCHECK(ig[2] == 2);\n\tCHECK(ig[3] == 3);\n\tCHECK(ig[4] == 4);\n\tCHECK(ig[5] == 5);\n\tr = rotate(Iter(ig), Iter(ig+4), Sent(ig+sg));\n\tCHECK(base(r.begin()) == ig+2);\n\tCHECK(base(r.end()) == ig+sg);\n\tCHECK(ig[0] == 4);\n\tCHECK(ig[1] == 5);\n\tCHECK(ig[2] == 0);\n\tCHECK(ig[3] == 1);\n\tCHECK(ig[4] == 2);\n\tCHECK(ig[5] == 3);\n\tr = rotate(Iter(ig), Iter(ig+5), Sent(ig+sg));\n\tCHECK(base(r.begin()) == ig+1);\n\tCHECK(base(r.end()) == ig+sg);\n\tCHECK(ig[0] == 3);\n\tCHECK(ig[1] == 4);\n\tCHECK(ig[2] == 5);\n\tCHECK(ig[3] == 0);\n\tCHECK(ig[4] == 1);\n\tCHECK(ig[5] == 2);\n\tr = rotate(Iter(ig), Iter(ig+sg), Sent(ig+sg));\n\tCHECK(base(r.begin()) == ig);\n\tCHECK(base(r.end()) == ig+sg);\n\tCHECK(ig[0] == 3);\n\tCHECK(ig[1] == 4);\n\tCHECK(ig[2] == 5);\n\tCHECK(ig[3] == 0);\n\tCHECK(ig[4] == 1);\n\tCHECK(ig[5] == 2);\n}\n\nint main()\n{\n\ttest<forward_iterator<int *>>();\n\ttest<bidirectional_iterator<int *>>();\n\ttest<random_access_iterator<int *>>();\n\n\ttest<forward_iterator<int *>, sentinel<int*>>();\n\ttest<bidirectional_iterator<int *>, sentinel<int*>>();\n\ttest<random_access_iterator<int *>, sentinel<int*>>();\n\n\t// test rvalue range\n\t{\n\t\tint rgi[] = {0,1,2,3,4,5};\n\t\tauto r = ranges::rotate(std::move(rgi), rgi+2);\n\t\tstatic_assert(ranges::same_as<decltype(r), ranges::dangling>);\n\t\tCHECK(rgi[0] == 2);\n\t\tCHECK(rgi[1] == 3);\n\t\tCHECK(rgi[2] == 4);\n\t\tCHECK(rgi[3] == 5);\n\t\tCHECK(rgi[4] == 0);\n\t\tCHECK(rgi[5] == 1);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/rotate_copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/rotate_copy.hpp>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n#include \"../test_utils.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class InIter, class OutIter, typename Sent = InIter>\nvoid test_iter()\n{\n\tint ia[] = {0, 1, 2, 3};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[sa] = {0};\n\n\tranges::rotate_copy_result<InIter, OutIter> r =\n\t\tranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia), OutIter(ib));\n\tCHECK(base(r.in) == ia);\n\tCHECK(base(r.out) == ib);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+1), OutIter(ib));\n\tCHECK(base(r.in) == ia+1);\n\tCHECK(base(r.out) == ib+1);\n\tCHECK(ib[0] == 0);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+1), OutIter(ib));\n\tCHECK(base(r.in) == ia+1);\n\tCHECK(base(r.out) == ib+1);\n\tCHECK(ib[0] == 0);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+2), OutIter(ib));\n\tCHECK(base(r.in) == ia+2);\n\tCHECK(base(r.out) == ib+2);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+2), OutIter(ib));\n\tCHECK(base(r.in) == ia+2);\n\tCHECK(base(r.out) == ib+2);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 0);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+2), Sent(ia+2), OutIter(ib));\n\tCHECK(base(r.in) == ia+2);\n\tCHECK(base(r.out) == ib+2);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+3), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+3), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 2);\n\tCHECK(ib[2] == 0);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+2), Sent(ia+3), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 2);\n\tCHECK(ib[1] == 0);\n\tCHECK(ib[2] == 1);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+3), Sent(ia+3), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia), Sent(ia+4), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\tCHECK(ib[3] == 3);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+1), Sent(ia+4), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 2);\n\tCHECK(ib[2] == 3);\n\tCHECK(ib[3] == 0);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+2), Sent(ia+4), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 2);\n\tCHECK(ib[1] == 3);\n\tCHECK(ib[2] == 0);\n\tCHECK(ib[3] == 1);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+3), Sent(ia+4), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 3);\n\tCHECK(ib[1] == 0);\n\tCHECK(ib[2] == 1);\n\tCHECK(ib[3] == 2);\n\n\tr = ranges::rotate_copy(InIter(ia), InIter(ia+4), Sent(ia+4), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\tCHECK(ib[3] == 3);\n}\n\ntemplate<class InIter, class OutIter, typename Sent = InIter>\nvoid test_rng()\n{\n\tint ia[] = {0, 1, 2, 3};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[sa] = {0};\n\n\tranges::rotate_copy_result<InIter, OutIter> r =\n\t\tranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia))), InIter(ia), OutIter(ib));\n\tCHECK(base(r.in) == ia);\n\tCHECK(base(r.out) == ib);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+1))), InIter(ia), OutIter(ib));\n\tCHECK(base(r.in) == ia+1);\n\tCHECK(base(r.out) == ib+1);\n\tCHECK(ib[0] == 0);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+1))), InIter(ia+1), OutIter(ib));\n\tCHECK(base(r.in) == ia+1);\n\tCHECK(base(r.out) == ib+1);\n\tCHECK(ib[0] == 0);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+2))), InIter(ia), OutIter(ib));\n\tCHECK(base(r.in) == ia+2);\n\tCHECK(base(r.out) == ib+2);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+2))), InIter(ia+1), OutIter(ib));\n\tCHECK(base(r.in) == ia+2);\n\tCHECK(base(r.out) == ib+2);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 0);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+2))), InIter(ia+2), OutIter(ib));\n\tCHECK(base(r.in) == ia+2);\n\tCHECK(base(r.out) == ib+2);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+3))), InIter(ia), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+3))), InIter(ia+1), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 2);\n\tCHECK(ib[2] == 0);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+3))), InIter(ia+2), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 2);\n\tCHECK(ib[1] == 0);\n\tCHECK(ib[2] == 1);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+3))), InIter(ia+3), OutIter(ib));\n\tCHECK(base(r.in) == ia+3);\n\tCHECK(base(r.out) == ib+3);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+4))), InIter(ia), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\tCHECK(ib[3] == 3);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+4))), InIter(ia+1), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 1);\n\tCHECK(ib[1] == 2);\n\tCHECK(ib[2] == 3);\n\tCHECK(ib[3] == 0);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+4))), InIter(ia+2), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 2);\n\tCHECK(ib[1] == 3);\n\tCHECK(ib[2] == 0);\n\tCHECK(ib[3] == 1);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+4))), InIter(ia+3), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 3);\n\tCHECK(ib[1] == 0);\n\tCHECK(ib[2] == 1);\n\tCHECK(ib[3] == 2);\n\n\tr = ranges::rotate_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+4))), InIter(ia+4), OutIter(ib));\n\tCHECK(base(r.in) == ia+4);\n\tCHECK(base(r.out) == ib+4);\n\tCHECK(ib[0] == 0);\n\tCHECK(ib[1] == 1);\n\tCHECK(ib[2] == 2);\n\tCHECK(ib[3] == 3);\n}\n\ntemplate<class InIter, class OutIter, typename Sent = InIter>\nvoid test()\n{\n\ttest_iter<InIter, OutIter, Sent>();\n\ttest_rng<InIter, OutIter, Sent>();\n}\n\nstruct S\n{\n\tint i;\n};\n\nint main()\n{\n\ttest<forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*> >();\n\ttest<forward_iterator<const int*>, int*, sentinel<const int*> >();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*> >();\n\ttest<bidirectional_iterator<const int*>, int*, sentinel<const int*> >();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*>, sentinel<const int*> >();\n\ttest<random_access_iterator<const int*>, int*, sentinel<const int*> >();\n\n\ttest<const int*, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<int*> >();\n\ttest<const int*, int*>();\n\n\t// test rvalue range\n\t{\n\t\tint rgi[] = {0,1,2,3,4,5};\n\t\tint rgo[6] = {0};\n\t\tauto r = ranges::rotate_copy(std::move(rgi), rgi+2, rgo);\n\t\tstatic_assert(ranges::same_as<decltype(r.in), ranges::dangling>);\n\t\tCHECK(r.out == ranges::end(rgo));\n\t\tCHECK(rgo[0] == 2);\n\t\tCHECK(rgo[1] == 3);\n\t\tCHECK(rgo[2] == 4);\n\t\tCHECK(rgo[3] == 5);\n\t\tCHECK(rgo[4] == 0);\n\t\tCHECK(rgo[5] == 1);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/sample.cpp",
    "content": "// Range v3 lbrary\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distrbution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distrbuted under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/sample.hpp>\n\n#include <array>\n#include <numeric>\n#include <stl2/detail/algorithm/equal.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\ttemplate<class I, ranges::sentinel_for<I> S>\n\tbool in_sequence(I first, I mid, S last)\n\t{\n\t\tfor (; first != mid; ++first)\n\t\t\tSTL2_ASSERT(first != last);\n\t\tfor (; first != last; ++first)\n\t\t\t;\n\t\treturn true;\n\t}\n\n\tstruct MoveOnly {\n\t\tMoveOnly() = default;\n\t\tMoveOnly(MoveOnly&&) = default;\n\t\tMoveOnly& operator=(MoveOnly&&) & = default;\n\t};\n}\n\nint main() {\n\tconstexpr unsigned N = 100;\n\tconstexpr unsigned K = 10;\n\t{\n\t\tstd::array<int, N> i;\n\t\tstd::iota(std::begin(i), std::end(i), 0);\n\t\tstd::array<int, K> a{}, b{}, c{};\n\t\tstd::minstd_rand g1, g2 = g1;\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(random_access_iterator<int*>(i.data()),\n\t\t\t\tsentinel<int*>(i.data()+N), a.begin(), K, g1);\n\t\t\tCHECK(in_sequence(i.data(), result.in.base(), i.data() + N));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, c));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i.begin(), i.end(), b.begin(), K, g1);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t\tCHECK(!ranges::equal(b, c));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i.begin(), i.end(), c.begin(), K, g2);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == c.end());\n\t\t\tCHECK(ranges::equal(a, c));\n\t\t}\n\t}\n\n\t{\n\t\tstd::array<int, N> i;\n\t\tstd::iota(std::begin(i), std::end(i), 0);\n\t\tstd::array<int, K> a{}, b{}, c{};\n\t\tstd::minstd_rand g1, g2 = g1;\n\t\tauto rng = ranges::subrange(random_access_iterator<int*>(i.data()), sentinel<int*>(i.data() + N));\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(rng, a.begin(), K, g1);\n\t\t\tCHECK(in_sequence(ranges::begin(rng), result.in, ranges::end(rng)));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i, b.begin(), K, g2);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(ranges::equal(a, b));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i, b.begin(), K, g1);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t\tCHECK(!ranges::equal(b, c));\n\t\t}\n\n\t\t{\n\t\t\ta.fill(0);\n\t\t\tauto result = ranges::ext::sample(std::move(rng), a.begin(), K, g1);\n\t\t\tCHECK(in_sequence(ranges::begin(rng), result.in, ranges::end(rng)));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, c));\n\t\t}\n\t}\n\n\t{\n\t\tstd::array<int, N> i;\n\t\tstd::iota(std::begin(i), std::end(i), 0);\n\t\tstd::array<int, K> a{}, b{}, c{};\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(random_access_iterator<int*>(i.data()),\n\t\t\t\tsentinel<int*>(i.data() + N), a.begin(), K);\n\t\t\tCHECK(in_sequence(i.data(), result.in.base(), i.data() + N));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i, b.begin(), K);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(!ranges::equal(b, c));\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t}\n\t}\n\n\t{\n\t\tstd::array<MoveOnly, 10> source;\n\t\tstd::array<MoveOnly, 4> dest;\n\t\tauto result = ranges::ext::sample(ranges::make_move_iterator(source.begin()),\n\t\t\tranges::make_move_sentinel(source.end()),\n\t\t\tforward_iterator<MoveOnly*>(dest.data()), dest.size());\n\t\tCHECK(in_sequence(ranges::make_move_iterator(source.begin()),\n\t\t\tresult.in,\n\t\t\tranges::make_move_sentinel(source.end())));\n\t\tCHECK(result.out == forward_iterator<MoveOnly*>(dest.data() + dest.size()));\n\t}\n\n\t{\n\t\tstd::array<int, N> i;\n\t\tstd::iota(std::begin(i), std::end(i), 0);\n\t\tstd::array<int, K> a{}, b{}, c{};\n\t\tstd::minstd_rand g1, g2 = g1;\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(random_access_iterator<int*>(i.data()),\n\t\t\t\tsentinel<int*>(i.data()+N), a, g1);\n\t\t\tCHECK(in_sequence(i.data(), result.in.base(), i.data() + N));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, c));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i.begin(), i.end(), b, g1);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t\tCHECK(!ranges::equal(b, c));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i.begin(), i.end(), c, g2);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == c.end());\n\t\t\tCHECK(ranges::equal(a, c));\n\t\t}\n\t}\n\n\t{\n\t\tstd::array<int, N> i;\n\t\tstd::iota(std::begin(i), std::end(i), 0);\n\t\tstd::array<int, K> a{}, b{}, c{};\n\t\tstd::minstd_rand g1, g2 = g1;\n\t\tauto rng = ranges::subrange(random_access_iterator<int*>(i.data()), sentinel<int*>(i.data() + N));\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(rng, a, g1);\n\t\t\tCHECK(in_sequence(i.data(), result.in.base(), i.data() + N));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i, b, g2);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(ranges::equal(a, b));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i, b, g1);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t\tCHECK(!ranges::equal(b, c));\n\t\t}\n\n\t\t{\n\t\t\ta.fill(0);\n\t\t\tauto result = ranges::ext::sample(std::move(rng), a, g1);\n\t\t\tCHECK(in_sequence(i.data(), result.in.base(), i.data() + N));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, c));\n\t\t}\n\t}\n\n\t{\n\t\tstd::array<int, N> i;\n\t\tstd::iota(std::begin(i), std::end(i), 0);\n\t\tstd::array<int, K> a{}, b{}, c{};\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(random_access_iterator<int*>(i.data()),\n\t\t\t\tsentinel<int*>(i.data() + N), a);\n\t\t\tCHECK(in_sequence(i.data(), result.in.base(), i.data() + N));\n\t\t\tCHECK(result.out == a.end());\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t}\n\n\t\t{\n\t\t\tauto result = ranges::ext::sample(i, b);\n\t\t\tCHECK(in_sequence(i.begin(), result.in, i.end()));\n\t\t\tCHECK(result.out == b.end());\n\t\t\tCHECK(!ranges::equal(b, c));\n\t\t\tCHECK(!ranges::equal(a, b));\n\t\t}\n\t}\n\n\t{\n\t\tstd::array<MoveOnly, 10> source;\n\t\tstd::array<MoveOnly, 4> dest;\n\t\tauto out = ranges::subrange(\n\t\t\tforward_iterator<MoveOnly*>(dest.data()),\n\t\t\tsentinel<MoveOnly*, true>(dest.data() + dest.size()));\n\t\tauto result = ranges::ext::sample(ranges::make_move_iterator(source.begin()),\n\t\t\tranges::make_move_sentinel(source.end()), out);\n\t\tCHECK(in_sequence(source.begin(), result.in.base(), source.end()));\n\t\tCHECK(result.out == ranges::end(out));\n\t}\n\n\t{\n\t\tint data[] = {0,1,2,3};\n\t\tint sample[2];\n\t\tstd::minstd_rand g;\n\t\t{\n\t\t\tauto result = ranges::ext::sample(data, sample, g);\n\t\t\tCHECK(in_sequence(ranges::begin(data), result.in, ranges::end(data)));\n\t\t\tCHECK(result.out == ranges::end(sample));\n\t\t}\n\t\t{\n\t\t\tauto result = ranges::ext::sample(data, sample);\n\t\t\tCHECK(in_sequence(ranges::begin(data), result.in, ranges::end(data)));\n\t\t\tCHECK(result.out == ranges::end(sample));\n\t\t}\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/search.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/search.hpp>\n#include <initializer_list>\n#include <stl2/functional.hpp>\n#include <stl2/iterator.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\nusing ranges::subrange;\n\ntemplate<class I>\nconstexpr bool eq(subrange<I> const& x, subrange<I> const& y) {\n\treturn x.begin() == y.begin() && x.end() == y.end();\n}\n\ntemplate<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>\nvoid\ntest_iter_impl()\n{\n\tint ia[] = {0, 1, 2, 3, 4, 5};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia))));\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia + 1)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia+1))));\n\tCHECK(eq(subrange{Iter1(ia + 1), Iter1(ia+2)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+1), Sent2(ia+2))));\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+2))));\n\tCHECK(eq(subrange{Iter1(ia+2), Iter1(ia+3)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+2), Sent2(ia+3))));\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia)},\n\t\tranges::search(Iter1(ia), Sent1(ia), Iter2(ia+2), Sent2(ia+3))));\n\tCHECK(eq(subrange{Iter1(ia+sa-1), Iter1(ia+sa)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+sa-1), Sent2(ia+sa))));\n\tCHECK(eq(subrange{Iter1(ia+sa-3), Iter1(ia+sa)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia+sa-3), Sent2(ia+sa))));\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia+sa)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa), Iter2(ia), Sent2(ia+sa))));\n\tCHECK(eq(subrange{Iter1(ia+sa-1), Iter1(ia+sa-1)},\n\t\tranges::search(Iter1(ia), Sent1(ia+sa-1), Iter2(ia), Sent2(ia+sa))));\n\tCHECK(eq(subrange{Iter1(ia+1), Iter1(ia+1)},\n\t\tranges::search(Iter1(ia), Sent1(ia+1), Iter2(ia), Sent2(ia+sa))));\n\n\tint ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[] = {1};\n\tCHECK(eq(subrange{Iter1(ib+1), Iter1(ib+2)},\n\t\tranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ic), Sent2(ic+1))));\n\tint id[] = {1, 2};\n\tCHECK(eq(subrange{Iter1(ib+1), Iter1(ib+3)},\n\t\tranges::search(Iter1(ib), Sent1(ib+sb), Iter2(id), Sent2(id+2))));\n\tint ie[] = {1, 2, 3};\n\tCHECK(eq(subrange{Iter1(ib+4), Iter1(ib+7)},\n\t\tranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ie), Sent2(ie+3))));\n\tint ig[] = {1, 2, 3, 4};\n\tCHECK(eq(subrange{Iter1(ib+8), Iter1(ib+12)},\n\t\tranges::search(Iter1(ib), Sent1(ib+sb), Iter2(ig), Sent2(ig+4))));\n\n\tint ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};\n\tconst unsigned sh = sizeof(ih)/sizeof(ih[0]);\n\tint ii[] = {1, 1, 2};\n\tCHECK(eq(subrange{Iter1(ih+3), Iter1(ih+6)},\n\t\tranges::search(Iter1(ih), Sent1(ih+sh), Iter2(ii), Sent2(ii+3))));\n\n\tint ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};\n\tconst unsigned sj = sizeof(ij)/sizeof(ij[0]);\n\tint ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};\n\tconst unsigned sk = sizeof(ik)/sizeof(ik[0]);\n\tCHECK(eq(subrange{Iter1(ij+6), Iter1(ij+6+sk)},\n\t\tranges::search(Iter1(ij), Sent1(ij+sj), Iter2(ik), Sent2(ik+sk))));\n}\n\ntemplate<class Iter1, class Iter2>\nvoid\ntest_iter()\n{\n\tusing Sent1 = typename sentinel_type<Iter1>::type;\n\tusing Sent2 = typename sentinel_type<Iter2>::type;\n\ttest_iter_impl<Iter1, Iter2>();\n\ttest_iter_impl<Iter1, Iter2, Sent1>();\n\ttest_iter_impl<Iter1, Iter2, Iter1, Sent2>();\n\ttest_iter_impl<Iter1, Iter2, Sent1, Sent2>();\n\n\tusing SizedSent1 = typename sentinel_type<Iter1, true>::type;\n\tusing SizedSent2 = typename sentinel_type<Iter2, true>::type;\n\ttest_iter_impl<Iter1, Iter2, SizedSent1, SizedSent2>();\n}\n\ntemplate<class Iter1, class Iter2, typename Sent1 = Iter1, typename Sent2 = Iter2>\nvoid\ntest_range_impl()\n{\n\tint ia[] = {0, 1, 2, 3, 4, 5};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tauto const all_of_a = subrange{Iter1(ia), Iter1(ia+sa)};\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia)},\n\t\tranges::search(all_of_a, subrange(Iter2(ia), Sent2(ia)))));\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia+1)},\n\t\tranges::search(all_of_a, subrange(Iter2(ia), Sent2(ia+1)))));\n\tCHECK(eq(subrange{Iter1(ia+1), Iter1(ia+2)},\n\t\tranges::search(all_of_a, subrange(Iter2(ia+1), Sent2(ia+2)))));\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia)},\n\t\tranges::search(all_of_a, subrange(Iter2(ia+2), Sent2(ia+2)))));\n\tCHECK(eq(subrange{Iter1(ia+2), Iter1(ia+3)},\n\t\tranges::search(all_of_a, subrange(Iter2(ia+2), Sent2(ia+3)))));\n\tCHECK(eq(subrange{Iter1(ia), Iter1(ia)},\n\t\tranges::search(subrange(Iter1(ia), Sent1(ia)), subrange(Iter2(ia+2), Sent2(ia+3)))));\n\tCHECK(eq(subrange{Iter1(ia+sa-3), Iter1(ia+sa)},\n\t\tranges::search(all_of_a, subrange(Iter2(ia+sa-3), Sent2(ia+sa)))));\n\tCHECK(eq(subrange{Iter1(ia+sa-1), Iter1(ia+sa)},\n\t\tranges::search(all_of_a, subrange(Iter2(ia+sa-1), Sent2(ia+sa)))));\n\tCHECK(eq(all_of_a,\n\t\tranges::search(all_of_a, subrange(Iter2(ia), Sent2(ia+sa)))));\n\tCHECK(eq(subrange{Iter1(ia+sa-1), Iter1(ia+sa-1)},\n\t\tranges::search(subrange(Iter1(ia), Sent1(ia+sa-1)), subrange(Iter2(ia), Sent2(ia+sa)))));\n\tCHECK(eq(subrange{Iter1(ia+1), Iter1(ia+1)},\n\t\tranges::search(subrange(Iter1(ia), Sent1(ia+1)), subrange(Iter2(ia), Sent2(ia+sa)))));\n\n\tint ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tauto const all_of_b = subrange{Iter1(ib), Iter1(ib+sb)};\n\tint ic[] = {1};\n\tCHECK(eq(subrange{Iter1(ib+1), Iter1(ib+2)},\n\t\tranges::search(all_of_b, subrange(Iter2(ic), Sent2(ic+1)))));\n\n\tint id[] = {1, 2};\n\tCHECK(eq(subrange{Iter1(ib+1), Iter1(ib+3)},\n\t\tranges::search(all_of_b, subrange(Iter2(id), Sent2(id+2)))));\n\n\tint ie[] = {1, 2, 3};\n\tCHECK(eq(subrange{Iter1(ib+4), Iter1(ib+7)},\n\t\tranges::search(all_of_b, subrange(Iter2(ie), Sent2(ie+3)))));\n\n\tint ig[] = {1, 2, 3, 4};\n\tCHECK(eq(subrange{Iter1(ib+8), Iter1(ib+12)},\n\t\tranges::search(all_of_b, subrange(Iter2(ig), Sent2(ig+4)))));\n\n\tint ih[] = {0, 1, 1, 1, 1, 2, 3, 0, 1, 2, 3, 4};\n\tconst unsigned sh = sizeof(ih)/sizeof(ih[0]);\n\tint ii[] = {1, 1, 2};\n\tCHECK(eq(subrange{Iter1(ih+3), Iter1(ih+6)},\n\t\tranges::search(subrange(Iter1(ih), Sent1(ih+sh)),\n\t\t\tsubrange(Iter2(ii), Sent2(ii+3)))));\n\n\tint ij[] = {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0};\n\tconst unsigned sj = sizeof(ij)/sizeof(ij[0]);\n\tint ik[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0};\n\tconst unsigned sk = sizeof(ik)/sizeof(ik[0]);\n\tCHECK(eq(subrange{Iter1(ij+6), Iter1(ij+6+sk)},\n\t\tranges::search(subrange(Iter1(ij), Sent1(ij+sj)),\n\t\t\tsubrange(Iter2(ik), Sent2(ik+sk)))));\n}\n\ntemplate<class Iter1, class Iter2>\nvoid\ntest_range()\n{\n\tusing Sent1 = typename sentinel_type<Iter1>::type;\n\tusing Sent2 = typename sentinel_type<Iter2>::type;\n\ttest_range_impl<Iter1, Iter2>();\n\ttest_range_impl<Iter1, Iter2, Sent1>();\n\ttest_range_impl<Iter1, Iter2, Iter1, Sent2>();\n\ttest_range_impl<Iter1, Iter2, Sent1, Sent2>();\n\n\tusing SizedSent1 = typename sentinel_type<Iter1, true>::type;\n\tusing SizedSent2 = typename sentinel_type<Iter2, true>::type;\n\ttest_range_impl<Iter1, Iter2, SizedSent1, SizedSent2>();\n}\n\ntemplate<class Iter1, class Iter2>\nvoid\ntest()\n{\n\ttest_iter<Iter1, Iter2>();\n\ttest_range<Iter1, Iter2>();\n}\n\nstruct S\n{\n\tint i;\n};\n\nstruct T\n{\n\tint i;\n};\n\nint main()\n{\n\ttest<forward_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*> >();\n\n\t// Test projections:\n\t{\n\t\tS const in[] = {{0}, {1}, {2}, {3}, {4}, {5}};\n\t\tT const pat[] = {{2}, {3}};\n\n\t\tauto result = ranges::search(in, pat, ranges::equal_to{}, &S::i, &T::i);\n\t\tCHECK(result.begin() == in+2);\n\t\tCHECK(result.end() == in+4);\n\t}\n\n\t// Test counted ranges\n\t{\n\t\tint in[] = {0,1,2,3,4,5};\n\t\tauto rng = subrange(\n\t\t\t\t\t ranges::counted_iterator{\n\t\t\t\t\t   bidirectional_iterator<int*>(in), 6},\n\t\t\t\t\t ranges::default_sentinel);\n\t\t{\n\t\t\tauto [b, e] = ranges::search(rng, std::initializer_list<int>{2,3});\n\t\t\tCHECK(base(b.base()) == in+2);\n\t\t\tCHECK(b.count() == 4);\n\t\t\tCHECK((e - b) == 2);\n\t\t}\n\n\t\tauto [b, e] = ranges::search(rng, std::initializer_list<int>{5,6});\n\t\tCHECK(base(b.base()) == in+6);\n\t\tCHECK(b.count() == 0);\n\t\tCHECK((e - b) == 0);\n\t}\n\n\t// Test rvalue ranges\n\t{\n\t\tint ib[] = {0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};\n\t\tint ie[] = {1, 2, 3};\n\t\tCHECK(eq(subrange{ib+4, ib+7},\n\t\t\tranges::search(ranges::subrange(ib), ie)));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/search_n.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/search_n.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter, typename Sent = Iter>\nvoid test_iter_impl() {\n\tint ia[] = {0, 1, 2, 3, 4, 5};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 0) == Iter(ia));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 0) == Iter(ia+0));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 0) == Iter(ia+sa));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 0) == Iter(ia+sa));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 3) == Iter(ia));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 3) == Iter(ia+3));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 3) == Iter(ia+sa));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 3) == Iter(ia+sa));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 0, 5) == Iter(ia));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 1, 5) == Iter(ia+5));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), 2, 5) == Iter(ia+sa));\n\tCHECK(ranges::search_n(Iter(ia), Sent(ia+sa), sa, 5) == Iter(ia+sa));\n\n\tint ib[] = {0, 0, 1, 1, 2, 2};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 0) == Iter(ib));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 0) == Iter(ib+0));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 0) == Iter(ib+0));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 0) == Iter(ib+sb));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 0) == Iter(ib+sb));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 1) == Iter(ib));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 1) == Iter(ib+2));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 1) == Iter(ib+2));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 1) == Iter(ib+sb));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 1) == Iter(ib+sb));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 0, 2) == Iter(ib));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 1, 2) == Iter(ib+4));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 2, 2) == Iter(ib+4));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), 3, 2) == Iter(ib+sb));\n\tCHECK(ranges::search_n(Iter(ib), Sent(ib+sb), sb, 2) == Iter(ib+sb));\n\n\tint ic[] = {0, 0, 0};\n\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\tCHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 0, 0) == Iter(ic));\n\tCHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 1, 0) == Iter(ic));\n\tCHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 2, 0) == Iter(ic));\n\tCHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 3, 0) == Iter(ic));\n\tCHECK(ranges::search_n(Iter(ic), Sent(ic+sc), 4, 0) == Iter(ic+sc));\n}\n\ntemplate<class Iter, class Iter2>\nvoid test_iter() {\n\tusing Sent = typename sentinel_type<Iter>::type;\n\ttest_iter_impl<Iter>();\n\ttest_iter_impl<Iter, Sent>();\n\n\tusing SizedSent1 = typename sentinel_type<Iter, true>::type;\n\ttest_iter_impl<Iter, SizedSent1>();\n}\n\ntemplate<class Iter, typename Sent = Iter>\nvoid test_range_impl() {\n\tint ia[] = {0, 1, 2, 3, 4, 5};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 0, 0) == Iter(ia));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 1, 0) == Iter(ia+0));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 2, 0) == Iter(ia+sa));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), sa, 0) == Iter(ia+sa));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 0, 3) == Iter(ia));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 1, 3) == Iter(ia+3));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 2, 3) == Iter(ia+sa));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), sa, 3) == Iter(ia+sa));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 0, 5) == Iter(ia));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 1, 5) == Iter(ia+5));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), 2, 5) == Iter(ia+sa));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ia), Sent(ia+sa))), sa, 5) == Iter(ia+sa));\n\n\tint ib[] = {0, 0, 1, 1, 2, 2};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 0, 0) == Iter(ib));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 1, 0) == Iter(ib+0));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 2, 0) == Iter(ib+0));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 3, 0) == Iter(ib+sb));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), sb, 0) == Iter(ib+sb));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 0, 1) == Iter(ib));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 1, 1) == Iter(ib+2));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 2, 1) == Iter(ib+2));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 3, 1) == Iter(ib+sb));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), sb, 1) == Iter(ib+sb));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 0, 2) == Iter(ib));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 1, 2) == Iter(ib+4));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 2, 2) == Iter(ib+4));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), 3, 2) == Iter(ib+sb));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ib), Sent(ib+sb))), sb, 2) == Iter(ib+sb));\n\n\tint ic[] = {0, 0, 0};\n\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ic), Sent(ic+sc))), 0, 0) == Iter(ic));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ic), Sent(ic+sc))), 1, 0) == Iter(ic));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ic), Sent(ic+sc))), 2, 0) == Iter(ic));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ic), Sent(ic+sc))), 3, 0) == Iter(ic));\n\tCHECK(ranges::search_n(::as_lvalue(ranges::subrange(Iter(ic), Sent(ic+sc))), 4, 0) == Iter(ic+sc));\n}\n\ntemplate<class Iter, class Iter2>\nvoid test_range() {\n\tusing Sent = typename sentinel_type<Iter>::type;\n\ttest_range_impl<Iter>();\n\ttest_range_impl<Iter, Sent>();\n\n\tusing SizedSent1 = typename sentinel_type<Iter, true>::type;\n\ttest_range_impl<Iter, SizedSent1>();\n}\n\ntemplate<class Iter, class Iter2>\nvoid test() {\n\ttest_iter<Iter, Iter2>();\n\ttest_range<Iter, Iter2>();\n}\n\nstruct S {\n\tint i;\n};\n\nint main() {\n\ttest<forward_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*> >();\n\n\t// Test projections:\n\t{\n\t\tS const in[] = {{0}, {1}, {2}, {2}, {4}, {5}};\n\n\t\tS const *p = ranges::search_n(in, 2, 2, std::equal_to<int>{}, &S::i);\n\t\tCHECK(p == in+2);\n\t}\n\n\t// Test counted ranges\n\t{\n\t\tint in[] = {0,1,2,2,4,5};\n\t\tauto rng = ranges::subrange(\n\t\t\t\t\t ranges::counted_iterator{bidirectional_iterator<int*>(in), 6},\n\t\t\t\t\t ranges::default_sentinel);\n\t\tauto it = ranges::search_n(rng, 2, 2);\n\t\tCHECK(base(it.base()) == in+2);\n\t\tCHECK(it.count() == 4);\n\n\t\tauto it2 = ranges::search_n(rng, 3, 2);\n\t\tCHECK(base(it2.base()) == in+6);\n\t\tCHECK(it2.count() == 0);\n\t}\n\n\t// Test rvalue ranges\n\t{\n\t\tint ib[] = {0, 0, 1, 1, 2, 2};\n\t\tCHECK(ranges::search_n(ranges::subrange(ib), 2, 1) == ib+2);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_difference.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/set_difference.hpp>\n#include <stl2/detail/algorithm/fill.hpp>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid test_iter() {\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4, 4, 6};\n\tconst int sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[20];\n\tint ir[] = {1, 2, 3, 3, 3, 4, 4};\n\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\tauto set_difference = ::make_testable_2<false, true>([](auto&&... args) {\n\t\treturn ranges::set_difference(std::forward<decltype(args)>(args)...);\n\t});\n\n\tset_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic)).\n\t\tcheck([&](ranges::set_difference_result<Iter1, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.in) - ia) == sa));\n\t\t\tCHECK(bool((base(res.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), ir, ir+sr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n\tint irr[] = {6};\n\tconst int srr = sizeof(irr)/sizeof(irr[0]);\n\tset_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic)).\n\t\tcheck([&](ranges::set_difference_result<Iter1, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.in) - ib) == sb));\n\t\t\tCHECK(bool((base(res.out) - ic) == srr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), irr, irr+srr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n}\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid test_comp() {\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4, 4, 6};\n\tconst int sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[20];\n\tint ir[] = {1, 2, 3, 3, 3, 4, 4};\n\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\tauto set_difference = ::make_testable_2<false, true>([](auto&&... args) {\n\t\treturn ranges::set_difference(std::forward<decltype(args)>(args)...);\n\t});\n\n\tset_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic), std::less<int>()).\n\t\tcheck([&](ranges::set_difference_result<Iter1, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.in) - ia) == sa));\n\t\t\tCHECK(bool((base(res.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), ir, ir+sr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n\tint irr[] = {6};\n\tconst int srr = sizeof(irr)/sizeof(irr[0]);\n\tset_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic), std::less<int>()).\n\t\tcheck([&](ranges::set_difference_result<Iter1, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.in) - ib) == sb));\n\t\t\tCHECK(bool((base(res.out) - ic) == srr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), irr, irr+srr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n}\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid test() {\n\ttest_iter<Iter1, Iter2, OutIter>();\n\ttest_comp<Iter1, Iter2, OutIter>();\n}\n\nstruct S {\n\tint i;\n};\n\nstruct T {\n\tint j;\n};\n\nstruct U {\n\tint k;\n\tU& operator=(S s) { k = s.i; return *this;}\n\tU& operator=(T t) { k = t.j; return *this;}\n};\n"
  },
  {
    "path": "test/algorithm/set_difference1.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_difference.hpp\"\n\nint main()\n{\n\ttest<input_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_difference2.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_difference.hpp\"\n\nint main()\n{\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_difference3.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_difference.hpp\"\n\nint main()\n{\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_difference4.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_difference.hpp\"\n\nint main()\n{\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_difference5.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_difference.hpp\"\n\nint main() {\n\ttest<const int*, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, int*>();\n\n\ttest<const int*, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, int*>();\n\n\ttest<const int*, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, int*>();\n\n\ttest<const int*, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, const int*, output_iterator<int*> >();\n\ttest<const int*, const int*, forward_iterator<int*> >();\n\ttest<const int*, const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, const int*, random_access_iterator<int*> >();\n\ttest<const int*, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_difference6.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_difference.hpp\"\n#include <stl2/detail/algorithm/lexicographical_compare.hpp>\n\nint main() {\n\t// Test projections\n\t{\n\t\tS ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};\n\t\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\t\tT ib[] = {T{2}, T{4}, T{4}, T{6}};\n\t\tconst int sb = sizeof(ib)/sizeof(ib[0]);\n\t\tU ic[20];\n\t\tint ir[] = {1, 2, 3, 3, 3, 4, 4};\n\t\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\t\tranges::set_difference_result<S*, U*> res =\n\t\t\tranges::set_difference(ia, ib, ic, std::less<int>(), &S::i, &T::j);\n\t\tCHECK((res.in - ia) == sa);\n\t\tCHECK((res.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res.out, ir, ir+sr,\n\t\t\tstd::less<int>(), &U::k));\n\t\tranges::fill(ic, U{0});\n\n\t\tint irr[] = {6};\n\t\tconst int srr = sizeof(irr)/sizeof(irr[0]);\n\t\tranges::set_difference_result<T*, U*> res2 =\n\t\t\tranges::set_difference(ib, ia, ic, std::less<int>(), &T::j, &S::i);\n\t\tCHECK((res2.in - ib) == sb);\n\t\tCHECK((res2.out - ic) == srr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res2.out, ir, irr+srr,\n\t\t\tstd::less<int>(), &U::k));\n\t}\n\n\t// Test rvalue ranges\n\t{\n\t\tS ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};\n\t\tT ib[] = {T{2}, T{4}, T{4}, T{6}};\n\t\tU ic[20];\n\t\tint ir[] = {1, 2, 3, 3, 3, 4, 4};\n\t\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\t\tauto res = ranges::set_difference(std::move(ia), std::move(ib), ic,\n\t\t\tstd::less<int>(), &S::i, &T::j);\n\t\tstatic_assert(ranges::same_as<decltype(res.in), ranges::dangling>);\n\t\tCHECK((res.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res.out, ir, ir+sr,\n\t\t\tstd::less<int>(), &U::k));\n\t\tranges::fill(ic, U{0});\n\n\t\tint irr[] = {6};\n\t\tconst int srr = sizeof(irr)/sizeof(irr[0]);\n\t\tauto res2 = ranges::set_difference(std::move(ib), std::move(ia), ic,\n\t\t\tstd::less<int>(), &T::j, &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(res2.in), ranges::dangling>);\n\t\tCHECK((res2.out - ic) == srr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res2.out, ir, irr+srr,\n\t\t\tstd::less<int>(), &U::k));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_intersection.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/set_intersection.hpp>\n#include <stl2/detail/algorithm/fill.hpp>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid\ntest()\n{\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4, 4, 6};\n\tconst int sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[20];\n\tint ir[] = {2, 4, 4};\n\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\tauto set_intersection = ::make_testable_2<true, true>([](auto&&... args) {\n\t\treturn stl2::set_intersection(std::forward<decltype(args)>(args)...);\n\t});\n\n\tset_intersection(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic))\n\t\t.check([&](auto result) {\n\t\t\tCHECK(bool((base(result.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(result.out), ir, ir+sr));\n\t\t\tstl2::fill(ic, 0);\n\t\t});\n\tset_intersection(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic))\n\t\t.check([&](auto result) {\n\t\t\tCHECK(bool((base(result.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(result.out), ir, ir+sr));\n\t\t\tstl2::fill(ic, 0);\n\t\t});\n\n\n\tset_intersection(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic), stl2::less{})\n\t\t.check([&](auto result) {\n\t\t\tCHECK(bool((base(result.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(result.out), ir, ir+sr));\n\t\t\tstl2::fill(ic, 0);\n\t\t});\n\tset_intersection(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic), stl2::less{})\n\t\t.check([&](auto result) {\n\t\t\tCHECK(bool((base(result.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(result.out), ir, ir+sr));\n\t\t\tstl2::fill(ic, 0);\n\t\t});\n}\n\nstruct S\n{\n\tint i;\n};\n\nstruct T\n{\n\tint j;\n};\n\nstruct U\n{\n\tint k;\n\tU& operator=(S s) { k = s.i; return *this;}\n\tU& operator=(T t) { k = t.j; return *this;}\n};\n"
  },
  {
    "path": "test/algorithm/set_intersection1.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_intersection.hpp\"\n\nint main()\n{\n\ttest<input_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_intersection2.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_intersection.hpp\"\n\nint main()\n{\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_intersection3.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_intersection.hpp\"\n\nint main()\n{\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_intersection4.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_intersection.hpp\"\n\nint main()\n{\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_intersection5.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_intersection.hpp\"\n\nint main()\n{\n\ttest<const int*, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, int*>();\n\n\ttest<const int*, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, int*>();\n\n\ttest<const int*, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, int*>();\n\n\ttest<const int*, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, const int*, output_iterator<int*> >();\n\ttest<const int*, const int*, forward_iterator<int*> >();\n\ttest<const int*, const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, const int*, random_access_iterator<int*> >();\n\ttest<const int*, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_intersection6.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include <array>\n#include \"set_intersection.hpp\"\n#include <stl2/detail/algorithm/lexicographical_compare.hpp>\n\nint main()\n{\n\t// Test projections\n\t{\n\t\tconst auto in1 = std::array{S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};\n\t\tconst auto in2 = std::array{T{2}, T{4}, T{4}, T{6}};\n\t\tauto out = std::array<U, 20>{};\n\t\tconst auto expected = std::array{2, 4, 4};\n\n\t\tauto result = stl2::set_intersection(in1, in2, stl2::begin(out), stl2::less{}, &S::i, &T::j);\n\t\tCHECK((result.out - stl2::begin(out)) == stl2::distance(expected));\n\t\tCHECK(!stl2::lexicographical_compare(\n\t\t\tstl2::begin(out), result.out,\n\t\t\tstl2::begin(expected), stl2::end(expected),\n\t\t\tstl2::less{}, &U::k));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_symmetric_difference.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/set_symmetric_difference.hpp>\n#include <stl2/detail/algorithm/fill.hpp>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid test_iter() {\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4, 4, 6};\n\tconst int sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[20];\n\tint ir[] = {1, 2, 3, 3, 3, 4, 4, 6};\n\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\tauto set_symmetric_difference = ::make_testable_2([](auto&&... args) {\n\t\treturn ranges::set_symmetric_difference(std::forward<decltype(args)>(args)...);\n\t});\n\n\tset_symmetric_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic)).\n\t\tcheck([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), ir, ir+sr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n\n\tset_symmetric_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic)).\n\t\tcheck([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), ir, ir+sr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n}\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid test_comp() {\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4, 4, 6};\n\tconst int sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[20];\n\tint ir[] = {1, 2, 3, 3, 3, 4, 4, 6};\n\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\tauto set_symmetric_difference = ::make_testable_2([](auto&&... args) {\n\t\treturn ranges::set_symmetric_difference(std::forward<decltype(args)>(args)...);\n\t});\n\n\tset_symmetric_difference(Iter1(ia), Iter1(ia+sa), Iter2(ib), Iter2(ib+sb), OutIter(ic), std::less<int>()).\n\t\tcheck([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), ir, ir+sr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n\n\tset_symmetric_difference(Iter1(ib), Iter1(ib+sb), Iter2(ia), Iter2(ia+sa), OutIter(ic), std::less<int>()).\n\t\tcheck([&](ranges::set_symmetric_difference_result<Iter1, Iter2, OutIter> res)\n\t\t{\n\t\t\tCHECK(bool((base(res.out) - ic) == sr));\n\t\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), ir, ir+sr));\n\t\t\tranges::fill(ic, 0);\n\t\t}\n\t);\n}\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid test() {\n\ttest_iter<Iter1, Iter2, OutIter>();\n\ttest_comp<Iter1, Iter2, OutIter>();\n}\n\nstruct S {\n\tint i;\n};\n\nstruct T {\n\tint j;\n};\n\nstruct U {\n\tint k;\n\tU& operator=(S s) { k = s.i; return *this;}\n\tU& operator=(T t) { k = t.j; return *this;}\n};\n"
  },
  {
    "path": "test/algorithm/set_symmetric_difference1.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_symmetric_difference.hpp\"\n\nint main()\n{\n\ttest<input_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_symmetric_difference2.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_symmetric_difference.hpp\"\n\nint main()\n{\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_symmetric_difference3.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_symmetric_difference.hpp\"\n\nint main()\n{\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_symmetric_difference4.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_symmetric_difference.hpp\"\n\nint main()\n{\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_symmetric_difference5.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_symmetric_difference.hpp\"\n\nint main()\n{\n\ttest<const int*, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, int*>();\n\n\ttest<const int*, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, int*>();\n\n\ttest<const int*, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, int*>();\n\n\ttest<const int*, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, const int*, output_iterator<int*> >();\n\ttest<const int*, const int*, forward_iterator<int*> >();\n\ttest<const int*, const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, const int*, random_access_iterator<int*> >();\n\ttest<const int*, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_symmetric_difference6.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_symmetric_difference.hpp\"\n#include <stl2/detail/algorithm/lexicographical_compare.hpp>\n\nint main() {\n\t// Test projections\n\t{\n\t\tS ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};\n\t\tT ib[] = {T{2}, T{4}, T{4}, T{6}};\n\t\tU ic[20];\n\t\tint ir[] = {1, 2, 3, 3, 3, 4, 4, 6};\n\t\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\t\tranges::set_symmetric_difference_result<S *, T *, U *> res1 =\n\t\t\tranges::set_symmetric_difference(ia, ib, ic, std::less<int>(), &S::i, &T::j);\n\t\tCHECK((res1.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res1.out, ir, ir+sr, std::less<int>(), &U::k));\n\t\tranges::fill(ic, U{0});\n\n\t\tranges::set_symmetric_difference_result<T *, S *, U *> res2 =\n\t\t\tranges::set_symmetric_difference(ib, ia, ic, std::less<int>(), &T::j, &S::i);\n\t\tCHECK((res2.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res2.out, ir, ir+sr, std::less<int>(), &U::k));\n\t}\n\n\t// Test rvalue ranges\n\t{\n\t\tS ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};\n\t\tT ib[] = {T{2}, T{4}, T{4}, T{6}};\n\t\tU ic[20];\n\t\tint ir[] = {1, 2, 3, 3, 3, 4, 4, 6};\n\t\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\t\tauto res1 =\n\t\t\tranges::set_symmetric_difference(std::move(ia), std::move(ib), ic, std::less<int>(), &S::i, &T::j);\n\t\tstatic_assert(ranges::same_as<decltype(res1.in1), ranges::dangling>);\n\t\tstatic_assert(ranges::same_as<decltype(res1.in2), ranges::dangling>);\n\t\tCHECK((res1.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res1.out, ir, ir+sr, std::less<int>(), &U::k));\n\t\tranges::fill(ic, U{0});\n\n\t\tauto res2 =\n\t\t\tranges::set_symmetric_difference(std::move(ib), std::move(ia), ic, std::less<int>(), &T::j, &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(res2.in1), ranges::dangling>);\n\t\tstatic_assert(ranges::same_as<decltype(res2.in2), ranges::dangling>);\n\t\tCHECK((res2.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res2.out, ir, ir+sr, std::less<int>(), &U::k));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_union.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/set_union.hpp>\n#include <stl2/detail/algorithm/fill.hpp>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter1, class Iter2, class OutIter>\nvoid test() {\n\tint ia[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};\n\tconst int sa = sizeof(ia)/sizeof(ia[0]);\n\tint ib[] = {2, 4, 4, 6};\n\tconst int sb = sizeof(ib)/sizeof(ib[0]);\n\tint ic[20];\n\tint ir[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 6};\n\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\tusing R = ranges::set_union_result<Iter1, Iter2, OutIter>;\n\tauto set_union = make_testable_2([](auto&&... args) {\n\t\treturn ranges::set_union(std::forward<decltype(args)>(args)...);\n\t});\n\n\tauto checker = [&](R res)\n\t{\n\t\tCHECK(bool((base(res.out) - ic) == sr));\n\t\tCHECK(!std::lexicographical_compare(ic, base(res.out), ir, ir+sr));\n\t\tranges::fill(ic, 0);\n\t};\n\n\tset_union(Iter1(ia), Iter1(ia+sa),\n\t\tIter2(ib), Iter2(ib+sb), OutIter(ic)).check(checker);\n\tset_union(Iter1(ib), Iter1(ib+sb),\n\t\tIter2(ia), Iter2(ia+sa), OutIter(ic)).check(checker);\n\n\tset_union(Iter1(ia), Iter1(ia+sa),\n\t\tIter2(ib), Iter2(ib+sb), OutIter(ic), std::less<int>()).check(checker);\n\tset_union(Iter1(ib), Iter1(ib+sb),\n\t\tIter2(ia), Iter2(ia+sa), OutIter(ic), std::less<int>()).check(checker);\n}\n\nstruct S {\n\tint i;\n};\n\nstruct T {\n\tint j;\n};\n\nstruct U {\n\tint k;\n\tU& operator=(S s) { k = s.i; return *this;}\n\tU& operator=(T t) { k = t.j; return *this;}\n};\n"
  },
  {
    "path": "test/algorithm/set_union1.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_union.hpp\"\n\nint main()\n{\n\ttest<input_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<input_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_union2.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_union.hpp\"\n\nint main()\n{\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_union3.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_union.hpp\"\n\nint main()\n{\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_union4.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_union.hpp\"\n\nint main()\n{\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, input_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, const int*, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_union5.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_union.hpp\"\n\nint main()\n{\n\ttest<const int*, input_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, input_iterator<const int*>, int*>();\n\n\ttest<const int*, forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, forward_iterator<const int*>, int*>();\n\n\ttest<const int*, bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<const int*>, int*>();\n\n\ttest<const int*, random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<const int*, random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, const int*, output_iterator<int*> >();\n\ttest<const int*, const int*, forward_iterator<int*> >();\n\ttest<const int*, const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, const int*, random_access_iterator<int*> >();\n\ttest<const int*, const int*, int*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/set_union6.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n\n#include \"set_union.hpp\"\n#include <stl2/detail/algorithm/lexicographical_compare.hpp>\n\nint main()\n{\n\t// Test projections\n\t{\n\t\tS ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};\n\t\tT ib[] = {T{2}, T{4}, T{4}, T{6}};\n\t\tU ic[20];\n\t\tint ir[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 6};\n\t\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\t\tusing R = ranges::set_union_result<S *, T*, U*>;\n\t\tR res = ranges::set_union(ia, ib, ic, std::less<int>(), &S::i, &T::j);\n\t\tCHECK((res.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res.out, ir, ir+sr, std::less<int>(), &U::k));\n\t\tranges::fill(ic, U{0});\n\n\t\tusing R2 = ranges::set_union_result<T *, S*, U*>;\n\t\tR2 res2 = ranges::set_union(ib, ia, ic, std::less<int>(), &T::j, &S::i);\n\t\tCHECK((res2.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res2.out, ir, ir+sr, std::less<int>(), &U::k));\n\t}\n\n\t// Test projections\n\t{\n\t\tS ia[] = {S{1}, S{2}, S{2}, S{3}, S{3}, S{3}, S{4}, S{4}, S{4}, S{4}};\n\t\tT ib[] = {T{2}, T{4}, T{4}, T{6}};\n\t\tU ic[20];\n\t\tint ir[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 6};\n\t\tconst int sr = sizeof(ir)/sizeof(ir[0]);\n\n\t\tauto res = ranges::set_union(std::move(ia), std::move(ib), ic, std::less<int>(), &S::i, &T::j);\n\t\tstatic_assert(ranges::same_as<decltype(res.in1), ranges::dangling>);\n\t\tstatic_assert(ranges::same_as<decltype(res.in2), ranges::dangling>);\n\t\tCHECK((res.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res.out, ir, ir+sr, std::less<int>(), &U::k));\n\t\tranges::fill(ic, U{0});\n\n\t\tauto res2 = ranges::set_union(std::move(ib), std::move(ia), ic, std::less<int>(), &T::j, &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(res2.in1), ranges::dangling>);\n\t\tstatic_assert(ranges::same_as<decltype(res2.in2), ranges::dangling>);\n\t\tCHECK((res2.out - ic) == sr);\n\t\tCHECK(!ranges::lexicographical_compare(ic, res2.out, ir, ir+sr, std::less<int>(), &U::k));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/shuffle.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/equal.hpp>\n#include <stl2/detail/algorithm/shuffle.hpp>\n#include <numeric>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nint main()\n{\n\t{\n\t\tint ia[100];\n\t\tconstexpr unsigned s = sizeof(ia)/sizeof(ia[0]);\n\t\tint ib[s];\n\t\tint orig[s];\n\t\tstd::iota(ia, ia + s, 0);\n\t\tstd::iota(ib, ib + s, 0);\n\t\tstd::iota(orig, orig + s, 0);\n\t\tstd::minstd_rand g;\n\t\tstl2::shuffle(random_access_iterator<int*>(ia), sentinel<int*>(ia+s), g);\n\t\tCHECK(!stl2::equal(ia, orig));\n\t\tCHECK(stl2::shuffle(ib, ib+s, g) == ib+s);\n\t\tCHECK(!stl2::equal(ia, ib));\n\t}\n\n\t{\n\t\tint ia[100];\n\t\tconstexpr unsigned s = sizeof(ia)/sizeof(ia[0]);\n\t\tint ib[100];\n\t\tint orig[100];\n\t\tstd::iota(ia, ia + s, 0);\n\t\tstd::iota(ib, ib + s, 0);\n\t\tstd::iota(orig, orig + s, 0);\n\t\tstd::minstd_rand g;\n\t\tauto rng = stl2::subrange(random_access_iterator<int*>(ia), sentinel<int*>(ia+s));\n\t\tstl2::shuffle(rng, g);\n\t\tCHECK(!stl2::equal(ia, orig));\n\t\tCHECK(stl2::shuffle(ib, g) == stl2::end(ib));\n\t\tCHECK(!stl2::equal(ia, ib));\n\n\t\tstd::iota(ia, ia + s, 0);\n\t\tCHECK(stl2::shuffle(std::move(rng), g).base() == stl2::end(ia));\n\t\tCHECK(!stl2::equal(ia, orig));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/sort.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/sort.hpp>\n#include <stl2/detail/algorithm/copy.hpp>\n#include <algorithm>\n#include <cassert>\n#include <memory>\n#include <random>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace { std::mt19937 gen; }\n\n// BUGBUG\nnamespace std\n{\n\ttemplate<typename F, typename S>\n\tstd::ostream & operator<<(std::ostream &sout, std::pair<F,S> const & p)\n\t{\n\t\treturn sout << '[' << p.first << ',' << p.second << ']';\n\t}\n}\n\nstruct first\n{\n\ttemplate<typename P>\n\tint operator()(P const & p) const\n\t{\n\t\treturn p.first;\n\t}\n};\n\nstruct indirect_less\n{\n\ttemplate<class P>\n\tbool operator()(const P& x, const P& y) const\n\t\t{return *x < *y;}\n};\n\ntemplate<class RI>\nvoid\ntest_sort_helper(RI f, RI l)\n{\n\tusing value_type = ranges::iter_value_t<RI>;\n\tauto sort = make_testable_1<false>([](auto&&... args) {\n\t\treturn ranges::sort(std::forward<decltype(args)>(args)...);\n\t});\n\tif (f != l)\n\t{\n\t\tauto len = ranges::distance(f, l);\n\t\tvalue_type* save(new value_type[len]);\n\t\tdo\n\t\t{\n\t\t\tstd::copy(f, l, save);\n\t\t\tsort(save, save+len).check([&](auto res)\n\t\t\t{\n\t\t\t\tCHECK(base(res) == save+len);\n\t\t\t\tCHECK(std::is_sorted(save, save+len));\n\t\t\t\tstd::copy(f, l, save);\n\t\t\t});\n\t\t\tsort(save, save+len, std::greater<int>{}).check([&](auto res)\n\t\t\t{\n\t\t\t\tCHECK(base(res) == save+len);\n\t\t\t\tCHECK(std::is_sorted(save, save+len, std::greater<int>{}));\n\t\t\t\tstd::copy(f, l, save);\n\t\t\t});\n\t\t} while (std::next_permutation(f, l));\n\t\tdelete [] save;\n\t}\n}\n\ntemplate<class RI>\nvoid\ntest_sort_driver_driver(RI f, RI l, int start, RI real_last)\n{\n\tfor (RI i = l; i > f + start;)\n\t{\n\t\t*--i = start;\n\t\tif (f == i)\n\t\t{\n\t\t\ttest_sort_helper(f, real_last);\n\t\t}\n\t\tif (start > 0)\n\t\t\ttest_sort_driver_driver(f, i, start-1, real_last);\n\t}\n}\n\ntemplate<class RI>\nvoid\ntest_sort_driver(RI f, RI l, int start)\n{\n\ttest_sort_driver_driver(f, l, start, l);\n}\n\ntemplate<int sa>\nvoid\ntest_sort_()\n{\n\tint ia[sa];\n\tfor (int i = 0; i < sa; ++i)\n\t{\n\t\ttest_sort_driver(ia, ia+sa, i);\n\t}\n}\n\nvoid\ntest_larger_sorts(int N, int M)\n{\n\tassert(N > 0);\n\tassert(M > 0);\n\t// create array length N filled with M different numbers\n\tint* array = new int[N];\n\tint x = 0;\n\tfor (int i = 0; i < N; ++i)\n\t{\n\t\tarray[i] = x;\n\t\tif (++x == M)\n\t\t\tx = 0;\n\t}\n\n\t// test saw tooth pattern\n\tCHECK(ranges::sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test random pattern\n\tstd::shuffle(array, array+N, gen);\n\tCHECK(ranges::sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test sorted pattern\n\tCHECK(ranges::sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test reverse sorted pattern\n\tstd::reverse(array, array+N);\n\tCHECK(ranges::sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test swap ranges 2 pattern\n\tstd::swap_ranges(array, array+N/2, array+N/2);\n\tCHECK(ranges::sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test reverse swap ranges 2 pattern\n\tstd::reverse(array, array+N);\n\tstd::swap_ranges(array, array+N/2, array+N/2);\n\tCHECK(ranges::sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\tdelete [] array;\n}\n\nvoid\ntest_larger_sorts(unsigned N)\n{\n\ttest_larger_sorts(N, 1);\n\ttest_larger_sorts(N, 2);\n\ttest_larger_sorts(N, 3);\n\ttest_larger_sorts(N, N/2-1);\n\ttest_larger_sorts(N, N/2);\n\ttest_larger_sorts(N, N/2+1);\n\ttest_larger_sorts(N, N-2);\n\ttest_larger_sorts(N, N-1);\n\ttest_larger_sorts(N, N);\n}\n\nstruct S\n{\n\tint i, j;\n};\n\nstruct Int\n{\n\tusing difference_type = int;\n\tint i_;\n\tInt(int i = 0) : i_(i) {}\n\tInt(Int && that) : i_(that.i_) { that.i_ = 0; }\n\tInt(Int const &) = delete;\n\tInt & operator=(Int && that)\n\t{\n\t\ti_ = that.i_;\n\t\tthat.i_ = 0;\n\t\treturn *this;\n\t}\n\tInt &operator++() { ++i_; return *this; }\n\tvoid operator++(int) { ++i_; }\n\tfriend bool operator==(Int const &a, Int const &b)\n\t{\n\t\treturn a.i_ == b.i_;\n\t}\n\tfriend bool operator!=(Int const &a, Int const &b)\n\t{\n\t\treturn !(a == b);\n\t}\n\tfriend bool operator<(Int const &a, Int const &b)\n\t{\n\t\treturn a.i_ < b.i_;\n\t}\n\tfriend bool operator>(Int const &a, Int const &b)\n\t{\n\t\treturn a.i_ > b.i_;\n\t}\n\tfriend bool operator<=(Int const &a, Int const &b)\n\t{\n\t\treturn a.i_ <= b.i_;\n\t}\n\tfriend bool operator>=(Int const &a, Int const &b)\n\t{\n\t\treturn a.i_ >= b.i_;\n\t}\n};\n\nint main()\n{\n\t// test null range\n\tint d = 0;\n\tranges::sort(&d, &d);\n\t// exhaustively test all possibilities up to length 8\n\ttest_sort_<1>();\n\ttest_sort_<2>();\n\ttest_sort_<3>();\n\ttest_sort_<4>();\n\ttest_sort_<5>();\n\ttest_sort_<6>();\n\ttest_sort_<7>();\n\ttest_sort_<8>();\n\n\ttest_larger_sorts(15);\n\ttest_larger_sorts(16);\n\ttest_larger_sorts(17);\n\ttest_larger_sorts(256);\n\ttest_larger_sorts(257);\n\ttest_larger_sorts(499);\n\ttest_larger_sorts(500);\n\ttest_larger_sorts(997);\n\ttest_larger_sorts(1000);\n\ttest_larger_sorts(1009);\n\n\t// Check move-only types\n\t{\n\t\tstd::vector<std::unique_ptr<int> > v(1000);\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t\tv[i].reset(new int(v.size() - i - 1));\n\t\tranges::sort(v, indirect_less());\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t\tCHECK(*v[i] == i);\n\t}\n\n\t// Check projections\n\t{\n\t\tstd::vector<S> v(1000, S{});\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tv[i].i = v.size() - i - 1;\n\t\t\tv[i].j = i;\n\t\t}\n\t\tranges::sort(v, std::less<int>{}, &S::i);\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tCHECK(v[i].i == i);\n\t\t\tCHECK((std::size_t)v[i].j == v.size() - i - 1);\n\t\t}\n\t}\n\n\t// Check rvalue range\n\t{\n\t\tstd::vector<S> v(1000, S{});\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tv[i].i = v.size() - i - 1;\n\t\t\tv[i].j = i;\n\t\t}\n\t\tauto r = ranges::sort(std::move(v), std::less<int>{}, &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(r), ranges::dangling>);\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tCHECK(v[i].i == i);\n\t\t\tCHECK((std::size_t)v[i].j == v.size() - i - 1);\n\t\t}\n\t}\n\n#if 0\n\t// Check sorting a zip view, which uses iter_move\n\t{\n\t\tusing namespace ranges;\n\t\tstd::vector<int> v0 =\n\t\t\tviews::for_each(views::ints(1,6) | views::reverse, [](int i){\n\t\t\t\treturn ranges::yield_from(views::repeat_n(i,i));\n\t\t\t});\n\t\tauto v1 = ranges::to_<std::vector<Int>>(\n\t\t\t{1,2,2,3,3,3,4,4,4,4,5,5,5,5,5});\n\t\tauto rng = views::zip(v0, v1);\n\t\tCHECK_EQUAL(v0,{5,5,5,5,5,4,4,4,4,3,3,3,2,2,1});\n\t\tCHECK_EQUAL(v1,{1,2,2,3,3,3,4,4,4,4,5,5,5,5,5});\n\t\tusing Rng = decltype(rng);\n\t\tusing CR = range_common_reference_t<Rng>;\n\t\tauto proj = [](CR r) { return r; };\n\t\tauto pred = [](CR r1, CR r2) { return r1 < r2; };\n\t\tsort(rng, pred, proj);\n\t\tCHECK_EQUAL(v0,{1,2,2,3,3,3,4,4,4,4,5,5,5,5,5});\n\t\tCHECK_EQUAL(v1,{5,5,5,4,5,5,3,4,4,4,1,2,2,3,3});\n\n\t\t// Check that this compiles, too:\n\t\tsort(rng);\n\t}\n#endif\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/sort_heap.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/sort_heap.hpp>\n#include <memory>\n#include <random>\n#include <algorithm>\n#include <functional>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace stl2 = __stl2;\n\nnamespace { std::mt19937 gen; }\n\nvoid test_1(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tCHECK(stl2::sort_heap(ia, ia+N) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N));\n\tdelete [] ia;\n}\n\nvoid test_2(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tCHECK(stl2::sort_heap(ia, sentinel<int*>(ia+N)) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N));\n\tdelete [] ia;\n}\n\nvoid test_3(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tCHECK(stl2::sort_heap(::as_lvalue(stl2::subrange(ia, ia+N))) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N));\n\tdelete [] ia;\n}\n\nvoid test_4(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N);\n\tCHECK(stl2::sort_heap(::as_lvalue(stl2::subrange(ia, sentinel<int*>(ia+N)))) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N));\n\tdelete [] ia;\n}\n\nvoid test_5(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tCHECK(stl2::sort_heap(ia, ia+N, std::greater<int>()) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N, std::greater<int>()));\n\tdelete [] ia;\n}\n\nvoid test_6(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tCHECK(stl2::sort_heap(ia, sentinel<int*>(ia+N), std::greater<int>()) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N, std::greater<int>()));\n\tdelete [] ia;\n}\n\nvoid test_7(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tCHECK(stl2::sort_heap(::as_lvalue(stl2::subrange(ia, ia+N)), std::greater<int>()) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N, std::greater<int>()));\n\tdelete [] ia;\n}\n\nvoid test_8(int N)\n{\n\tint* ia = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i] = i;\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tCHECK(stl2::sort_heap(::as_lvalue(stl2::subrange(ia, sentinel<int*>(ia+N))), std::greater<int>()) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N, std::greater<int>()));\n\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, std::greater<int>());\n\tCHECK(stl2::sort_heap(stl2::subrange(ia, sentinel<int*>(ia+N)), std::greater<int>()) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N, std::greater<int>()));\n\n\tdelete [] ia;\n}\n\nstruct indirect_less\n{\n\ttemplate<class P>\n\tbool operator()(const P& x, const P& y) const\n\t\t{return *x < *y;}\n};\n\nvoid test_9(int N)\n{\n\tstd::unique_ptr<int>* ia = new std::unique_ptr<int> [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tia[i].reset(new int(i));\n\tstd::shuffle(ia, ia+N, gen);\n\tstd::make_heap(ia, ia+N, indirect_less());\n\tCHECK(stl2::sort_heap(ia, ia+N, indirect_less()) == ia+N);\n\tCHECK(std::is_sorted(ia, ia+N, indirect_less()));\n\tdelete [] ia;\n}\n\nstruct S\n{\n\tint i;\n};\n\nvoid test_10(int N)\n{\n\tS* ia = new S [N];\n\tint* ib = new int [N];\n\tfor (int i = 0; i < N; ++i)\n\t\tib[i] = i;\n\tstd::shuffle(ib, ib+N, gen);\n\tstd::make_heap(ib, ib+N);\n\tstd::transform(ib, ib+N, ia, [](int i){return S{i};});\n\tCHECK(stl2::sort_heap(ia, ia+N, std::less<int>(), &S::i) == ia+N);\n\tstd::transform(ia, ia+N, ib, std::mem_fn(&S::i));\n\tCHECK(std::is_sorted(ib, ib+N));\n\tdelete [] ia;\n\tdelete [] ib;\n}\n\nvoid test(int N)\n{\n\ttest_1(N);\n\ttest_2(N);\n\ttest_3(N);\n\ttest_4(N);\n\ttest_5(N);\n\ttest_6(N);\n\ttest_7(N);\n\ttest_8(N);\n}\n\nint main()\n{\n\ttest(0);\n\ttest(1);\n\ttest(2);\n\ttest(3);\n\ttest(10);\n\ttest(1000);\n\ttest_9(1000);\n\ttest_10(1000);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/algorithm/stable_partition.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/stable_partition.hpp>\n#include <memory>\n#include <utility>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct is_odd {\n\tbool operator()(const int& i) const {\n\t\treturn i & 1;\n\t}\n};\n\nstruct odd_first {\n\tbool operator()(const std::pair<int,int>& p) const {\n\t\treturn p.first & 1;\n\t}\n};\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_iter() {\n\tusing P = std::pair<int, int>;\n\t{\t// check mixed\n\t\tP ap[] = { {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}, {3, 1}, {3, 2}, {4, 1}, {4, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap + 4);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{0, 1});\n\t\tCHECK(ap[5] == P{0, 2});\n\t\tCHECK(ap[6] == P{2, 1});\n\t\tCHECK(ap[7] == P{2, 2});\n\t\tCHECK(ap[8] == P{4, 1});\n\t\tCHECK(ap[9] == P{4, 2});\n\t}\n\t{\n\t\tP ap[] = { {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}, {3, 1}, {3, 2}, {4, 1}, {4, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap + 4);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{0, 1});\n\t\tCHECK(ap[5] == P{0, 2});\n\t\tCHECK(ap[6] == P{2, 1});\n\t\tCHECK(ap[7] == P{2, 2});\n\t\tCHECK(ap[8] == P{4, 1});\n\t\tCHECK(ap[9] == P{4, 2});\n\t\t// check empty\n\t\tr = ranges::stable_partition(Iter(ap), Sent(ap), odd_first());\n\t\tCHECK(base(r) == ap);\n\t\t// check one true\n\t\tr = ranges::stable_partition(Iter(ap), Sent(ap+1), odd_first());\n\t\tCHECK(base(r) == ap+1);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\t// check one false\n\t\tr = ranges::stable_partition(Iter(ap+4), Sent(ap+5), odd_first());\n\t\tCHECK(base(r) == ap+4);\n\t\tCHECK(ap[4] == P{0, 1});\n\t}\n\t{\t// check all false\n\t\tP ap[] = { {0, 1}, {0, 2}, {2, 1}, {2, 2}, {4, 1}, {4, 2}, {6, 1}, {6, 2}, {8, 1}, {8, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap);\n\t\tCHECK(ap[0] == P{0, 1});\n\t\tCHECK(ap[1] == P{0, 2});\n\t\tCHECK(ap[2] == P{2, 1});\n\t\tCHECK(ap[3] == P{2, 2});\n\t\tCHECK(ap[4] == P{4, 1});\n\t\tCHECK(ap[5] == P{4, 2});\n\t\tCHECK(ap[6] == P{6, 1});\n\t\tCHECK(ap[7] == P{6, 2});\n\t\tCHECK(ap[8] == P{8, 1});\n\t\tCHECK(ap[9] == P{8, 2});\n\t}\n\t{\t// check all true\n\t\tP ap[] = { {1, 1}, {1, 2}, {3, 1}, {3, 2}, {5, 1}, {5, 2}, {7, 1}, {7, 2}, {9, 1}, {9, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap + size);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{5, 1});\n\t\tCHECK(ap[5] == P{5, 2});\n\t\tCHECK(ap[6] == P{7, 1});\n\t\tCHECK(ap[7] == P{7, 2});\n\t\tCHECK(ap[8] == P{9, 1});\n\t\tCHECK(ap[9] == P{9, 2});\n\t}\n\t{\t// check all false but first true\n\t\tP ap[] = { {1, 1}, {0, 2}, {2, 1}, {2, 2}, {4, 1}, {4, 2}, {6, 1}, {6, 2}, {8, 1}, {8, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap + 1);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{0, 2});\n\t\tCHECK(ap[2] == P{2, 1});\n\t\tCHECK(ap[3] == P{2, 2});\n\t\tCHECK(ap[4] == P{4, 1});\n\t\tCHECK(ap[5] == P{4, 2});\n\t\tCHECK(ap[6] == P{6, 1});\n\t\tCHECK(ap[7] == P{6, 2});\n\t\tCHECK(ap[8] == P{8, 1});\n\t\tCHECK(ap[9] == P{8, 2});\n\t}\n\t{\t// check all false but last true\n\t\tP ap[] = { {0, 1}, {0, 2}, {2, 1}, {2, 2}, {4, 1}, {4, 2}, {6, 1}, {6, 2}, {8, 1}, {1, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap + 1);\n\t\tCHECK(ap[0] == P{1, 2});\n\t\tCHECK(ap[1] == P{0, 1});\n\t\tCHECK(ap[2] == P{0, 2});\n\t\tCHECK(ap[3] == P{2, 1});\n\t\tCHECK(ap[4] == P{2, 2});\n\t\tCHECK(ap[5] == P{4, 1});\n\t\tCHECK(ap[6] == P{4, 2});\n\t\tCHECK(ap[7] == P{6, 1});\n\t\tCHECK(ap[8] == P{6, 2});\n\t\tCHECK(ap[9] == P{8, 1});\n\t}\n\t{\t// check all true but first false\n\t\tP ap[] = { {0, 1}, {1, 2}, {3, 1}, {3, 2}, {5, 1}, {5, 2}, {7, 1}, {7, 2}, {9, 1}, {9, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap + size-1);\n\t\tCHECK(ap[0] == P{1, 2});\n\t\tCHECK(ap[1] == P{3, 1});\n\t\tCHECK(ap[2] == P{3, 2});\n\t\tCHECK(ap[3] == P{5, 1});\n\t\tCHECK(ap[4] == P{5, 2});\n\t\tCHECK(ap[5] == P{7, 1});\n\t\tCHECK(ap[6] == P{7, 2});\n\t\tCHECK(ap[7] == P{9, 1});\n\t\tCHECK(ap[8] == P{9, 2});\n\t\tCHECK(ap[9] == P{0, 1});\n\t}\n\t{\t// check all true but last false\n\t\tP ap[] = { {1, 1}, {1, 2}, {3, 1}, {3, 2}, {5, 1}, {5, 2}, {7, 1}, {7, 2}, {9, 1}, {0, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(Iter(ap), Sent(ap+size), odd_first());\n\t\tCHECK(base(r) == ap + size-1);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{5, 1});\n\t\tCHECK(ap[5] == P{5, 2});\n\t\tCHECK(ap[6] == P{7, 1});\n\t\tCHECK(ap[7] == P{7, 2});\n\t\tCHECK(ap[8] == P{9, 1});\n\t\tCHECK(ap[9] == P{0, 2});\n\t}\n}\n\ntemplate<class Iter, class Sent = Iter>\nvoid test_range() {\n\tusing P = std::pair<int, int>;\n\t{\t// check mixed\n\t\tP ap[] = { {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}, {3, 1}, {3, 2}, {4, 1}, {4, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap + 4);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{0, 1});\n\t\tCHECK(ap[5] == P{0, 2});\n\t\tCHECK(ap[6] == P{2, 1});\n\t\tCHECK(ap[7] == P{2, 2});\n\t\tCHECK(ap[8] == P{4, 1});\n\t\tCHECK(ap[9] == P{4, 2});\n\t}\n\t{\n\t\tP ap[] = { {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}, {3, 1}, {3, 2}, {4, 1}, {4, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap + 4);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{0, 1});\n\t\tCHECK(ap[5] == P{0, 2});\n\t\tCHECK(ap[6] == P{2, 1});\n\t\tCHECK(ap[7] == P{2, 2});\n\t\tCHECK(ap[8] == P{4, 1});\n\t\tCHECK(ap[9] == P{4, 2});\n\t\t// check empty\n\t\tr = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap))), odd_first());\n\t\tCHECK(base(r) == ap);\n\t\t// check one true\n\t\tr = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+1))), odd_first());\n\t\tCHECK(base(r) == ap+1);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\t// check one false\n\t\tr = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap+4), Sent(ap+5))), odd_first());\n\t\tCHECK(base(r) == ap+4);\n\t\tCHECK(ap[4] == P{0, 1});\n\t}\n\t{\t// check all false\n\t\tP ap[] = { {0, 1}, {0, 2}, {2, 1}, {2, 2}, {4, 1}, {4, 2}, {6, 1}, {6, 2}, {8, 1}, {8, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap);\n\t\tCHECK(ap[0] == P{0, 1});\n\t\tCHECK(ap[1] == P{0, 2});\n\t\tCHECK(ap[2] == P{2, 1});\n\t\tCHECK(ap[3] == P{2, 2});\n\t\tCHECK(ap[4] == P{4, 1});\n\t\tCHECK(ap[5] == P{4, 2});\n\t\tCHECK(ap[6] == P{6, 1});\n\t\tCHECK(ap[7] == P{6, 2});\n\t\tCHECK(ap[8] == P{8, 1});\n\t\tCHECK(ap[9] == P{8, 2});\n\t}\n\t{\t// check all true\n\t\tP ap[] = { {1, 1}, {1, 2}, {3, 1}, {3, 2}, {5, 1}, {5, 2}, {7, 1}, {7, 2}, {9, 1}, {9, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap + size);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{5, 1});\n\t\tCHECK(ap[5] == P{5, 2});\n\t\tCHECK(ap[6] == P{7, 1});\n\t\tCHECK(ap[7] == P{7, 2});\n\t\tCHECK(ap[8] == P{9, 1});\n\t\tCHECK(ap[9] == P{9, 2});\n\t}\n\t{\t// check all false but first true\n\t\tP ap[] = { {1, 1}, {0, 2}, {2, 1}, {2, 2}, {4, 1}, {4, 2}, {6, 1}, {6, 2}, {8, 1}, {8, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap + 1);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{0, 2});\n\t\tCHECK(ap[2] == P{2, 1});\n\t\tCHECK(ap[3] == P{2, 2});\n\t\tCHECK(ap[4] == P{4, 1});\n\t\tCHECK(ap[5] == P{4, 2});\n\t\tCHECK(ap[6] == P{6, 1});\n\t\tCHECK(ap[7] == P{6, 2});\n\t\tCHECK(ap[8] == P{8, 1});\n\t\tCHECK(ap[9] == P{8, 2});\n\t}\n\t{\t// check all false but last true\n\t\tP ap[] = { {0, 1}, {0, 2}, {2, 1}, {2, 2}, {4, 1}, {4, 2}, {6, 1}, {6, 2}, {8, 1}, {1, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap + 1);\n\t\tCHECK(ap[0] == P{1, 2});\n\t\tCHECK(ap[1] == P{0, 1});\n\t\tCHECK(ap[2] == P{0, 2});\n\t\tCHECK(ap[3] == P{2, 1});\n\t\tCHECK(ap[4] == P{2, 2});\n\t\tCHECK(ap[5] == P{4, 1});\n\t\tCHECK(ap[6] == P{4, 2});\n\t\tCHECK(ap[7] == P{6, 1});\n\t\tCHECK(ap[8] == P{6, 2});\n\t\tCHECK(ap[9] == P{8, 1});\n\t}\n\t{\t// check all true but first false\n\t\tP ap[] = { {0, 1}, {1, 2}, {3, 1}, {3, 2}, {5, 1}, {5, 2}, {7, 1}, {7, 2}, {9, 1}, {9, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap + size-1);\n\t\tCHECK(ap[0] == P{1, 2});\n\t\tCHECK(ap[1] == P{3, 1});\n\t\tCHECK(ap[2] == P{3, 2});\n\t\tCHECK(ap[3] == P{5, 1});\n\t\tCHECK(ap[4] == P{5, 2});\n\t\tCHECK(ap[5] == P{7, 1});\n\t\tCHECK(ap[6] == P{7, 2});\n\t\tCHECK(ap[7] == P{9, 1});\n\t\tCHECK(ap[8] == P{9, 2});\n\t\tCHECK(ap[9] == P{0, 1});\n\t}\n\t{\t// check all true but last false\n\t\tP ap[] = { {1, 1}, {1, 2}, {3, 1}, {3, 2}, {5, 1}, {5, 2}, {7, 1}, {7, 2}, {9, 1}, {0, 2} };\n\t\tstd::size_t size = ranges::size(ap);\n\t\tIter r = ranges::stable_partition(::as_lvalue(ranges::subrange(Iter(ap), Sent(ap+size))), odd_first());\n\t\tCHECK(base(r) == ap + size-1);\n\t\tCHECK(ap[0] == P{1, 1});\n\t\tCHECK(ap[1] == P{1, 2});\n\t\tCHECK(ap[2] == P{3, 1});\n\t\tCHECK(ap[3] == P{3, 2});\n\t\tCHECK(ap[4] == P{5, 1});\n\t\tCHECK(ap[5] == P{5, 2});\n\t\tCHECK(ap[6] == P{7, 1});\n\t\tCHECK(ap[7] == P{7, 2});\n\t\tCHECK(ap[8] == P{9, 1});\n\t\tCHECK(ap[9] == P{0, 2});\n\t}\n}\n\nstruct move_only {\n\tstatic int count;\n\tint i;\n\tmove_only() = delete;\n\tmove_only(int j) : i(j) { ++count; }\n\tmove_only(move_only &&that) : i(that.i) {  ++count; }\n\tmove_only(move_only const &) = delete;\n\t~move_only() { --count; }\n\tmove_only &operator=(move_only &&) = default;\n\tmove_only &operator=(move_only const &) = delete;\n};\n\nint move_only::count = 0;\n\ntemplate<class Iter>\nvoid test_move_only() {\n\tconst unsigned size = 5;\n\tmove_only array[size] = { 1, 2, 3, 4, 5 };\n\tIter r = ranges::stable_partition(Iter(array), Iter(array+size), is_odd{}, &move_only::i);\n\tCHECK(base(r) == array + 3);\n\tCHECK(array[0].i == 1);\n\tCHECK(array[1].i == 3);\n\tCHECK(array[2].i == 5);\n\tCHECK(array[3].i == 2);\n\tCHECK(array[4].i == 4);\n}\n\nstruct S {\n\tstd::pair<int,int> p;\n};\n\nint main() {\n\ttest_iter<forward_iterator<std::pair<int,int>*> >();\n\ttest_iter<bidirectional_iterator<std::pair<int,int>*> >();\n\ttest_iter<random_access_iterator<std::pair<int,int>*> >();\n\ttest_iter<std::pair<int,int>*>();\n\ttest_iter<forward_iterator<std::pair<int,int>*>, sentinel<std::pair<int,int>*> >();\n\ttest_iter<bidirectional_iterator<std::pair<int,int>*>, sentinel<std::pair<int,int>*> >();\n\ttest_iter<random_access_iterator<std::pair<int,int>*>, sentinel<std::pair<int,int>*> >();\n\n\ttest_range<forward_iterator<std::pair<int,int>*> >();\n\ttest_range<bidirectional_iterator<std::pair<int,int>*> >();\n\ttest_range<random_access_iterator<std::pair<int,int>*> >();\n\ttest_range<std::pair<int,int>*>();\n\ttest_range<forward_iterator<std::pair<int,int>*>, sentinel<std::pair<int,int>*> >();\n\ttest_range<bidirectional_iterator<std::pair<int,int>*>, sentinel<std::pair<int,int>*> >();\n\ttest_range<random_access_iterator<std::pair<int,int>*>, sentinel<std::pair<int,int>*> >();\n\n\tCHECK(move_only::count == 0);\n\ttest_move_only<forward_iterator<move_only*> >();\n\ttest_move_only<bidirectional_iterator<move_only*> >();\n\tCHECK(move_only::count == 0);\n\n\t// Test projections\n\tusing P = std::pair<int, int>;\n\t{\t// check mixed\n\t\tS ap[] = { {{0, 1}}, {{0, 2}}, {{1, 1}}, {{1, 2}}, {{2, 1}}, {{2, 2}}, {{3, 1}}, {{3, 2}}, {{4, 1}}, {{4, 2}} };\n\t\tS* r = ranges::stable_partition(ap, odd_first(), &S::p);\n\t\tCHECK(r == ap + 4);\n\t\tCHECK(ap[0].p == P{1, 1});\n\t\tCHECK(ap[1].p == P{1, 2});\n\t\tCHECK(ap[2].p == P{3, 1});\n\t\tCHECK(ap[3].p == P{3, 2});\n\t\tCHECK(ap[4].p == P{0, 1});\n\t\tCHECK(ap[5].p == P{0, 2});\n\t\tCHECK(ap[6].p == P{2, 1});\n\t\tCHECK(ap[7].p == P{2, 2});\n\t\tCHECK(ap[8].p == P{4, 1});\n\t\tCHECK(ap[9].p == P{4, 2});\n\t}\n\n\t// Test rvalue ranges\n\tusing P = std::pair<int, int>;\n\t{\t// check mixed\n\t\tS ap[] = { {{0, 1}}, {{0, 2}}, {{1, 1}}, {{1, 2}}, {{2, 1}}, {{2, 2}}, {{3, 1}}, {{3, 2}}, {{4, 1}}, {{4, 2}} };\n\t\tauto r = ranges::stable_partition(std::move(ap), odd_first(), &S::p);\n\t\tstatic_assert(ranges::same_as<decltype(r), ranges::dangling>);\n\t\tCHECK(ap[0].p == P{1, 1});\n\t\tCHECK(ap[1].p == P{1, 2});\n\t\tCHECK(ap[2].p == P{3, 1});\n\t\tCHECK(ap[3].p == P{3, 2});\n\t\tCHECK(ap[4].p == P{0, 1});\n\t\tCHECK(ap[5].p == P{0, 2});\n\t\tCHECK(ap[6].p == P{2, 1});\n\t\tCHECK(ap[7].p == P{2, 2});\n\t\tCHECK(ap[8].p == P{4, 1});\n\t\tCHECK(ap[9].p == P{4, 2});\n\t}\n\n\t{\n\t\tint some_ints[] = {1, 0};\n\t\tauto first = some_ints + 0, last = some_ints + 2;\n\t\tauto even = [](int i) { return i % 2 == 0; };\n\t\tranges::stable_partition(first, last, even);\n\t\tCHECK(std::is_partitioned(first, last, even));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/stable_sort.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/stable_sort.hpp>\n#include <cassert>\n#include <memory>\n#include <random>\n#include <vector>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace { std::mt19937 gen; }\n\nstruct indirect_less {\n\ttemplate<class P>\n\tbool operator()(const P& x, const P& y) const\n\t\t{return *x < *y;}\n};\n\ntemplate<class RI>\nvoid test_sort_helper(RI f, RI l) {\n\tusing value_type = ranges::iter_value_t<RI>;\n\tauto stable_sort = make_testable_1<false>([](auto&&... args) {\n\t\treturn ranges::stable_sort(std::forward<decltype(args)>(args)...);\n\t});\n\tif (f != l)\n\t{\n\t\tlong len = l - f;\n\t\tvalue_type* save(new value_type[len]);\n\t\tdo\n\t\t{\n\t\t\tstd::copy(f, l, save);\n\t\t\tstable_sort(save, save+len).check([&](int *res)\n\t\t\t{\n\t\t\t\tCHECK(res == save+len);\n\t\t\t\tCHECK(std::is_sorted(save, save+len));\n\t\t\t\tstd::copy(f, l, save);\n\t\t\t});\n\t\t\tstable_sort(save, save+len, std::greater<int>{}).check([&](int *res)\n\t\t\t{\n\t\t\t\tCHECK(res == save+len);\n\t\t\t\tCHECK(std::is_sorted(save, save+len, std::greater<int>{}));\n\t\t\t\tstd::copy(f, l, save);\n\t\t\t});\n\t\t} while (std::next_permutation(f, l));\n\t\tdelete [] save;\n\t}\n}\n\ntemplate<class RI>\nvoid test_sort_driver_driver(RI f, RI l, int start, RI real_last) {\n\tfor (RI i = l; i > f + start;)\n\t{\n\t\t*--i = start;\n\t\tif (f == i)\n\t\t{\n\t\t\ttest_sort_helper(f, real_last);\n\t\t}\n\t\tif (start > 0)\n\t\t\ttest_sort_driver_driver(f, i, start-1, real_last);\n\t}\n}\n\ntemplate<class RI>\nvoid test_sort_driver(RI f, RI l, int start) {\n\ttest_sort_driver_driver(f, l, start, l);\n}\n\ntemplate<int sa>\nvoid test_sort_() {\n\tint ia[sa];\n\tfor (int i = 0; i < sa; ++i)\n\t{\n\t\ttest_sort_driver(ia, ia+sa, i);\n\t}\n}\n\nvoid test_larger_sorts(int N, int M) {\n\tassert(N > 0);\n\tassert(M > 0);\n\t// create array length N filled with M different numbers\n\tint* array = new int[N];\n\tint x = 0;\n\tfor (int i = 0; i < N; ++i)\n\t{\n\t\tarray[i] = x;\n\t\tif (++x == M)\n\t\t\tx = 0;\n\t}\n\n\t// test saw tooth pattern\n\tCHECK(ranges::stable_sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test random pattern\n\tstd::shuffle(array, array+N, gen);\n\tCHECK(ranges::stable_sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test sorted pattern\n\tCHECK(ranges::stable_sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test reverse sorted pattern\n\tstd::reverse(array, array+N);\n\tCHECK(ranges::stable_sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test swap ranges 2 pattern\n\tstd::swap_ranges(array, array+N/2, array+N/2);\n\tCHECK(ranges::stable_sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\t// test reverse swap ranges 2 pattern\n\tstd::reverse(array, array+N);\n\tstd::swap_ranges(array, array+N/2, array+N/2);\n\tCHECK(ranges::stable_sort(array, array+N) == array+N);\n\tCHECK(std::is_sorted(array, array+N));\n\tdelete [] array;\n}\n\nvoid test_larger_sorts(unsigned N) {\n\ttest_larger_sorts(N, 1);\n\ttest_larger_sorts(N, 2);\n\ttest_larger_sorts(N, 3);\n\ttest_larger_sorts(N, N/2-1);\n\ttest_larger_sorts(N, N/2);\n\ttest_larger_sorts(N, N/2+1);\n\ttest_larger_sorts(N, N-2);\n\ttest_larger_sorts(N, N-1);\n\ttest_larger_sorts(N, N);\n}\n\nstruct S {\n\tint i, j;\n};\n\nint main() {\n\t// test null range\n\tint d = 0;\n\tint * r = ranges::stable_sort(&d, &d);\n\tCHECK(r == &d);\n\t// exhaustively test all possibilities up to length 8\n\ttest_sort_<1>();\n\ttest_sort_<2>();\n\ttest_sort_<3>();\n\ttest_sort_<4>();\n\ttest_sort_<5>();\n\ttest_sort_<6>();\n\ttest_sort_<7>();\n\ttest_sort_<8>();\n\n\ttest_larger_sorts(15);\n\ttest_larger_sorts(16);\n\ttest_larger_sorts(17);\n\ttest_larger_sorts(256);\n\ttest_larger_sorts(257);\n\ttest_larger_sorts(499);\n\ttest_larger_sorts(500);\n\ttest_larger_sorts(997);\n\ttest_larger_sorts(1000);\n\ttest_larger_sorts(1009);\n\n\t// Check move-only types\n\t{\n\t\tstd::vector<std::unique_ptr<int> > v(1000);\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t\tv[i].reset(new int(v.size() - i - 1));\n\t\tranges::stable_sort(v, indirect_less());\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t\tCHECK(*v[i] == i);\n\t}\n\n\t// Check projections\n\t{\n\t\tstd::vector<S> v(1000, S{});\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tv[i].i = v.size() - i - 1;\n\t\t\tv[i].j = i;\n\t\t}\n\t\tranges::stable_sort(v, std::less<int>{}, &S::i);\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tCHECK(v[i].i == i);\n\t\t\tCHECK((std::size_t)v[i].j == v.size() - i - 1);\n\t\t}\n\t}\n\n\t// Check rvalue range\n\t{\n\t\tstd::vector<S> v(1000, S{});\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tv[i].i = v.size() - i - 1;\n\t\t\tv[i].j = i;\n\t\t}\n\t\tauto r = ranges::stable_sort(std::move(v), std::less<int>{}, &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(r), ranges::dangling>);\n\t\tfor(int i = 0; (std::size_t)i < v.size(); ++i)\n\t\t{\n\t\t\tCHECK(v[i].i == i);\n\t\t\tCHECK((std::size_t)v[i].j == v.size() - i - 1);\n\t\t}\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/swap_ranges.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#include <stl2/detail/algorithm/swap_ranges.hpp>\n#include <memory>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class Iter1, class Iter2>\nvoid test_iter_3() {\n\tint i[3] = {1, 2, 3};\n\tint j[3] = {4, 5, 6};\n\tranges::swap_ranges_result<Iter1, Iter2> r =\n\t\tranges::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j), ranges::unreachable_sentinel);\n\tCHECK(base(r.in1) == i+3);\n\tCHECK(base(r.in2) == j+3);\n\tCHECK(i[0] == 4);\n\tCHECK(i[1] == 5);\n\tCHECK(i[2] == 6);\n\tCHECK(j[0] == 1);\n\tCHECK(j[1] == 2);\n\tCHECK(j[2] == 3);\n\n\tusing Sent1 = typename sentinel_type<Iter1>::type;\n\tr = ranges::swap_ranges(Iter1(j), Sent1(j+3), Iter2(i), ranges::unreachable_sentinel);\n\tCHECK(base(r.in1) == j+3);\n\tCHECK(base(r.in2) == i+3);\n\tCHECK(i[0] == 1);\n\tCHECK(i[1] == 2);\n\tCHECK(i[2] == 3);\n\tCHECK(j[0] == 4);\n\tCHECK(j[1] == 5);\n\tCHECK(j[2] == 6);\n}\n\ntemplate<class Iter1, class Iter2>\nvoid test_iter_4() {\n\tint i[3] = {1, 2, 3};\n\tint j[4] = {4, 5, 6, 7};\n\tranges::swap_ranges_result<Iter1, Iter2> r =\n\t\tranges::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j), Iter2(j+4));\n\tCHECK(base(r.in1) == i+3);\n\tCHECK(base(r.in2) == j+3);\n\tCHECK(i[0] == 4);\n\tCHECK(i[1] == 5);\n\tCHECK(i[2] == 6);\n\tCHECK(j[0] == 1);\n\tCHECK(j[1] == 2);\n\tCHECK(j[2] == 3);\n\tCHECK(j[3] == 7);\n\n\tusing Sent1 = typename sentinel_type<Iter1>::type;\n\tusing Sent2 = typename sentinel_type<Iter2>::type;\n\tr = ranges::swap_ranges(Iter1(j), Sent1(j+4), Iter2(i), Sent2(i+3));\n\tCHECK(base(r.in1) == j+3);\n\tCHECK(base(r.in2) == i+3);\n\tCHECK(i[0] == 1);\n\tCHECK(i[1] == 2);\n\tCHECK(i[2] == 3);\n\tCHECK(j[0] == 4);\n\tCHECK(j[1] == 5);\n\tCHECK(j[2] == 6);\n\tCHECK(j[3] == 7);\n}\n\ntemplate<class Iter1, class Iter2>\nvoid test_rng_4() {\n\tint i[3] = {1, 2, 3};\n\tint j[4] = {4, 5, 6, 7};\n\tranges::swap_ranges_result<Iter1, Iter2> r = ranges::swap_ranges(\n\t\tas_lvalue(ranges::subrange(Iter1(i), Iter1(i+3))),\n\t\tas_lvalue(ranges::subrange(Iter2(j), Iter2(j+4))));\n\tCHECK(base(r.in1) == i+3);\n\tCHECK(base(r.in2) == j+3);\n\tCHECK(i[0] == 4);\n\tCHECK(i[1] == 5);\n\tCHECK(i[2] == 6);\n\tCHECK(j[0] == 1);\n\tCHECK(j[1] == 2);\n\tCHECK(j[2] == 3);\n\tCHECK(j[3] == 7);\n\n\tusing Sent1 = typename sentinel_type<Iter1>::type;\n\tusing Sent2 = typename sentinel_type<Iter2>::type;\n\tr = ranges::swap_ranges(\n\t\tas_lvalue(ranges::subrange(Iter1(j), Sent1(j+4))),\n\t\tas_lvalue(ranges::subrange(Iter2(i), Sent2(i+3))));\n\tCHECK(base(r.in1) == j+3);\n\tCHECK(base(r.in2) == i+3);\n\tCHECK(i[0] == 1);\n\tCHECK(i[1] == 2);\n\tCHECK(i[2] == 3);\n\tCHECK(j[0] == 4);\n\tCHECK(j[1] == 5);\n\tCHECK(j[2] == 6);\n\tCHECK(j[3] == 7);\n\n\tauto r2 = ranges::swap_ranges(\n\t\tranges::subrange(Iter1(j), Sent1(j+4)),\n\t\tranges::subrange(Iter2(i), Sent2(i+3)));\n\tCHECK(base(r2.in1) == j+3);\n\tCHECK(base(r2.in2) == i+3);\n\tCHECK(i[0] == 4);\n\tCHECK(i[1] == 5);\n\tCHECK(i[2] == 6);\n\tCHECK(j[0] == 1);\n\tCHECK(j[1] == 2);\n\tCHECK(j[2] == 3);\n\tCHECK(j[3] == 7);\n}\n\ntemplate<class Iter1, class Iter2>\nvoid test_move_only() {\n\tstd::unique_ptr<int> i[3];\n\tfor (int k = 0; k < 3; ++k)\n\t\ti[k].reset(new int(k+1));\n\tstd::unique_ptr<int> j[3];\n\tfor (int k = 0; k < 3; ++k)\n\t\tj[k].reset(new int(k+4));\n\tranges::swap_ranges_result<Iter1, Iter2> r =\n\t\tranges::swap_ranges(Iter1(i), Iter1(i+3), Iter2(j), ranges::unreachable_sentinel);\n\tCHECK(base(r.in1) == i+3);\n\tCHECK(base(r.in2) == j+3);\n\tCHECK(*i[0] == 4);\n\tCHECK(*i[1] == 5);\n\tCHECK(*i[2] == 6);\n\tCHECK(*j[0] == 1);\n\tCHECK(*j[1] == 2);\n\tCHECK(*j[2] == 3);\n}\n\ntemplate<class Iter1, class Iter2>\nvoid test() {\n\ttest_iter_3<Iter1, Iter2>();\n\ttest_iter_4<Iter1, Iter2>();\n\ttest_rng_4<Iter1, Iter2>();\n}\n\nint main() {\n\ttest<forward_iterator<int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<int*>, int*>();\n\n\ttest<bidirectional_iterator<int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<int*>, int*>();\n\n\ttest<random_access_iterator<int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<int*>, int*>();\n\n\ttest<int*, forward_iterator<int*> >();\n\ttest<int*, bidirectional_iterator<int*> >();\n\ttest<int*, random_access_iterator<int*> >();\n\ttest<int*, int*>();\n\n\ttest_move_only<forward_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<forward_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<forward_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<forward_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest_move_only<bidirectional_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<bidirectional_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<bidirectional_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<bidirectional_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest_move_only<random_access_iterator<std::unique_ptr<int>*>, forward_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<random_access_iterator<std::unique_ptr<int>*>, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<random_access_iterator<std::unique_ptr<int>*>, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<random_access_iterator<std::unique_ptr<int>*>, std::unique_ptr<int>*>();\n\n\ttest_move_only<std::unique_ptr<int>*, forward_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<std::unique_ptr<int>*, bidirectional_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<std::unique_ptr<int>*, random_access_iterator<std::unique_ptr<int>*> >();\n\ttest_move_only<std::unique_ptr<int>*, std::unique_ptr<int>*>();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/transform.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/algorithm/transform.hpp>\n\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main() {\n\tint rgi[]{1,2,3,4,5};\n\tranges::transform(rgi, rgi+5, rgi, [](int i){ return i * 2; });\n\tCHECK_EQUAL(rgi, {2,4,6,8,10});\n\n\tranges::transform(rgi, rgi, [](int i){ return i / 2; });\n\tCHECK_EQUAL(rgi, {1,2,3,4,5});\n\n\t{\n\t\tauto sum = [](int x, int y) { return x + y; };\n\t\tint const source1[] = {0,1,2,3};\n\t\tint const source2[] = {4,5,6,7};\n\t\tint const control[] = {4,6,8,10};\n\n\t\t{\n\t\t\tint target[4]{};\n\t\t\tauto result = ranges::transform(ranges::begin(source1), ranges::end(source1),\n\t\t\t\tranges::begin(source2), ranges::end(source2), target, sum);\n\t\t\tCHECK(result.in1 == ranges::end(source1));\n\t\t\tCHECK(result.in2 == ranges::end(source2));\n\t\t\tCHECK(result.out == ranges::end(target));\n\t\t\tCHECK_EQUAL(target, control);\n\t\t}\n\n\t\t{\n\t\t\tint target[4]{};\n\t\t\tauto result = ranges::transform(source1, source2, target, sum);\n\t\t\tCHECK(result.in1 == ranges::end(source1));\n\t\t\tCHECK(result.in2 == ranges::end(source2));\n\t\t\tCHECK(result.out == ranges::end(target));\n\t\t\tCHECK_EQUAL(target, control);\n\t\t}\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/unique.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n// Implementation based on the code in libc++\n//   http://http://libcxx.llvm.org/\n\n#include <stl2/detail/algorithm/unique.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\n/// Calls the iterator interface of the algorithm\ntemplate<class Iter>\nstruct iter_call\n{\n\tusing begin_t = Iter;\n\tusing sentinel_t = typename sentinel_type<Iter>::type;\n\n\ttemplate<class B, class E, class... Args>\n\tauto operator()(B &&It, E &&e, Args &&... args) const\n\t{\n\t\treturn ranges::unique(begin_t{It}, sentinel_t{e}, std::forward<Args>(args)...);\n\t}\n};\n\n/// Calls the range interface of the algorithm\ntemplate<class Iter>\nstruct range_call\n{\n\tusing begin_t = Iter;\n\tusing sentinel_t = typename sentinel_type<Iter>::type;\n\n\ttemplate<class B, class E, class... Args>\n\tauto operator()(B &&It, E &&e, Args &&... args) const\n\t{\n\t\tauto rng = ranges::subrange(begin_t{It}, sentinel_t{e});\n\t\treturn ranges::unique(rng, std::forward<Args>(args)...);\n\t}\n};\n\ntemplate<class T> using identity_t = T;\n\ntemplate<class It, template<class> class FunT>\nvoid test()\n{\n\tusing Fun = FunT<It>;\n\n\t{\n\t\tint a[] = {0};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + sa));\n\t\tCHECK(a[0] == 0);\n\t}\n\t{\n\t\tint a[] = {0, 1};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + sa));\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 1);\n\t}\n\t{\n\t\tint a[] = {0, 0};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + 1));\n\t\tCHECK(a[0] == 0);\n\t}\n\t{\n\t\tint a[] = {0, 0, 1};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + 2));\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 1);\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 0};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + 3));\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 1);\n\t\tCHECK(a[2] == 0);\n\t}\n\t{\n\t\tint a[] = {0, 0, 1, 1};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + 2));\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 1);\n\t}\n\t{\n\t\tint a[] = {0, 1, 1};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + 2));\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 1);\n\t}\n\t{\n\t\tint a[] = {0, 1, 1, 1, 2, 2, 2};\n\t\tconst unsigned sa = sizeof(a) / sizeof(a[0]);\n\t\tauto r = Fun{}(a, a + sa);\n\t\tCHECK(r == It(a + 3));\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 1);\n\t\tCHECK(a[2] == 2);\n\t}\n}\n\nint main()\n{\n\ttest<forward_iterator<int*>, iter_call>();\n\ttest<bidirectional_iterator<int*>, iter_call>();\n\ttest<random_access_iterator<int*>, iter_call>();\n\ttest<int*, iter_call>();\n\n\ttest<forward_iterator<int*>, range_call>();\n\ttest<bidirectional_iterator<int*>, range_call>();\n\ttest<random_access_iterator<int*>, range_call>();\n\ttest<int*, range_call>();\n\n\t// Test rvalue range\n\t{\n\t\tint a[] = {0, 1, 1, 1, 2, 2, 2};\n\t\tauto r = ranges::unique(std::move(a));\n\t\tstatic_assert(ranges::same_as<decltype(r), ranges::dangling>);\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 1);\n\t\tCHECK(a[2] == 2);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/unique_copy.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n// Implementation based on the code in libc++\n//   http://http://libcxx.llvm.org/\n\n#include <stl2/detail/algorithm/unique_copy.hpp>\n#include <cstring>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct count_equal {\n\tstatic unsigned count;\n\n\ttemplate<class T>\n\tbool operator()(const T& x, const T& y) {\n\t\t++count;\n\t\treturn x == y;\n\t}\n};\n\nunsigned count_equal::count = 0;\n\ntemplate<class InIter, class OutIter, typename Sent = InIter>\nvoid test_iter() {\n\tconst int ia[] = {0};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ja[sa] = {-1};\n\tcount_equal::count = 0;\n\tranges::unique_copy_result<InIter, OutIter> r =\n\t\tranges::unique_copy(InIter(ia), Sent(ia+sa), OutIter(ja), count_equal());\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ja + sa);\n\tCHECK(ja[0] == 0);\n\tCHECK(count_equal::count == sa - 1);\n\n\tconst int ib[] = {0, 1};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tint jb[sb] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(InIter(ib), Sent(ib+sb), OutIter(jb), count_equal());\n\tCHECK(base(r.in) == ib + sb);\n\tCHECK(base(r.out) == jb + sb);\n\tCHECK(jb[0] == 0);\n\tCHECK(jb[1] == 1);\n\tCHECK(count_equal::count == sb - 1);\n\n\tconst int ic[] = {0, 0};\n\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\tint jc[sc] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(InIter(ic), Sent(ic+sc), OutIter(jc), count_equal());\n\tCHECK(base(r.in) == ic + sc);\n\tCHECK(base(r.out) == jc + 1);\n\tCHECK(jc[0] == 0);\n\tCHECK(count_equal::count == sc - 1);\n\n\tconst int id[] = {0, 0, 1};\n\tconst unsigned sd = sizeof(id)/sizeof(id[0]);\n\tint jd[sd] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(InIter(id), Sent(id+sd), OutIter(jd), count_equal());\n\tCHECK(base(r.in) == id + sd);\n\tCHECK(base(r.out) == jd + 2);\n\tCHECK(jd[0] == 0);\n\tCHECK(jd[1] == 1);\n\tCHECK(count_equal::count == sd - 1);\n\n\tconst int ie[] = {0, 0, 1, 0};\n\tconst unsigned se = sizeof(ie)/sizeof(ie[0]);\n\tint je[se] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(InIter(ie), Sent(ie+se), OutIter(je), count_equal());\n\tCHECK(base(r.in) == ie + se);\n\tCHECK(base(r.out) == je + 3);\n\tCHECK(je[0] == 0);\n\tCHECK(je[1] == 1);\n\tCHECK(je[2] == 0);\n\tCHECK(count_equal::count == se - 1);\n\n\tconst int ig[] = {0, 0, 1, 1};\n\tconst unsigned sg = sizeof(ig)/sizeof(ig[0]);\n\tint jg[sg] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(InIter(ig), Sent(ig+sg), OutIter(jg), count_equal());\n\tCHECK(base(r.in) == ig + sg);\n\tCHECK(base(r.out) == jg + 2);\n\tCHECK(jg[0] == 0);\n\tCHECK(jg[1] == 1);\n\tCHECK(count_equal::count == sg - 1);\n\n\tconst int ih[] = {0, 1, 1};\n\tconst unsigned sh = sizeof(ih)/sizeof(ih[0]);\n\tint jh[sh] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(InIter(ih), Sent(ih+sh), OutIter(jh), count_equal());\n\tCHECK(base(r.in) == ih + sh);\n\tCHECK(base(r.out) == jh + 2);\n\tCHECK(jh[0] == 0);\n\tCHECK(jh[1] == 1);\n\tCHECK(count_equal::count == sh - 1);\n\n\tconst int ii[] = {0, 1, 1, 1, 2, 2, 2};\n\tconst unsigned si = sizeof(ii)/sizeof(ii[0]);\n\tint ji[si] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(InIter(ii), Sent(ii+si), OutIter(ji), count_equal());\n\tCHECK(base(r.in) == ii + si);\n\tCHECK(base(r.out) == ji + 3);\n\tCHECK(ji[0] == 0);\n\tCHECK(ji[1] == 1);\n\tCHECK(ji[2] == 2);\n\tCHECK(count_equal::count == si - 1);\n}\n\ntemplate<class InIter, class OutIter, typename Sent = InIter>\nvoid\ntest_range()\n{\n\tconst int ia[] = {0};\n\tconst unsigned sa = sizeof(ia)/sizeof(ia[0]);\n\tint ja[sa] = {-1};\n\tcount_equal::count = 0;\n\tranges::unique_copy_result<InIter, OutIter> r =\n\t\tranges::unique_copy(::as_lvalue(ranges::subrange(InIter(ia), Sent(ia+sa))), OutIter(ja), count_equal());\n\tCHECK(base(r.in) == ia + sa);\n\tCHECK(base(r.out) == ja + sa);\n\tCHECK(ja[0] == 0);\n\tCHECK(count_equal::count == sa - 1);\n\n\tconst int ib[] = {0, 1};\n\tconst unsigned sb = sizeof(ib)/sizeof(ib[0]);\n\tint jb[sb] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(::as_lvalue(ranges::subrange(InIter(ib), Sent(ib+sb))), OutIter(jb), count_equal());\n\tCHECK(base(r.in) == ib + sb);\n\tCHECK(base(r.out) == jb + sb);\n\tCHECK(jb[0] == 0);\n\tCHECK(jb[1] == 1);\n\tCHECK(count_equal::count == sb - 1);\n\n\tconst int ic[] = {0, 0};\n\tconst unsigned sc = sizeof(ic)/sizeof(ic[0]);\n\tint jc[sc] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(::as_lvalue(ranges::subrange(InIter(ic), Sent(ic+sc))), OutIter(jc), count_equal());\n\tCHECK(base(r.in) == ic + sc);\n\tCHECK(base(r.out) == jc + 1);\n\tCHECK(jc[0] == 0);\n\tCHECK(count_equal::count == sc - 1);\n\n\tconst int id[] = {0, 0, 1};\n\tconst unsigned sd = sizeof(id)/sizeof(id[0]);\n\tint jd[sd] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(::as_lvalue(ranges::subrange(InIter(id), Sent(id+sd))), OutIter(jd), count_equal());\n\tCHECK(base(r.in) == id + sd);\n\tCHECK(base(r.out) == jd + 2);\n\tCHECK(jd[0] == 0);\n\tCHECK(jd[1] == 1);\n\tCHECK(count_equal::count == sd - 1);\n\n\tconst int ie[] = {0, 0, 1, 0};\n\tconst unsigned se = sizeof(ie)/sizeof(ie[0]);\n\tint je[se] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(::as_lvalue(ranges::subrange(InIter(ie), Sent(ie+se))), OutIter(je), count_equal());\n\tCHECK(base(r.in) == ie + se);\n\tCHECK(base(r.out) == je + 3);\n\tCHECK(je[0] == 0);\n\tCHECK(je[1] == 1);\n\tCHECK(je[2] == 0);\n\tCHECK(count_equal::count == se - 1);\n\n\tconst int ig[] = {0, 0, 1, 1};\n\tconst unsigned sg = sizeof(ig)/sizeof(ig[0]);\n\tint jg[sg] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(::as_lvalue(ranges::subrange(InIter(ig), Sent(ig+sg))), OutIter(jg), count_equal());\n\tCHECK(base(r.in) == ig + sg);\n\tCHECK(base(r.out) == jg + 2);\n\tCHECK(jg[0] == 0);\n\tCHECK(jg[1] == 1);\n\tCHECK(count_equal::count == sg - 1);\n\n\tconst int ih[] = {0, 1, 1};\n\tconst unsigned sh = sizeof(ih)/sizeof(ih[0]);\n\tint jh[sh] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(::as_lvalue(ranges::subrange(InIter(ih), Sent(ih+sh))), OutIter(jh), count_equal());\n\tCHECK(base(r.in) == ih + sh);\n\tCHECK(base(r.out) == jh + 2);\n\tCHECK(jh[0] == 0);\n\tCHECK(jh[1] == 1);\n\tCHECK(count_equal::count == sh - 1);\n\n\tconst int ii[] = {0, 1, 1, 1, 2, 2, 2};\n\tconst unsigned si = sizeof(ii)/sizeof(ii[0]);\n\tint ji[si] = {-1};\n\tcount_equal::count = 0;\n\tr = ranges::unique_copy(::as_lvalue(ranges::subrange(InIter(ii), Sent(ii+si))), OutIter(ji), count_equal());\n\tCHECK(base(r.in) == ii + si);\n\tCHECK(base(r.out) == ji + 3);\n\tCHECK(ji[0] == 0);\n\tCHECK(ji[1] == 1);\n\tCHECK(ji[2] == 2);\n\tCHECK(count_equal::count == si - 1);\n}\n\ntemplate<class InIter, class OutIter>\nvoid test() {\n\tusing Sent = typename sentinel_type<InIter>::type;\n\ttest_iter<InIter, OutIter>();\n\ttest_iter<InIter, OutIter, Sent>();\n\n\ttest_range<InIter, OutIter>();\n\ttest_range<InIter, OutIter, Sent>();\n}\n\nstruct S {\n\tint i, j;\n};\n\nbool operator==(S l, S r) {\n\treturn l.i == r.i && l.j == r.j;\n}\n\nbool operator!=(S l, S r) {\n\treturn !(l == r);\n}\n\nint main() {\n\ttest<input_iterator<const int*>, output_iterator<int*> >();\n\ttest<input_iterator<const int*>, forward_iterator<int*> >();\n\ttest<input_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<input_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<input_iterator<const int*>, int*>();\n\n\ttest<forward_iterator<const int*>, output_iterator<int*> >();\n\ttest<forward_iterator<const int*>, forward_iterator<int*> >();\n\ttest<forward_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<forward_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<forward_iterator<const int*>, int*>();\n\n\ttest<bidirectional_iterator<const int*>, output_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, forward_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<bidirectional_iterator<const int*>, int*>();\n\n\ttest<random_access_iterator<const int*>, output_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, forward_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, bidirectional_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, random_access_iterator<int*> >();\n\ttest<random_access_iterator<const int*>, int*>();\n\n\ttest<const int*, output_iterator<int*> >();\n\ttest<const int*, forward_iterator<int*> >();\n\ttest<const int*, bidirectional_iterator<int*> >();\n\ttest<const int*, random_access_iterator<int*> >();\n\ttest<const int*, int*>();\n\n\t// Test projections:\n\t{\n\t\tS const ia[] = {{1,1},{2,2},{3,3},{3,4},{4,5},{5,6},{5,7},{5,8},{6,9},{7,10}};\n\t\tS ib[ranges::size(ia)];\n\t\tranges::unique_copy_result<const S*, S*> r =\n\t\t\tranges::unique_copy(ia, ib, ranges::equal_to(), &S::i);\n\t\tCHECK(r.in == ranges::end(ia));\n\t\tCHECK(r.out == ib + 7);\n\t\tCHECK_EQUAL(ranges::subrange(ib, ib+7), {S{1,1},S{2,2},S{3,3},S{4,5},S{5,6},S{6,9},S{7,10}});\n\t}\n\n\t// Test rvalue ranges:\n\t{\n\t\tS const ia[] = {{1,1},{2,2},{3,3},{3,4},{4,5},{5,6},{5,7},{5,8},{6,9},{7,10}};\n\t\tS ib[ranges::size(ia)];\n\t\tauto r = ranges::unique_copy(std::move(ia), ib, ranges::equal_to(), &S::i);\n\t\tstatic_assert(ranges::same_as<decltype(r.in), ranges::dangling>);\n\t\tCHECK(r.out == ib + 7);\n\t\tCHECK_EQUAL(ranges::subrange(ib, ib+7), {S{1,1},S{2,2},S{3,3},S{4,5},S{5,6},S{6,9},S{7,10}});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/algorithm/upper_bound.cpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n//  Copyright 2005 - 2007 Adobe Systems Incorporated\n//  Distributed under the MIT License(see accompanying file LICENSE_1_0_0.txt\n//  or a copy at http://stlab.adobe.com/licenses.html)\n\n#include <stl2/detail/algorithm/upper_bound.hpp>\n#include <stl2/view/iota.hpp>\n#include <vector>\n#include <utility>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct my_int\n{\n\tint value;\n};\n\nbool compare(my_int lhs, my_int rhs)\n{\n\treturn lhs.value < rhs.value;\n}\n\nvoid not_totally_ordered()\n{\n\t// This better compile!\n\tstd::vector<my_int> vec;\n\tranges::upper_bound(vec, my_int{10}, compare);\n}\n\nint main()\n{\n\tusing ranges::begin;\n\tusing ranges::end;\n\tusing ranges::size;\n\tusing ranges::less;\n\n\tstd::pair<int, int> a[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\tconst std::pair<int, int> c[] = {{0, 0}, {0, 1}, {1, 2}, {1, 3}, {3, 4}, {3, 5}};\n\n\tCHECK(ranges::ext::upper_bound_n(begin(a), size(a), a[0]) == &a[1]);\n\tCHECK(ranges::ext::upper_bound_n(begin(a), size(a), a[1], less()) == &a[2]);\n\tCHECK(ranges::ext::upper_bound_n(begin(a), size(a), 1, less(), &std::pair<int, int>::first) == &a[4]);\n\n\tCHECK(ranges::upper_bound(begin(a), end(a), a[0]) == &a[1]);\n\tCHECK(ranges::upper_bound(begin(a), end(a), a[1], less()) == &a[2]);\n\tCHECK(ranges::upper_bound(begin(a), end(a), 1, less(), &std::pair<int, int>::first) == &a[4]);\n\n\tCHECK(ranges::upper_bound(a, a[2]) == &a[3]);\n\tCHECK(ranges::upper_bound(c, c[3]) == &c[4]);\n\n\tCHECK(ranges::upper_bound(a, a[4], less()) == &a[5]);\n\tCHECK(ranges::upper_bound(c, c[5], less()) == &c[6]);\n\n\tCHECK(ranges::upper_bound(a, 1, less(), &std::pair<int, int>::first) == &a[4]);\n\tCHECK(ranges::upper_bound(c, 1, less(), &std::pair<int, int>::first) == &c[4]);\n\n\tCHECK(ranges::upper_bound(ranges::subrange(a), a[2]) == &a[3]);\n\tCHECK(ranges::upper_bound(ranges::subrange(c), c[3]) == &c[4]);\n\n\tCHECK(ranges::upper_bound(ranges::subrange(a), a[4], less()) == &a[5]);\n\tCHECK(ranges::upper_bound(ranges::subrange(c), c[5], less()) == &c[6]);\n\n\tCHECK(ranges::upper_bound(ranges::subrange(a), 1, less(), &std::pair<int, int>::first) == &a[4]);\n\tCHECK(ranges::upper_bound(ranges::subrange(c), 1, less(), &std::pair<int, int>::first) == &c[4]);\n\n\tCHECK(*ranges::upper_bound(ranges::iota_view<int>{}, 42) == 43);\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/all_public_headers.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef ALL_PUBLIC_HEADERS_HPP\n#define ALL_PUBLIC_HEADERS_HPP\n\n#include <experimental/ranges/algorithm>\n#include <experimental/ranges/concepts>\n#include <experimental/ranges/functional>\n#include <experimental/ranges/iterator>\n#include <experimental/ranges/memory>\n#include <experimental/ranges/random>\n#include <experimental/ranges/ranges>\n#include <experimental/ranges/type_traits>\n#include <experimental/ranges/utility>\n#include <stl2/algorithm.hpp>\n#include <stl2/concepts.hpp>\n#include <stl2/functional.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/memory.hpp>\n#include <stl2/random.hpp>\n#include <stl2/ranges.hpp>\n#include <stl2/type_traits.hpp>\n#include <stl2/utility.hpp>\n\n#endif // ALL_PUBLIC_HEADERS_HPP\n"
  },
  {
    "path": "test/common-libcxx.hpp",
    "content": "//===----------------------------------------------------------------------===//\r\n//\r\n//                     The LLVM Compiler Infrastructure\r\n//\r\n// This file is dual licensed under the MIT and the University of Illinois Open\r\n// Source Licenses. See LICENSE.TXT for details.\r\n//\r\n//===----------------------------------------------------------------------===//\r\nnamespace libcpp_tests\r\n{\r\n\tstruct E {};\r\n\r\n\ttemplate<class T>\r\n\tstruct X { explicit X(T const&){} };\r\n\r\n\ttemplate<class T>\r\n\tstruct S { explicit S(T const&){} };\r\n}\r\nSTL2_OPEN_NAMESPACE {\r\n\ttemplate<typename T>\r\n\tstruct common_type<T, libcpp_tests::S<T>>\r\n\t{\r\n\t\ttypedef libcpp_tests::S<T> type;\r\n\t};\r\n\ttemplate<typename T>\r\n\tstruct common_type<libcpp_tests::S<T>, T>\r\n\t{\r\n\t\ttypedef libcpp_tests::S<T> type;\r\n\t};\r\n} STL2_CLOSE_NAMESPACE\r\nnamespace libcpp_tests\r\n{\r\n\ttemplate<class T, class U>\r\n\tstruct no_common_type : true_type {};\r\n\r\n\ttemplate<class T, class U>\r\n\trequires requires { typename common_type_t<T, U>; }\r\n\tstruct no_common_type<T, U> : false_type {};\r\n\r\n\tstatic_assert((is_same<common_type_t<int>, int>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<char>, char>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<int>,   int>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<char>, char>::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<               int>, int>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const          int>, int>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<      volatile int>, int>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const volatile int>, int>::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<int,           int>, int>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<int,     const int>, int>::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<long,       const int>, long>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const long,       int>, long>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<long,    volatile int>, long>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<volatile long,    int>, long>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const long, const int>, long>::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<double, char>, double>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<short, char>, int>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<double, char>, double>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<short, char>, int>::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<double, char, long long>, double>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<unsigned, char, long long>, long long>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<double, char, long long>, double>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<unsigned, char, long long>, long long>::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<               void>, void>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const          void>, void>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<      volatile void>, void>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const volatile void>, void>::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<void,       const void>, void>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const void,       void>, void>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<void,    volatile void>, void>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<volatile void,    void>, void>::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<const void, const void>, void>::value), \"\");\r\n\r\n\tstatic_assert((no_common_type<void, int>::value), \"\");\r\n\tstatic_assert((no_common_type<int, void>::value), \"\");\r\n\tstatic_assert((no_common_type<int, E>::value), \"\");\r\n\tstatic_assert((no_common_type<int, X<int> >::value), \"\");\r\n\r\n\tstatic_assert((is_same<common_type_t<int, S<int> >, S<int> >::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<int, S<int>, S<int> >, S<int> >::value), \"\");\r\n\tstatic_assert((is_same<common_type_t<int, int, S<int> >, S<int> >::value), \"\");\r\n}\r\n"
  },
  {
    "path": "test/common-libstdcxx.hpp",
    "content": "// Copyright (C) 2009-2016 Free Software Foundation, Inc.\r\n//\r\n// This file is part of the GNU ISO C++ Library.  This library is free\r\n// software; you can redistribute it and/or modify it under the\r\n// terms of the GNU General Public License as published by the\r\n// Free Software Foundation; either version 3, or (at your option)\r\n// any later version.\r\n//\r\n// This library is distributed in the hope that it will be useful,\r\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n// GNU General Public License for more details.\r\n//\r\n// You should have received a copy of the GNU General Public License along\r\n// with this library; see the file COPYING3.  If not see\r\n// <http://www.gnu.org/licenses/>.\r\n\r\nSTL2_OPEN_NAMESPACE {\r\n\ttypedef int test_type1;\r\n\ttypedef int& test_type2;\r\n\ttypedef double test_type3;\r\n\ttypedef float test_type4;\r\n\ttypedef void test_type5;\r\n\ttypedef const void test_type6;\r\n\r\n\ttemplate struct common_type<test_type1>;\r\n\ttemplate struct common_type<test_type1, test_type2>;\r\n\ttemplate struct common_type<test_type1, test_type2, test_type3>;\r\n\ttemplate struct common_type<test_type1, test_type2, test_type3, test_type4>;\r\n\r\n\ttemplate struct common_type<test_type5>;\r\n\ttemplate struct common_type<test_type5, test_type6>;\r\n} STL2_CLOSE_NAMESPACE\r\n\r\nnamespace libstdcpp_tests\r\n{\r\n\ttemplate<typename T, typename Expected>\r\n\tusing is_type = std::bool_constant<same_as<meta::_t<T>, Expected>>;\r\n\r\n\t// Inspection types:\r\n\r\n\tstruct S {};\r\n\r\n\tstruct B {};\r\n\tstruct D : B {};\r\n\r\n\tstruct F1 { operator void*(); };\r\n\tstruct F2 { operator void*(); };\r\n\r\n\tstruct G1 { operator const void*(); };\r\n\tstruct G2 { operator volatile void*(); };\r\n\r\n\ttemplate<typename T>\r\n\tstruct ImplicitTo\r\n\t{\r\n\t\toperator T();\r\n\t};\r\n\r\n\ttemplate<typename T>\r\n\tstruct ExplicitTo\r\n\t{\r\n\t\texplicit operator T();\r\n\t};\r\n\r\n\ttemplate<typename T>\r\n\tstruct PrivateImplicitTo\r\n\t{\r\n\tprivate:\r\n\t\toperator T();\r\n\t};\r\n\r\n\tauto lmd1 = [](int, double) {};\r\n\tauto lmd2 = [](int, double) {};\r\n\r\n\tstruct Abstract\r\n\t{\r\n\t\tvirtual ~Abstract() = 0;\r\n\t};\r\n\r\n\tenum class ScEn;\r\n\r\n\tenum UnscEn : int;\r\n\r\n\tstruct Ukn;\r\n\r\n\tunion U\r\n\t{\r\n\t\tint i;\r\n\t};\r\n\r\n\tunion U2\r\n\t{\r\n\t\tlong i;\r\n\t};\r\n\r\n\tunion UConv1\r\n\t{\r\n\t\toperator Abstract*();\r\n\t};\r\n\r\n\tunion UConv2\r\n\t{\r\n\t\toperator Abstract*();\r\n\t};\r\n\r\n#if 0 // All test cases involving these types are ill-formed NDR since they\r\n\t  // specialize common_type<X, Y> differently from common_type<Y, X>\r\n\tstruct X1 {};\r\n\tstruct X2 {};\r\n\tstruct RX12 {};\r\n\tstruct RX21 {};\r\n\tstruct Y1 {};\r\n\tstruct Y2 {};\r\n\tstruct Y3 {};\r\n\tstruct Y4 {};\r\n#endif // IFNDR test cases\r\n}\r\n\r\n#if 0 // These are all ill-formed NDR\r\nSTL2_OPEN_NAMESPACE {\r\n\ttemplate<>\r\n\tstruct common_type<libstdcpp_tests::X1, libstdcpp_tests::X2>\r\n\t{\r\n\t\ttypedef libstdcpp_tests::RX12 type;\r\n\t};\r\n\r\n\ttemplate<>\r\n\tstruct common_type<libstdcpp_tests::X2, libstdcpp_tests::X1>\r\n\t{\r\n\t\ttypedef libstdcpp_tests::RX12 type;\r\n\t};\r\n\r\n\ttemplate<>\r\n\tstruct common_type<libstdcpp_tests::RX12, libstdcpp_tests::X1>\r\n\t{\r\n\t\ttypedef libstdcpp_tests::Y1 type;\r\n\t};\r\n\r\n\ttemplate<>\r\n\tstruct common_type<libstdcpp_tests::X1, libstdcpp_tests::RX12>\r\n\t{\r\n\t\ttypedef libstdcpp_tests::Y1 type;\r\n\t};\r\n\r\n\ttemplate<>\r\n\tstruct common_type<libstdcpp_tests::RX21, libstdcpp_tests::X1>\r\n\t{\r\n\t\ttypedef libstdcpp_tests::Y3 type;\r\n\t};\r\n\r\n\ttemplate<>\r\n\tstruct common_type<libstdcpp_tests::X1, libstdcpp_tests::RX21>\r\n\t{\r\n\t\ttypedef libstdcpp_tests::Y3 type;\r\n\t};\r\n} STL2_CLOSE_NAMESPACE\r\n#endif // IFNDR test cases\r\n\r\nnamespace libstdcpp_tests\r\n{\r\n\tstatic_assert(is_type<common_type<int, int>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<ScEn, ScEn>, ScEn>(), \"\");\r\n\tstatic_assert(is_type<common_type<UnscEn, UnscEn>, UnscEn>(), \"\");\r\n\tstatic_assert(is_type<common_type<UnscEn, int>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<int, int, int>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<int, int, int, int>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<int, int, int, int, int>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<S, S>, S>(), \"\");\r\n\tstatic_assert(is_type<common_type<const S, const S>, S>(), \"\");\r\n\tstatic_assert(is_type<common_type<std::initializer_list<int>,\r\n\t\t\tstd::initializer_list<int>>, std::initializer_list<int>>(), \"\");\r\n\tstatic_assert(is_type<common_type<B, D>, B>(), \"\");\r\n\tstatic_assert(is_type<common_type<D, B>, B>(), \"\");\r\n\tstatic_assert(is_type<common_type<F1, F2>, void*>(), \"\");\r\n\tstatic_assert(is_type<common_type<F2, F1>, void*>(), \"\");\r\n#if STL2_WORKAROUND_MSVC_830361\r\n\tstatic_assert(!meta::is_trait<common_type<G1, G2>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<G2, G1>>(), \"\");\r\n#else // ^^^ \"workaround\" / no workaround vvv\r\n\tstatic_assert(is_type<common_type<G1, G2>, const volatile void*>(), \"\");\r\n\tstatic_assert(is_type<common_type<G2, G1>, const volatile void*>(), \"\");\r\n#endif // STL2_WORKAROUND_MSVC_830361\r\n\tstatic_assert(is_type<common_type<int*, const volatile int*>,\r\n\t\t\tconst volatile int*>(), \"\");\r\n\tstatic_assert(is_type<common_type<void*, const volatile int*>,\r\n\t\t\tconst volatile void*>(), \"\");\r\n\tstatic_assert(is_type<common_type<void, void>, void>(), \"\");\r\n\tstatic_assert(is_type<common_type<const void, const void>, void>(), \"\");\r\n\tstatic_assert(is_type<common_type<int&, int&&>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<int&, int&>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<int&&, int&&>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<int&&, const int&&>, int>(), \"\");\r\n\tstatic_assert(is_type<common_type<U&, const U&&>, U>(), \"\");\r\n\tstatic_assert(is_type<common_type<U&, U&>, U>(), \"\");\r\n\tstatic_assert(is_type<common_type<U&&, U&&>, U>(), \"\");\r\n\tstatic_assert(is_type<common_type<int B::*, int D::*>, int D::*>(), \"\");\r\n\tstatic_assert(is_type<common_type<int D::*, int B::*>, int D::*>(), \"\");\r\n#if STL2_WORKAROUND_MSVC_830361\r\n\t// \"Workaround\" is a misnomer; this simply asserts the incorrect behavior\r\n\t// so we'll notice when the bug is fixed.\r\n\tstatic_assert(is_type<common_type<const int B::*, volatile int D::*>,\r\n\t\t\tvolatile int D::*>(), \"\");\r\n#else // ^^^ \"workaround\" / no workaround vvv\r\n\tstatic_assert(is_type<common_type<const int B::*, volatile int D::*>,\r\n\t\t\tconst volatile int D::*>(), \"\");\r\n#endif // STL2_WORKAROUND_MSVC_830361\r\n\tstatic_assert(is_type<common_type<int (B::*)(), int (D::*)()>,\r\n\t\t\tint (D::*)()>(), \"\");\r\n\tstatic_assert(is_type<common_type<int (B::*)() const, int (D::*)() const>,\r\n\t\t\tint (D::*)() const>(), \"\");\r\n\tstatic_assert(is_type<common_type<int[3], int[3]>, int*>(), \"\");\r\n\tstatic_assert(is_type<common_type<int[1], const int[3]>,\r\n\t\t\tconst int*>(), \"\");\r\n\tstatic_assert(is_type<common_type<void(), void()>, void(*)()>(), \"\");\r\n\tstatic_assert(is_type<common_type<void(&)(), void(&)()>, void(*)()>(), \"\");\r\n\tstatic_assert(is_type<common_type<void(&)(), void(&&)()>,\r\n\t\t\tvoid(*)()>(), \"\");\r\n\tstatic_assert(is_type<common_type<void(&&)(), void(&)()>,\r\n\t\t\tvoid(*)()>(), \"\");\r\n\tstatic_assert(is_type<common_type<void(&&)(), void(&&)()>,\r\n\t\t\tvoid(*)()>(), \"\");\r\n\tstatic_assert(is_type<common_type<ImplicitTo<int>, int>, int>{}, \"\");\r\n\tstatic_assert(is_type<common_type<ImplicitTo<int>, ImplicitTo<int>>,\r\n\t\t\tImplicitTo<int>>{}, \"\");\r\n\tstatic_assert(is_type<common_type<ImplicitTo<int>, int,\r\n\t\t\tImplicitTo<int>>, int>{}, \"\");\r\n\tstatic_assert(is_type<common_type<ExplicitTo<int>, ExplicitTo<int>>,\r\n\t\t\tExplicitTo<int>>{}, \"\");\r\n\tstatic_assert(is_type<common_type<decltype(lmd1), decltype(lmd1)>,\r\n\t\t\tdecltype(lmd1)>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(lmd1)&, decltype(lmd1)&>,\r\n\t\t\tdecltype(lmd1)>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(lmd1)&, decltype(lmd2)&>,\r\n\t\t\tvoid(*)(int, double)>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(nullptr), void*>, void*>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(nullptr), int*>, int*>(), \"\");\r\n\tstatic_assert(is_type<common_type<const decltype(nullptr)&, int*>,\r\n\t\t\tint*>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(nullptr), const volatile int*>,\r\n\t\t\tconst volatile int*>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(nullptr), int (B::*)()>,\r\n\t\t\tint (B::*)()>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(nullptr), int (B::*)() const>,\r\n\t\t\tint (B::*)() const>(), \"\");\r\n\tstatic_assert(is_type<common_type<decltype(nullptr), const int B::*>,\r\n\t\t\tconst int B::*>(), \"\");\r\n\tstatic_assert(is_type<common_type<Abstract&, Abstract&>, Abstract>(), \"\");\r\n\tstatic_assert(is_type<common_type<Ukn&, Ukn&>, Ukn>(), \"\");\r\n\tstatic_assert(is_type<common_type<ImplicitTo<B&>, B&>, B>{}, \"\");\r\n\tstatic_assert(is_type<common_type<ImplicitTo<B&>&, B&&>, B>{}, \"\");\r\n\tstatic_assert(is_type<common_type<UConv1, const Abstract*&>,\r\n\t\t\tconst Abstract*>(), \"\");\r\n\tstatic_assert(is_type<common_type<UConv1, UConv2>, Abstract*>{}, \"\");\r\n\tstatic_assert(is_type<common_type<UConv1&, UConv2&>, Abstract*>{}, \"\");\r\n\r\n\tstatic_assert(is_type<common_type<Abstract&&, Abstract&&>,\r\n\t\t\tAbstract>(), \"\");\r\n\tstatic_assert(is_type<common_type<const Abstract&&,\r\n\t\t\t\t\t\tconst Abstract&&>, Abstract>(), \"\");\r\n\tstatic_assert(is_type<common_type<volatile Abstract&&,\r\n\t\t\t\t\t\tvolatile Abstract&&>, Abstract>(), \"\");\r\n\tstatic_assert(is_type<common_type<Ukn&&, Ukn&&>, Ukn>(), \"\");\r\n\tstatic_assert(is_type<common_type<const Ukn&&, const Ukn&&>,\r\n\t\t\tUkn>(), \"\");\r\n\tstatic_assert(is_type<common_type<volatile Ukn&&, volatile Ukn&&>,\r\n\t\t\tUkn>(), \"\");\r\n\r\n#if 0 // IFNDR test cases\r\n\tstatic_assert(is_type<common_type<X1, X2>, RX12>(), \"\");\r\n\tstatic_assert(is_type<common_type<X2, X1>, RX21>(), \"\");\r\n\r\n\tstatic_assert(is_type<common_type<X1, X2, X1>, Y1>(), \"\");\r\n\tstatic_assert(is_type<common_type<X2, X1, X1>, Y3>(), \"\");\r\n\r\n\tstatic_assert(is_type<common_type<X1, X1, X2>, RX12>(), \"\");\r\n\tstatic_assert(is_type<common_type<X1, X1, X2, X1>, Y1>(), \"\");\r\n#endif // IFNDR test cases\r\n\r\n\tstatic_assert(!meta::is_trait<common_type<>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, S>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<U, S>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<U, U2>>(), \"\");\r\n\t// See https://wg21.link/lwg2763 and P0435\r\n\tstatic_assert(is_same_v<common_type_t<const ImplicitTo<int>, int>, int>);\r\n#if !defined(__GNUC__) || defined(__clang__) // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67225\r\n\tstatic_assert(!meta::is_trait<common_type<PrivateImplicitTo<int>, int>>{}, \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<const PrivateImplicitTo<int>, int>>(), \"\");\r\n#endif\r\n\tstatic_assert(!meta::is_trait<common_type<int, Ukn>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, Abstract>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<Ukn, Abstract>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, const volatile void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<Abstract, void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<Ukn, void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int[4], void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<ScEn, void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<UnscEn, void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<U, void>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<std::initializer_list<int>,\r\n\t\t\tvoid>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, int, int, S>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, int, S, int>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, S, int, int>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<S, int, int, int>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, int, void, int, int>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<B, S>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, B, S>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<B, int, S>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<B, S, int>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int*, double*>>(), \"\");\r\n#if STL2_WORKAROUND_MSVC_FUNCTION_CONVERSIONS\r\n\tstatic_assert(is_type<common_type<void*, void(*)(...)>, void*>(), \"\");\r\n#else // ^^^ MSVC / not MSVC vvv\r\n\tstatic_assert(!meta::is_trait<common_type<void*, void(*)(...)>>(), \"\");\r\n#endif // STL2_WORKAROUND_MSVC_FUNCTION_CONVERSIONS\r\n\tstatic_assert(!meta::is_trait<common_type<void(*)(), void(*)(...)>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<void(*)(), void(S::*)()>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<void(S::*)() const,\r\n\t\t\tvoid(S::*)()>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int S::*, long S::*>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int S::*, void(S::*)()>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int (B::*)(),\r\n\t\t\tint (D::*)() const>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int (B::*)() const,\r\n\t\t\tint (D::*)()>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<int, ExplicitTo<int>>>{}, \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<ImplicitTo<int>,\r\n\t\t\t\t\t\tExplicitTo<int>>>{}, \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<ScEn, int>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<ScEn, UnscEn>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<U, S, Abstract, void, D,\r\n\t\t\tint (B::*)(), int[5]>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<UConv1, Abstract&&>>(), \"\");\r\n\tstatic_assert(!meta::is_trait<common_type<std::initializer_list<int>,\r\n\t\t\t\t\t\tstd::initializer_list<long>>>(), \"\");\r\n\r\n\tvoid test(int i)\r\n\t{\r\n\t\tauto local_lmd1 = [=](int, double) { return i + i; };\r\n\t\tauto local_lmd2 = [=](int, double) { return i - i; };\r\n\r\n\t\tstatic_assert(is_type<common_type<decltype(local_lmd1),\r\n\t\t\t\t\t\tdecltype(local_lmd1)>, decltype(local_lmd1)>(), \"\");\r\n\t\tstatic_assert(is_type<common_type<decltype(local_lmd1)&,\r\n\t\t\t\t\t\tdecltype(local_lmd1)>, decltype(local_lmd1)>(), \"\");\r\n\t\tstatic_assert(is_type<common_type<decltype(local_lmd1)&,\r\n\t\t\t\t\tdecltype(local_lmd1)&>, decltype(local_lmd1)>(), \"\");\r\n\r\n\t\tstatic_assert(!meta::is_trait<common_type<decltype(local_lmd1),\r\n\t\t\t\tdecltype(lmd1)>>(), \"\");\r\n\t\tstatic_assert(!meta::is_trait<common_type<decltype(local_lmd1)&,\r\n\t\t\t\tdecltype(lmd1)&>>(), \"\");\r\n\t\tstatic_assert(!meta::is_trait<common_type<decltype(local_lmd1),\r\n\t\t\t\tdecltype(local_lmd2)>>(), \"\");\r\n\t\tstatic_assert(!meta::is_trait<common_type<decltype(local_lmd1)&,\r\n\t\t\t\tdecltype(local_lmd2)&>>(), \"\");\r\n\t}\r\n\r\n\ttemplate<typename... Args>\r\n\tconstexpr\r\n\tstd::array<typename common_type<Args...>::type,\r\n\t\tsizeof...(Args)>\r\n\tmake_array(Args&&... args)\r\n\t{\r\n\t\ttypedef typename common_type<Args...>::type CT;\r\n\t\treturn std::array<CT, sizeof...(Args)>{static_cast<CT>\r\n\t\t\t(std::forward<Args>(args))...};\r\n\t}\r\n\r\n\tvoid test01()\r\n\t{\r\n\t\tconstexpr auto a1 = make_array(0);\r\n\t\tconstexpr auto a2 = make_array(0, 1.2);\r\n\t\tconstexpr auto a3 = make_array(5, true, 3.1415f, 'c');\r\n\r\n\t\tint i{};\r\n\t\tdouble d{1.2};\r\n\t\tfloat f{3.1415f};\r\n\r\n\t\tauto b1 = make_array(i);\r\n\t\tauto b2 = make_array(i, 1.2);\r\n\t\tauto b3 = make_array(i, d);\r\n\t\tauto b4 = make_array(0, d);\r\n\t\tauto b5 = make_array(i, true, f, 'c');\r\n\r\n\t\tstatic_assert(is_same<decltype(a1), const std::array<int, 1>>(), \"\");\r\n\t\tstatic_assert(is_same<decltype(a2), const std::array<double, 2>>(), \"\");\r\n\t\tstatic_assert(is_same<decltype(a3), const std::array<float, 4>>(), \"\");\r\n\r\n\t\tstatic_assert(is_same<decltype(b1), std::array<int, 1>>(), \"\");\r\n\t\tstatic_assert(is_same<decltype(b2), std::array<double, 2>>(), \"\");\r\n\t\tstatic_assert(is_same<decltype(b3), std::array<double, 2>>(), \"\");\r\n\t\tstatic_assert(is_same<decltype(b4), std::array<double, 2>>(), \"\");\r\n\t\tstatic_assert(is_same<decltype(b5), std::array<float, 4>>(), \"\");\r\n\t}\r\n\r\n\t#define JOIN( X, Y ) DO_JOIN( X, Y )\r\n\t#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)\r\n\t#define DO_JOIN2( X, Y ) X##Y\r\n\r\n\t#define COMMON_TYPE_TEST_1(type1, uid) \\\r\n\t\ttypedef common_type<type1>::type JOIN(test_t,uid); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,uid), JOIN(test_t,uid)>::value) ); \\\r\n\t\ttypedef common_type<const type1>::type JOIN(test_t,JOIN(uid,c)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,c)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,c))>::value) ); \\\r\n\t\ttypedef common_type<volatile type1>::type JOIN(test_t,JOIN(uid,v)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,v)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,v))>::value) ); \\\r\n\t\ttypedef common_type<const volatile type1>::type JOIN(test_t,JOIN(uid,cv)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,cv)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,cv))>::value) ); \\\r\n\t\ttypedef common_type<type1 &>::type JOIN(test_t,JOIN(uid,l)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,l)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,l))>::value) ); \\\r\n\t\ttypedef common_type<const type1 &>::type JOIN(test_t,JOIN(uid,lc)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,lc)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,lc))>::value) ); \\\r\n\t\ttypedef common_type<volatile type1 &>::type JOIN(test_t,JOIN(uid,lv)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,lv)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,lv))>::value) ); \\\r\n\t\ttypedef common_type<const volatile type1 &>::type JOIN(test_t,JOIN(uid,lcv)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,lcv)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,lcv))>::value) ); \\\r\n\t\ttypedef common_type<type1 &&>::type JOIN(test_t,JOIN(uid,r)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,r)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,r))>::value) ); \\\r\n\t\ttypedef common_type<const type1 &&>::type JOIN(test_t,JOIN(uid,rc)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,rc)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,rc))>::value) ); \\\r\n\t\ttypedef common_type<volatile type1 &&>::type JOIN(test_t,JOIN(uid,rv)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,rv)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,rv))>::value) ); \\\r\n\t\ttypedef common_type<const volatile type1 &&>::type JOIN(test_t,JOIN(uid,rcv)); \\\r\n\t\tCHECK( (is_same<JOIN(test_t,JOIN(uid,rcv)), \\\r\n\t\t\t\t\t\tJOIN(test_t,JOIN(uid,rcv))>::value) )\r\n\r\n\tstruct AA { };\r\n\tstruct BB : AA { };\r\n\r\n\tvoid typedefs_test01()\r\n\t{\r\n\t\t// Positive tests.\r\n\t\tCOMMON_TYPE_TEST_1(int, 1);\r\n\t\tCOMMON_TYPE_TEST_1(double, 2);\r\n\t\tCOMMON_TYPE_TEST_1(AA, 3);\r\n\t\tCOMMON_TYPE_TEST_1(BB, 4);\r\n\t}\r\n\r\n\t#define COMMON_TYPE_TEST_2_IMPL(type1, type2, type3, uid) \\\r\n\t\ttypedef common_type<type1, type2>::type JOIN(JOIN(test, uid),_t1); \\\r\n\t\ttypedef common_type<type2, type1>::type JOIN(JOIN(test, uid),_t2); \\\r\n\t\tCHECK( (is_same<JOIN(JOIN(test, uid),_t1), type3>::value) ); \\\r\n\t\tCHECK( (is_same<JOIN(JOIN(test, uid),_t2), type3>::value) )\r\n\r\n\t#define NO_CV\r\n\r\n\t#define COMMON_TYPE_TEST_2(cv_qual, type1, type2, type3, uid) \\\r\n\t\tCOMMON_TYPE_TEST_2_IMPL(cv_qual type1, type2, type3, uid); \\\r\n\t\tCOMMON_TYPE_TEST_2_IMPL(cv_qual type1 &, type2, type3, JOIN(uid,l)); \\\r\n\t\tCOMMON_TYPE_TEST_2_IMPL(cv_qual type1 &&, type2, type3, JOIN(uid,r))\r\n\r\n\t#define COMMON_TYPE_TEST_ALL_2(type1, type2, type3, uid) \\\r\n\t\tCOMMON_TYPE_TEST_2(NO_CV, type1, type2, type3, uid); \\\r\n\t\tCOMMON_TYPE_TEST_2(const, type1, type2, type3, uid); \\\r\n\t\tCOMMON_TYPE_TEST_2(volatile, type1, type2, type3, uid); \\\r\n\t\tCOMMON_TYPE_TEST_2(const volatile, type1, type2, type3, uid)\r\n\r\n\tvoid typedefs_test02()\r\n\t{\r\n\t\tCOMMON_TYPE_TEST_ALL_2(int, int, int, 1);\r\n\t\tCOMMON_TYPE_TEST_ALL_2(int, double, double, 2);\r\n\t\tCOMMON_TYPE_TEST_2(NO_CV, AA, AA, AA, 3);\r\n\t\tCOMMON_TYPE_TEST_2(const, AA, AA, AA, 4);\r\n\t\tCOMMON_TYPE_TEST_2(NO_CV, BB, AA, AA, 5);\r\n\t}\r\n\r\n\tvoid typedefs_1()\r\n\t{\r\n\t\ttypedefs_test01();\r\n\t\ttypedefs_test02();\r\n\t}\r\n\r\n\t// 2009-11-12  Paolo Carlini  <paolo.carlini@oracle.com>\r\n\t// DR 1255.\r\n\tstatic_assert( is_same<common_type<void>::type, void>(),\r\n\t\t\t\t\t\"common_type<void>\" );\r\n\tstatic_assert( is_same<common_type<const void>::type, void>(),\r\n\t\t\t\t\t\"common_type<const void>\" );\r\n\tstatic_assert( is_same<common_type<volatile void>::type, void>(),\r\n\t\t\t\t\t\"common_type<volatile void>\" );\r\n\tstatic_assert( is_same<common_type<const volatile void>::type, void>(),\r\n\t\t\t\t\t\"common_type<const volatile void>\" );\r\n\r\n\tstatic_assert( is_same<common_type<void, void>::type, void>(),\r\n\t\t\t\t\t\"common_type<void, void>\" );\r\n\tstatic_assert( is_same<common_type<void, const void>::type, void>(),\r\n\t\t\t\t\t\"common_type<void, const void>\" );\r\n\tstatic_assert( is_same<common_type<void, volatile void>::type, void>(),\r\n\t\t\t\t\t\"common_type<void, volatile void>\" );\r\n\tstatic_assert( is_same<common_type<void, const volatile void>::type, void>(),\r\n\t\t\t\t\t\"common_type<void, const volatile void>\" );\r\n\tstatic_assert( is_same<common_type<const void, void>::type, void>(),\r\n\t\t\t\t\t\"common_type<const void, void>\" );\r\n\tstatic_assert( is_same<common_type<const void, const void>::type, void>(),\r\n\t\t\t\t\t\"common_type<const void, const void>\" );\r\n\tstatic_assert( is_same<common_type<const void, volatile void>::type, void>(),\r\n\t\t\t\t\t\"common_type<const void, volatile void>\" );\r\n\tstatic_assert( is_same<common_type<const void, const volatile void>::type,\r\n\t\t\t\tvoid>(), \"common_type<const void, const volatile void>\" );\r\n\tstatic_assert( is_same<common_type<volatile void, void>::type, void>(),\r\n\t\t\t\t\t\"common_type<volatile void, void>\" );\r\n\tstatic_assert( is_same<common_type<volatile void, volatile void>::type,\r\n\t\t\t\tvoid>(), \"common_type<volatile void, volatile void>\" );\r\n\tstatic_assert( is_same<common_type<volatile void, const void>::type,\r\n\t\t\t\tvoid>(), \"common_type<volatile void, const void>\" );\r\n\tstatic_assert( is_same<common_type<volatile void, const volatile void>::type,\r\n\t\t\t\tvoid>(), \"common_type<volatile void, const volatile void>\" );\r\n\tstatic_assert( is_same<common_type<const volatile void, void>::type, void>(),\r\n\t\t\t\t\"common_type<const volatile void, const volatile void>\" );\r\n\tstatic_assert( is_same<common_type<const volatile void, const void>::type,\r\n\t\t\t\tvoid>(), \"common_type<const volatile void, const void>\" );\r\n\tstatic_assert( is_same<common_type<const volatile void, volatile void>::type,\r\n\t\t\t\tvoid>(), \"common_type<const volatile void, volatile void>\" );\r\n\tstatic_assert( is_same<common_type<const volatile void, const volatile void>::type,\r\n\t\t\t\tvoid>(),\r\n\t\t\t\t\"common_type<const volatile void, const volatile void>\" );\r\n}\r\n"
  },
  {
    "path": "test/common.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/type_traits.hpp>\n\n#include <array>\n#include <functional>\n#include <initializer_list>\n#include <tuple>\n#include <utility>\n\n#include \"simple_test.hpp\"\n\nusing std::tuple;\nusing std::is_same;\nusing std::is_same_v;\nusing std::false_type;\nusing std::true_type;\nusing namespace __stl2;\n\nstatic_assert(is_same_v<common_type_t<int, short&, int, char>, int>);\nstatic_assert(!meta::is_trait<common_type<int, short, int, char*>>());\n\nstruct X {};\nstruct Y { explicit Y(X){} };\n\nSTL2_OPEN_NAMESPACE {\ntemplate<> struct common_type<X, Y> { typedef Y type; };\ntemplate<> struct common_type<Y, X> { typedef Y type; };\n} STL2_CLOSE_NAMESPACE\n\nstatic_assert(is_same_v<common_type_t<X, Y>, Y>);    // (A)\nstatic_assert(is_same_v<common_type_t<X, Y, Y>, Y>); // (B)\nstatic_assert(is_same_v<common_type_t<X, X, Y>, Y>); // (C)\n\nstruct AA {\n\tAA() = default;\n\tAA(AA &&) = delete;\n\tAA(AA const &) = delete;\n};\nstruct BB : AA { };\n\nstatic_assert(is_same_v<common_type_t<AA, BB>, AA>); // (C)\n\nstatic_assert(is_same_v<common_reference_t<int &&, int const &, int volatile &>, int const volatile &>);\nstatic_assert(is_same_v<common_reference_t<int &&, int const &, float &>, float>);\nstatic_assert(!meta::is_trait<common_reference<int, short, int, char*>>());\n\nSTL2_OPEN_NAMESPACE {\ntemplate<class... T, class... U, template<class> class TQual, template<class> class UQual>\n\trequires (meta::Valid<common_reference_t, TQual<T>, UQual<U>> && ...)\nstruct basic_common_reference<tuple<T...>, tuple<U...>, TQual, UQual> {\n\tusing type = tuple<common_reference_t<TQual<T>, UQual<U>>...>;\n};\n} STL2_CLOSE_NAMESPACE\n\nstatic_assert(is_same_v<\n\tcommon_reference_t<const tuple<int, short> &, tuple<int&,short volatile&>>,\n\ttuple<const int&,const volatile short&>>);\n\nstatic_assert(is_same_v<\n\tcommon_reference_t<volatile tuple<int, short> &, const tuple<int,short>&>,\n\tconst volatile tuple<int, short>&>);\n\nstatic_assert(!meta::is_trait<\n\tcommon_reference<volatile tuple<short> &, const tuple<int,short>&>>());\n\nstruct B {};\nstruct D : B {};\n\nstruct noncopyable\n{\n\tnoncopyable() = default;\n\tnoncopyable(noncopyable const &) = delete;\n\tnoncopyable(noncopyable &&) = default;\n\tnoncopyable &operator=(noncopyable const &) = delete;\n\tnoncopyable &operator=(noncopyable &&) = default;\n};\n\nstruct noncopyable2 : noncopyable\n{};\n\nstatic_assert(is_same_v<common_reference_t<B &, D &>, B &>);\nstatic_assert(is_same_v<common_reference_t<B &, D const &>, B const &>);\nstatic_assert(is_same_v<common_reference_t<B &, D const &, D &>, B const &>);\nstatic_assert(is_same_v<common_reference_t<B const &, D &>, B const &>);\nstatic_assert(is_same_v<common_reference_t<B &, D &, B &, D &>, B &>);\n\nstatic_assert(is_same_v<common_reference_t<B &&, D &&>, B &&>);\nstatic_assert(is_same_v<common_reference_t<B const &&, D &&>, B const &&>);\nstatic_assert(is_same_v<common_reference_t<B &&, D const &&>, B const &&>);\n\nstatic_assert(is_same_v<common_reference_t<B &, D &&>, B const &>);\nstatic_assert(is_same_v<common_reference_t<B &, D const &&>, B const &>);\nstatic_assert(is_same_v<common_reference_t<B const &, D &&>, B const &>);\n\nstatic_assert(is_same_v<common_reference_t<B &&, D &>, B const &>);\nstatic_assert(is_same_v<common_reference_t<B &&, D const &>, B const &>);\nstatic_assert(is_same_v<common_reference_t<B const &&, D &>, B const &>);\n\nstatic_assert(is_same_v<common_reference_t<int, short>, int>);\nstatic_assert(is_same_v<common_reference_t<int, short &>, int>);\nstatic_assert(is_same_v<common_reference_t<int &, short &>, int>);\nstatic_assert(is_same_v<common_reference_t<int &, short>, int>);\n\n// tricky volatile reference case\nstatic_assert(is_same_v<common_reference_t<int &&, int volatile &>, int>);\nstatic_assert(is_same_v<common_reference_t<int volatile &, int &&>, int>);\nstatic_assert(is_same_v<common_reference_t<int const volatile &&, int volatile &&>, int const volatile &&>);\nstatic_assert(is_same_v<common_reference_t<int &&, int const &, int volatile &>, int const volatile &>);\n\n// Array types?? Yup!\nstatic_assert(is_same_v<common_reference_t<int (&)[10], int (&&)[10]>, int const(&)[10]>);\nstatic_assert(is_same_v<common_reference_t<int const (&)[10], int volatile (&)[10]>, int const volatile(&)[10]>);\nstatic_assert(is_same_v<common_reference_t<int (&)[10], int (&)[11]>, int *>);\n\n// Some tests with noncopyable types\nstatic_assert(is_same_v<\n\tcommon_reference_t<noncopyable const &, noncopyable>,\n\tnoncopyable>);\n\nstatic_assert(is_same_v<\n\tcommon_reference_t<noncopyable2 const &, noncopyable>,\n\tnoncopyable>);\n\nstatic_assert(is_same_v<\n\tcommon_reference_t<noncopyable const &, noncopyable2>,\n\tnoncopyable>);\n\nstruct X2 {};\nstruct Y2 {};\nstruct Z2 {\n\texplicit Z2(X2);\n\texplicit Z2(Y2);\n};\n\nSTL2_OPEN_NAMESPACE {\ntemplate<>\nstruct common_type<X2, Y2>\n{\n\tusing type = Z2;\n};\ntemplate<>\nstruct common_type<Y2, X2>\n{\n\tusing type = Z2;\n};\n} STL2_CLOSE_NAMESPACE\n\nstatic_assert(is_same_v<common_type_t<X2 &, Y2 const &>, Z2>);\nstatic_assert(is_same_v<common_reference_t<X2 &, Y2 const &>, Z2>);\n\nstatic_assert(common_reference_with<void, void>);\nstatic_assert(is_same_v<common_reference_t<void, void>, void>);\nstatic_assert(common_with<void, void>);\nstatic_assert(is_same_v<common_type_t<void, void>, void>);\n\nstatic_assert(is_same_v<common_type_t<reference_wrapper<int>, int>, int>);\nstatic_assert(is_same_v<common_type_t<std::reference_wrapper<int>, int>, int>);\n\n// https://github.com/ericniebler/stl2/issues/338\nstruct MyIntRef {\n  MyIntRef(int &);\n};\nstatic_assert(is_same_v<common_reference_t<int&, MyIntRef>, MyIntRef>);\nstatic_assert(is_same_v<common_reference_t<int, int, int>, int>);\n\n// Test cases taken from libc++\n#include \"common-libcxx.hpp\"\n\n// libstdc++ tests\n#include \"common-libstdcxx.hpp\"\n\nint main() {\n\t::libstdcpp_tests::typedefs_1();\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/concepts/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_stl2_test(test.concepts.core concepts.core core.cpp)\nadd_stl2_test(test.concepts.compare concepts.compare compare.cpp)\nadd_stl2_test(test.concepts.fundamental concepts.fundamental fundamental.cpp)\nadd_stl2_test(test.concepts.iterator concepts.iterator iterator.cpp)\nadd_stl2_test(test.concepts.object concepts.object object.cpp)\nadd_stl2_test(test.concepts.range concepts.range range.cpp)\nadd_stl2_test(test.concepts.swap concepts.swap swap.cpp)\n"
  },
  {
    "path": "test/concepts/compare.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <bitset>\n#include <type_traits>\n#include <stl2/detail/concepts/compare.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = std::experimental::ranges;\n\nnamespace boolean_test {\n// Better have at least these three, since we use them as\n// examples in the TS draft.\nstatic_assert(ranges::boolean<bool>);\nstatic_assert(ranges::boolean<std::true_type>);\nstatic_assert(ranges::boolean<std::bitset<42>::reference>);\n\nstatic_assert(ranges::boolean<int>);\nstatic_assert(!ranges::boolean<void*>);\n\nstruct A {};\nstruct B { operator bool() const; };\n\nstatic_assert(!ranges::boolean<A>);\nstatic_assert(ranges::boolean<B>);\n}\n\nnamespace equality_comparable_test {\nstruct A {\n\tfriend bool operator==(const A&, const A&);\n\tfriend bool operator!=(const A&, const A&);\n};\n\nstatic_assert(ranges::equality_comparable<int>);\nstatic_assert(ranges::equality_comparable<A>);\nstatic_assert(!ranges::equality_comparable<void>);\nstatic_assert(ranges::equality_comparable<int&>);\nstatic_assert(ranges::equality_comparable<std::nullptr_t>);\n\nstatic_assert(ranges::equality_comparable_with<int, int>);\nstatic_assert(ranges::equality_comparable_with<A, A>);\nstatic_assert(!ranges::equality_comparable_with<void, void>);\nstatic_assert(ranges::equality_comparable_with<int&, int>);\n} // namespace equality_comparable_test\n\nstatic_assert(ranges::totally_ordered<int>);\nstatic_assert(ranges::totally_ordered<float>);\nstatic_assert(!ranges::totally_ordered<void>);\nstatic_assert(ranges::totally_ordered<int&>);\n\nstatic_assert(ranges::totally_ordered_with<int, int>);\nstatic_assert(ranges::totally_ordered_with<int, double>);\nstatic_assert(!ranges::totally_ordered_with<int, void>);\nstatic_assert(ranges::totally_ordered_with<int&, int>);\n\nint main() {\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/concepts/core.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <iostream>\n#include <type_traits>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/utility.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = std::experimental::ranges;\n\nstatic_assert(ranges::same_as<int, int>);\nstatic_assert(ranges::same_as<double, double>);\nstatic_assert(!ranges::same_as<double, int>);\nstatic_assert(!ranges::same_as<int, double>);\n\n// Test that `same_as<A, B> && X` subsumes `same_as<B, A>` (with reversed args).\ntemplate<class A, class B>\n\trequires ranges::same_as<B, A>\nconstexpr bool test_same() {\n\treturn false;\n}\n\ntemplate<class A, class B>\n\trequires ranges::same_as<A, B> && ranges::integral<A>\nconstexpr bool test_same() {\n\treturn true;\n}\n\nstatic_assert(!test_same<int*, int*>());\nstatic_assert(test_same<int, int>());\n\nnamespace convertible_to_test {\n\tstruct A {};\n\tstruct B : A {};\n\n\tstatic_assert(ranges::convertible_to<A, A>);\n\tstatic_assert(ranges::convertible_to<B, B>);\n\tstatic_assert(!ranges::convertible_to<A, B>);\n\tstatic_assert(ranges::convertible_to<B, A>);\n\tstatic_assert(ranges::convertible_to<int, double>);\n\tstatic_assert(ranges::convertible_to<double, int>);\n\tstatic_assert(ranges::convertible_to<void, void>);\n}\n\nnamespace common_test {\n\tstatic_assert(ranges::same_as<ranges::common_type_t<int, int>, int>);\n\tstatic_assert(ranges::same_as<ranges::common_type_t<int, float, double>, double>);\n\n\tstatic_assert(ranges::common_with<int, int>);\n\tstatic_assert(ranges::common_with<int, double>);\n\tstatic_assert(ranges::common_with<double, int>);\n\tstatic_assert(ranges::common_with<double, double>);\n\tstatic_assert(!ranges::common_with<void, int>);\n\tstatic_assert(!ranges::common_with<int*, int>);\n\tstatic_assert(ranges::common_with<void*, int*>);\n\tstatic_assert(ranges::common_with<double, long long>);\n\tstatic_assert(ranges::common_with<void, void>);\n\n\tstruct B {};\n\tstruct C { C() = default; C(B) {} C(int) {} };\n\tstatic_assert(ranges::common_with<B, C>);\n\n\tstruct incomplete;\n\tstatic_assert(ranges::common_with<void*, incomplete*>);\n}\n\nnamespace {\n\tstruct A {\n\t\tA() = default;\n\t\tA(int) {}\n\t};\n\n\tenum class result {\n\t\texact, convertible, unrelated\n\t};\n\n\t// Concepts version\n\tresult f(A) {\n\t\tstd::cout << \"exactly A\\n\";\n\t\treturn result::exact;\n\t}\n\n\ttemplate<ranges::convertible_to<A> T>\n\tresult f(T) {\n\t\tstd::cout << \"Convertible to A\\n\";\n\t\treturn result::convertible;\n\t}\n\n\ttemplate<class T>\n\tresult f(T) {\n\t\tstd::cout << \"Nothing to do with A\\n\";\n\t\treturn result::unrelated;\n\t}\n} // unnamed namespace\n\nint main() {\n\tCHECK(f(A{}) == result::exact);\n\t{\n\t\tconst A a{};\n\t\tCHECK(f(a) == result::exact);\n\t}\n\tCHECK(f(42) == result::convertible);\n\tCHECK(f(\"foo\") == result::unrelated);\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/concepts/fundamental.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <cstddef>\n#include <stl2/detail/concepts/fundamental.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = std::experimental::ranges;\n\nstatic_assert(ranges::integral<int>);\nstatic_assert(!ranges::integral<double>);\nstatic_assert(ranges::integral<unsigned>);\nstatic_assert(!ranges::integral<void>);\nstatic_assert(ranges::integral<std::ptrdiff_t>);\nstatic_assert(ranges::integral<std::size_t>);\n\nstatic_assert(ranges::signed_integral<int>);\nstatic_assert(!ranges::signed_integral<double>);\nstatic_assert(!ranges::signed_integral<unsigned>);\nstatic_assert(!ranges::signed_integral<void>);\nstatic_assert(ranges::signed_integral<std::ptrdiff_t>);\nstatic_assert(!ranges::signed_integral<std::size_t>);\n\nstatic_assert(!ranges::unsigned_integral<int>);\nstatic_assert(!ranges::unsigned_integral<double>);\nstatic_assert(ranges::unsigned_integral<unsigned>);\nstatic_assert(!ranges::unsigned_integral<void>);\nstatic_assert(!ranges::unsigned_integral<std::ptrdiff_t>);\nstatic_assert(ranges::unsigned_integral<std::size_t>);\n\nnamespace scalar_types {\n\tenum class t {\n\t\tregular, scalar, arithmetic, floating_point,\n\t\tintegral, signed_integral, unsigned_integral, ull\n\t};\n\n\ttemplate<ranges::regular T>\n\tconstexpr t f(T) { return t::regular; }\n\ttemplate<ranges::ext::Scalar T>\n\tconstexpr t f(T) { return t::scalar; }\n\ttemplate<ranges::ext::Arithmetic T>\n\tconstexpr t f(T) { return t::arithmetic; }\n\ttemplate<ranges::floating_point T>\n\tconstexpr t f(T) { return t::floating_point; }\n\ttemplate<ranges::integral T>\n\tconstexpr t f(T) { return t::integral; }\n\ttemplate<ranges::signed_integral T>\n\tconstexpr t f(T) { return t::signed_integral; }\n\ttemplate<ranges::unsigned_integral T>\n\tconstexpr t f(T) { return t::unsigned_integral; }\n\tconstexpr t f(unsigned long long) { return t::ull; }\n\n\tvoid test() {\n\t\tCHECK(f(0.0f) == t::floating_point);\n\t\tCHECK(f(0.0) == t::floating_point);\n\t\tCHECK(f(0) == t::signed_integral);\n\t\tCHECK(f(0u) == t::unsigned_integral);\n\t\tCHECK(f(nullptr) == t::scalar);\n\t\tCHECK(f(0ull) == t::ull);\n\t\tCHECK((f('a') == t::signed_integral || f('a') == t::unsigned_integral));\n\t\t{\n\t\t\tint i;\n\t\t\tCHECK(f(&i) == t::scalar);\n\t\t}\n\t\t{\n\t\t\tstruct A { void foo() {} };\n\t\t\tCHECK(f(&A::foo) == t::scalar);\n\t\t}\n\t}\n} // namespace scalar_types\n\nint main() {\n\tscalar_types::test();\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/concepts/iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <array>\n#include <cstddef>\n#include <memory>\n#include <string>\n#include <type_traits>\n#include <valarray>\n#include <vector>\n#include <stl2/iterator.hpp>\n#include <stl2/detail/concepts/callable.hpp>\n#include <stl2/detail/concepts/core.hpp>\n\nnamespace ranges = std::experimental::ranges;\n\nnamespace associated_type_test {\n\tstruct A {\n\t\tusing value_type = int;\n\t\tint& operator*() const;\n\t};\n\tstruct B : A {\n\t\tusing value_type = double;\n\t};\n\n\ttemplate<class, class = void>\n\tconstexpr bool has_member_value_type = false;\n\ttemplate<class T>\n\tconstexpr bool has_member_value_type<T, std::void_t<typename T::value_type>> = true;\n\n\tstatic_assert(ranges::same_as<int&, ranges::iter_reference_t<int*>>);\n\tstatic_assert(ranges::same_as<int&, ranges::iter_reference_t<int[]>>);\n\tstatic_assert(ranges::same_as<int&, ranges::iter_reference_t<int[4]>>);\n\tstatic_assert(ranges::same_as<int&, ranges::iter_reference_t<A>>);\n\tstatic_assert(ranges::same_as<int&, ranges::iter_reference_t<B>>);\n\tstatic_assert(ranges::same_as<const int&, ranges::iter_reference_t<const int*>>);\n\n\tstatic_assert(ranges::same_as<int&&, ranges::iter_rvalue_reference_t<int*>>);\n\tstatic_assert(ranges::same_as<int&&, ranges::iter_rvalue_reference_t<int[]>>);\n\tstatic_assert(ranges::same_as<int&&, ranges::iter_rvalue_reference_t<int[4]>>);\n\tstatic_assert(ranges::same_as<int&&, ranges::iter_rvalue_reference_t<A>>);\n\tstatic_assert(ranges::same_as<int&&, ranges::iter_rvalue_reference_t<B>>);\n\tstatic_assert(ranges::same_as<const int&&, ranges::iter_rvalue_reference_t<const int*>>);\n\n\tstatic_assert(ranges::same_as<int, ranges::iter_value_t<int*>>);\n\tstatic_assert(ranges::same_as<int, ranges::iter_value_t<int[]>>);\n\tstatic_assert(ranges::same_as<int, ranges::iter_value_t<int[4]>>);\n\tstatic_assert(ranges::same_as<int, ranges::iter_value_t<A>>);\n\tstatic_assert(ranges::same_as<double, ranges::iter_value_t<B>>);\n\tstatic_assert(ranges::same_as<int, ranges::iter_value_t<const int*>>);\n\tstatic_assert(!has_member_value_type<ranges::readable_traits<void>>);\n\tstatic_assert(!has_member_value_type<ranges::readable_traits<void*>>);\n\tstatic_assert(ranges::same_as<int, ranges::iter_value_t<const int* const>>);\n\tstatic_assert(ranges::same_as<int, ranges::iter_value_t<const int[2]>>);\n\tstruct S { using value_type = int; using element_type = int const; };\n\t// ranges::readable_traits<S> // ill-formed, hard error\n\n\tstatic_assert(ranges::same_as<std::ptrdiff_t, ranges::iter_difference_t<int*>>);\n\tstatic_assert(ranges::same_as<std::ptrdiff_t, ranges::iter_difference_t<int[]>>);\n\tstatic_assert(ranges::same_as<std::ptrdiff_t, ranges::iter_difference_t<int[4]>>);\n\n\tstatic_assert(!meta::is_trait<ranges::incrementable_traits<void>>());\n\tstatic_assert(!meta::is_trait<ranges::incrementable_traits<void*>>());\n\n\tstatic_assert(ranges::same_as<int, ranges::iter_difference_t<int>>);\n\tstatic_assert(ranges::same_as<ranges::iterator_category_t<int*>, ranges::contiguous_iterator_tag>);\n\tstatic_assert(ranges::same_as<ranges::iterator_category_t<const int*>, ranges::contiguous_iterator_tag>);\n\n\ttemplate<class T>\n\tstruct derive_from : T {};\n\n\ttemplate<class Cat, class Value, class Distance = std::ptrdiff_t,\n\t\tclass Pointer = Value*, class Reference = Value&>\n\tstruct not_std_iterator {\n\t\tusing iterator_category = Cat;\n\t\tusing value_type = Value;\n\t\tusing difference_type = Distance;\n\t\tusing pointer = Pointer;\n\t\tusing reference = Reference;\n\t};\n\n\ttemplate<class T, bool Derive>\n\tusing iterator =\n\t\tnot_std_iterator<std::conditional_t<Derive, derive_from<T>, T>,\n\t\t\tstd::conditional_t<std::is_same_v<T, std::output_iterator_tag>, int, void>,\n\t\t\tstd::conditional_t<std::is_same_v<T, std::output_iterator_tag>, std::ptrdiff_t, void>,\n\t\t\tstd::conditional_t<std::is_same_v<T, std::output_iterator_tag>, int*, void>,\n\t\t\tstd::conditional_t<std::is_same_v<T, std::output_iterator_tag>, int&, void>>;\n\n\ttemplate<class T, bool B, class U>\n\tusing test = std::is_same<ranges::iterator_category_t<iterator<T, B>>, U>;\n\n\tstatic_assert(!meta::is_trait<ranges::iterator_category<void*>>());\n\tstatic_assert(!meta::is_trait<ranges::iterator_category<int(*)()>>());\n\tstatic_assert(!meta::is_trait<ranges::iterator_category<iterator<std::output_iterator_tag, false>>>());\n\tstatic_assert(!meta::is_trait<ranges::iterator_category<iterator<std::output_iterator_tag, true>>>());\n\n\tstatic_assert(test<std::input_iterator_tag, false, ranges::input_iterator_tag>());\n\tstatic_assert(test<std::forward_iterator_tag, false, ranges::forward_iterator_tag>());\n\tstatic_assert(test<std::bidirectional_iterator_tag, false, ranges::bidirectional_iterator_tag>());\n\tstatic_assert(test<std::random_access_iterator_tag, false, ranges::random_access_iterator_tag>());\n\n\tstatic_assert(test<std::input_iterator_tag, true, ranges::input_iterator_tag>());\n\tstatic_assert(test<std::forward_iterator_tag, true, ranges::forward_iterator_tag>());\n\tstatic_assert(test<std::bidirectional_iterator_tag, true, ranges::bidirectional_iterator_tag>());\n\tstatic_assert(test<std::random_access_iterator_tag, true, ranges::random_access_iterator_tag>());\n\n\tstruct foo {};\n\tstatic_assert(test<foo, false, foo>());\n\n#if STL2_HOOK_ITERATOR_TRAITS\n\t// Some sanity tests\n\tstruct my_wonky_tag : std::random_access_iterator_tag, ranges::random_access_iterator_tag {};\n\tstruct my_wonky_tag2 : std::input_iterator_tag, ranges::random_access_iterator_tag {};\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<my_wonky_tag, int>, my_wonky_tag>::value, \"\");\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<my_wonky_tag, int&>, my_wonky_tag>::value, \"\");\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<my_wonky_tag2, int>, my_wonky_tag2>::value, \"\");\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<my_wonky_tag2, int&>, my_wonky_tag2>::value, \"\");\n\tstruct my_wonky_tag3 : ranges::random_access_iterator_tag {};\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<my_wonky_tag3, int>, std::input_iterator_tag>::value, \"\");\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<my_wonky_tag3, int&>, std::random_access_iterator_tag>::value, \"\");\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<ranges::input_iterator_tag, int>, std::input_iterator_tag>::value, \"\");\n\tstatic_assert(std::is_same<ranges::detail::stl2_to_std_iterator_category<ranges::input_iterator_tag, int&>, std::input_iterator_tag>::value, \"\");\n#endif // STL2_HOOK_ITERATOR_TRAITS\n} // namespace associated_type_test\n\nnamespace readable_test {\n\tstruct A {\n\t\tint operator*() const;\n\t\tusing value_type = int;\n\t};\n\n\tstatic_assert(!ranges::readable<void>);\n\tstatic_assert(!ranges::readable<void*>);\n\tstatic_assert(ranges::readable<int*>);\n\tstatic_assert(ranges::readable<const int*>);\n\tstatic_assert(ranges::readable<A>);\n\tstatic_assert(ranges::same_as<ranges::iter_value_t<A>,int>);\n\n\tstruct MoveOnlyReadable {\n\t\tusing value_type = std::unique_ptr<int>;\n\t\tvalue_type operator*() const;\n\t};\n\n\tstatic_assert(ranges::readable<MoveOnlyReadable>);\n\n\tstruct ArrayReadable {\n\t\tusing value_type = int[2];\n\t\tvalue_type& operator*() const;\n\t};\n\n\tstatic_assert(ranges::readable<ArrayReadable>);\n\n\tstruct Abstract {\n\t\tvirtual void foo() = 0;\n\t};\n\tstruct AbstractReadable {\n\t\tusing value_type = Abstract;\n\t\tAbstract& operator*() const;\n\t};\n\n\tstatic_assert(ranges::readable<AbstractReadable>);\n}\n\nnamespace writable_test {\n\tstruct A {\n\t\tint& operator*() const;\n\t};\n\n\tstatic_assert(ranges::writable<std::unique_ptr<int>*, std::unique_ptr<int>&&>);\n\tstatic_assert(!ranges::writable<std::unique_ptr<int>*, std::unique_ptr<int>&>);\n\tstatic_assert(!ranges::writable<void, int>);\n\tstatic_assert(!ranges::writable<void*, void>);\n\tstatic_assert(ranges::writable<int*, int>);\n\tstatic_assert(ranges::writable<int*, int&>);\n\tstatic_assert(ranges::writable<int*, const int&>);\n\tstatic_assert(ranges::writable<int*, const int>);\n\tstatic_assert(!ranges::writable<const int*, int>);\n\tstatic_assert(ranges::writable<A, int>);\n\tstatic_assert(ranges::writable<A, const int&>);\n\tstatic_assert(ranges::writable<A, double>);\n\tstatic_assert(ranges::writable<A, const double&>);\n} // namespace writable_test\n\nstatic_assert(ranges::weakly_incrementable<int>);\nstatic_assert(ranges::weakly_incrementable<unsigned int>);\nstatic_assert(!ranges::weakly_incrementable<void>);\nstatic_assert(ranges::weakly_incrementable<int*>);\nstatic_assert(ranges::weakly_incrementable<const int*>);\n\nstatic_assert(ranges::incrementable<int>);\nstatic_assert(ranges::incrementable<unsigned int>);\nstatic_assert(!ranges::incrementable<void>);\nstatic_assert(ranges::incrementable<int*>);\nstatic_assert(ranges::incrementable<const int*>);\n\nnamespace iterator_sentinel_test {\n\tstruct A {\n\t\tusing difference_type = signed char;\n\t\tusing iterator_category = ranges::input_iterator_tag;\n\t\tusing value_type = double;\n\n\t\tA& operator++();\n\t\tA operator++(int);\n\t\tdouble operator*() const;\n\n\t\tbool operator == (const A&) const;\n\t\tbool operator != (const A&) const;\n\t};\n\n\tstatic_assert(ranges::input_or_output_iterator<int*>);\n\tstatic_assert(ranges::input_or_output_iterator<const int*>);\n\tstatic_assert(!ranges::input_or_output_iterator<void*>);\n\tstatic_assert(ranges::input_or_output_iterator<A>);\n\tstatic_assert(ranges::input_iterator<A>);\n\n\tstatic_assert(ranges::input_or_output_iterator<int*>);\n\tstatic_assert(ranges::sentinel_for<int*, int*>);\n\tstatic_assert(ranges::sentinel_for<const int*, const int*>);\n\tstatic_assert(ranges::sentinel_for<const int*, int*>);\n\tstatic_assert(!ranges::sentinel_for<void*, void*>);\n\tstatic_assert(ranges::sentinel_for<A, A>);\n} // namespace iterator_sentinel_test\n\nnamespace indirectly_callable_test {\n\tstatic_assert(ranges::ext::indirect_invocable<std::plus<int>, int*, int*>);\n}\n\nnamespace indirect_invoke_result_test {\n\ttemplate<class R, class... Args>\n\tusing fn_t = R(Args...);\n\tstatic_assert(ranges::same_as<ranges::indirect_result_t<fn_t<void, int>&, const int*>, void>);\n}\n\nnamespace contiguous_test {\n\ttemplate<class T>\n\tstruct fancy {\n\t\tusing iterator_category = std::random_access_iterator_tag;\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = std::remove_cv_t<T>;\n\t\tusing pointer = T*;\n\t\tusing reference = std::add_lvalue_reference_t<T>;\n\n\t\tstatic fancy pointer_to(T& t) { return fancy{std::addressof(t)}; }\n\n\t\tfancy() = default;\n\t\tfancy(std::nullptr_t) : ptr_{} {}\n\t\texplicit fancy(T* ptr) : ptr_{ptr} {}\n\n\t\texplicit operator bool() const { return ptr_ != nullptr; }\n\n\t\treference operator*() const { return *ptr_; }\n\t\tT* operator->() const { return ptr_; }\n\n\t\tfancy& operator++() { ++ptr_; return *this; }\n\t\tfancy operator++(int) { auto tmp = *this; ++*this; return tmp; }\n\t\tfancy& operator--() { --ptr_; return *this; }\n\t\tfancy operator--(int) { auto tmp = *this; --*this; return tmp; }\n\n\t\tfancy& operator+=(difference_type n) { ptr_ += n; return *this; }\n\t\tfancy operator+(difference_type n) const { return fancy{ptr_ + n}; }\n\t\tfriend fancy operator+(difference_type n, fancy x) { return x + n; }\n\t\tfancy& operator-=(difference_type n) { *this += -n; return *this; }\n\t\tfancy operator-(difference_type n) const { return fancy{ptr_ - n}; }\n\t\tdifference_type operator-(fancy x) const { return ptr_ - x.ptr_; }\n\n\t\tbool operator==(fancy x) const { return ptr_ == x.ptr_; }\n\t\tbool operator!=(fancy x) const { return !(*this == x); }\n\t\tbool operator< (fancy x) const { return ptr_ < x.ptr_; }\n\t\tbool operator> (fancy x) const { return x < *this; }\n\t\tbool operator<=(fancy x) const { return !(x < *this); }\n\t\tbool operator>=(fancy x) const { return !(*this < x); }\n\n\t\tT* ptr_;\n\t};\n\n\ttemplate<class T>\n\tstruct allocator {\n\t\tusing value_type = T;\n\t\tusing size_type = std::size_t;\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing reference = std::add_lvalue_reference_t<T>;\n\t\tusing const_reference = std::add_lvalue_reference_t<const T>;\n\t\tusing pointer = fancy<T>;\n\t\tusing const_pointer = fancy<const T>;\n\t\tusing void_pointer = fancy<void>;\n\t\tusing const_void_pointer = fancy<const void>;\n\n\t\ttemplate<class U> struct rebind {\n\t\t\tusing other = allocator<U>;\n\t\t};\n\n\t\tallocator() = default;\n\t\ttemplate<class U>\n\t\tallocator(const allocator<U>&);\n\n\t\tfancy<T> allocate(std::size_t);\n\t\tvoid deallocate(fancy<T>, std::size_t) noexcept;\n\n\t\ttemplate<class U>\n\t\tbool operator==(allocator<U>);\n\t\ttemplate<class U>\n\t\tbool operator!=(allocator<U>);\n\t};\n\n\tstatic_assert(ranges::contiguous_iterator<std::array<int, 42>::iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::array<int, 42>::const_iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::string::iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::string::const_iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::basic_string<char, std::char_traits<char>, allocator<char>>::iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::basic_string<char, std::char_traits<char>, allocator<char>>::const_iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::string_view::iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::string_view::const_iterator>);\n\tstatic_assert(ranges::contiguous_iterator<ranges::iterator_t<std::valarray<double>>>);\n\tstatic_assert(ranges::contiguous_iterator<ranges::iterator_t<const std::valarray<double>>>);\n\tstatic_assert(ranges::contiguous_iterator<std::vector<int>::iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::vector<int>::const_iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::vector<int, allocator<int>>::iterator>);\n\tstatic_assert(ranges::contiguous_iterator<std::vector<int, allocator<int>>::const_iterator>);\n}\n\nint main() {}\n"
  },
  {
    "path": "test/concepts/object.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/concepts/object.hpp>\n\nnamespace ranges = std::experimental::ranges;\n\nstruct copyable {};\n\nstruct moveonly {\n\tmoveonly() = default;\n\tmoveonly(moveonly&&) = default;\n\tmoveonly& operator=(moveonly&&) = default;\n};\n\nstruct copyonly {\n\tcopyonly() = default;\n\tcopyonly(const copyonly&) = default;\n\tcopyonly& operator=(const copyonly&) = default;\n\tcopyonly(copyonly&&) = delete;\n\tcopyonly& operator=(copyonly&&) = delete;\n};\n\nstruct nonmovable {\n\tnonmovable() = default;\n\tnonmovable(nonmovable&&) = delete;\n};\n\nstruct nondefaultconstructible {\n\tnondefaultconstructible(int) {}\n};\n\nstruct indestructible {\n\t~indestructible() = delete;\n};\n\nstruct throwing_destructor {\n\t~throwing_destructor() noexcept(false);\n};\n\nstruct explicit_default {\n\texplicit explicit_default() {}\n};\n\nstruct deleted_default {\n\tdeleted_default() = delete;\n};\n\nstruct explicit_move {\n\texplicit_move() = default;\n\texplicit explicit_move(explicit_move&&) = default;\n};\n\nstruct explicit_copy {\n\texplicit_copy() = default;\n\texplicit_copy(explicit_copy&&) = default;\n\texplicit explicit_copy(const explicit_copy&) = default;\n};\n\nstruct semiregular {};\n\nstruct regular {\n\tfriend constexpr bool operator==(const regular&, const regular&) {\n\t\treturn true;\n\t}\n\tfriend constexpr bool operator!=(const regular&, const regular&) {\n\t\treturn false;\n\t}\n};\n\nstruct XXX\n{\n\tXXX() = default;\n\tXXX(XXX&&) = delete;\n\texplicit XXX(int) {}\n};\n\nstatic_assert(ranges::destructible<int>);\nstatic_assert(ranges::destructible<const int>);\nstatic_assert(!ranges::destructible<void>);\nstatic_assert(ranges::destructible<int&>);\nstatic_assert(!ranges::destructible<void()>);\nstatic_assert(ranges::destructible<void(*)()>);\nstatic_assert(ranges::destructible<void(&)()>);\nstatic_assert(!ranges::destructible<int[]>);\nstatic_assert(ranges::destructible<int[2]>);\nstatic_assert(ranges::destructible<int(*)[2]>);\nstatic_assert(ranges::destructible<int(&)[2]>);\nstatic_assert(ranges::destructible<moveonly>);\nstatic_assert(ranges::destructible<nonmovable>);\nstatic_assert(!ranges::destructible<indestructible>);\nstatic_assert(!ranges::destructible<throwing_destructor>);\n\nstatic_assert(ranges::constructible_from<int>);\nstatic_assert(ranges::constructible_from<int const>);\nstatic_assert(!ranges::constructible_from<int const&>);\nstatic_assert(!ranges::constructible_from<int()>);\nstatic_assert(!ranges::constructible_from<int(&)()>);\nstatic_assert(!ranges::constructible_from<int[]>);\nstatic_assert(ranges::constructible_from<int[5]>);\nstatic_assert(!ranges::constructible_from<nondefaultconstructible>);\nstatic_assert(ranges::constructible_from<int const(&)[5], int(&)[5]>);\nstatic_assert(!ranges::constructible_from<int, int(&)[3]>);\n\nstatic_assert(ranges::constructible_from<int, int>);\nstatic_assert(ranges::constructible_from<int, int&>);\nstatic_assert(ranges::constructible_from<int, int&&>);\nstatic_assert(ranges::constructible_from<int, const int>);\nstatic_assert(ranges::constructible_from<int, const int&>);\nstatic_assert(ranges::constructible_from<int, const int&&>);\n\nstatic_assert(ranges::constructible_from<copyable, copyable>);\nstatic_assert(ranges::constructible_from<copyable, copyable&>);\nstatic_assert(ranges::constructible_from<copyable, copyable&&>);\nstatic_assert(ranges::constructible_from<copyable, const copyable>);\nstatic_assert(ranges::constructible_from<copyable, const copyable&>);\nstatic_assert(ranges::constructible_from<copyable, const copyable&&>);\n\nstatic_assert(!ranges::constructible_from<int&, int>);\nstatic_assert(ranges::constructible_from<int&, int&>);\nstatic_assert(!ranges::constructible_from<int&, int&&>);\nstatic_assert(!ranges::constructible_from<int&, const int>);\nstatic_assert(!ranges::constructible_from<int&, const int&>);\nstatic_assert(!ranges::constructible_from<int&, const int&&>);\n\nstatic_assert(ranges::constructible_from<const int&, int>);\nstatic_assert(ranges::constructible_from<const int&, int&>);\nstatic_assert(ranges::constructible_from<const int&, int&&>);\nstatic_assert(ranges::constructible_from<const int&, const int>);\nstatic_assert(ranges::constructible_from<const int&, const int&>);\nstatic_assert(ranges::constructible_from<const int&, const int&&>);\n\nstatic_assert(ranges::constructible_from<int&&, int>);\nstatic_assert(!ranges::constructible_from<int&&, int&>);\nstatic_assert(ranges::constructible_from<int&&, int&&>);\nstatic_assert(!ranges::constructible_from<int&&, const int>);\nstatic_assert(!ranges::constructible_from<int&&, const int&>);\nstatic_assert(!ranges::constructible_from<int&&, const int&&>);\n\nstatic_assert(ranges::constructible_from<const int&&, int>);\nstatic_assert(!ranges::constructible_from<const int&&, int&>);\nstatic_assert(ranges::constructible_from<const int&&, int&&>);\nstatic_assert(ranges::constructible_from<const int&&, const int>);\nstatic_assert(!ranges::constructible_from<const int&&, const int&>);\nstatic_assert(ranges::constructible_from<const int&&, const int&&>);\n\nstatic_assert(ranges::constructible_from<XXX, int>);\n\nstatic_assert(ranges::default_initializable<int>);\nstatic_assert(ranges::default_initializable<int const>);\nstatic_assert(!ranges::default_initializable<int&>);\nstatic_assert(!ranges::default_initializable<int const&>);\nstatic_assert(!ranges::default_initializable<int()>);\nstatic_assert(!ranges::default_initializable<int(&)()>);\nstatic_assert(ranges::default_initializable<double>);\nstatic_assert(!ranges::default_initializable<void>);\nstatic_assert(!ranges::default_initializable<int[]>);\nstatic_assert(ranges::default_initializable<int[2]>);\nstatic_assert(!ranges::default_initializable<nondefaultconstructible>);\n\nnamespace pathological_explicit_default_constructor {\n\tstruct S0 { explicit S0() = default; };\n\tstruct S1 { S0 x; };\n#if STL2_WORKAROUND_GCC_UNKNOWN0 || STL2_WORKAROUND_MSVC_830372\n\tstatic_assert(ranges::default_initializable<S1>);\n#else // ^^^ workaround / no workaround vvv\n\tstatic_assert(!ranges::default_initializable<S1>);\n#endif // STL2_WORKAROUND_GCC_UNKNOWN0\n}\n\nstatic_assert(ranges::default_initializable<explicit_move>);\nstatic_assert(ranges::default_initializable<explicit_copy>);\nstatic_assert(!ranges::default_initializable<deleted_default>);\n\nstatic_assert(!ranges::move_constructible<void>);\nstatic_assert(ranges::move_constructible<int>);\nstatic_assert(ranges::move_constructible<const int>);\nstatic_assert(!ranges::move_constructible<int[4]>);\nstatic_assert(!ranges::move_constructible<void()>);\nstatic_assert(ranges::move_constructible<int &>);\nstatic_assert(ranges::move_constructible<int &&>);\nstatic_assert(ranges::move_constructible<const int &>);\nstatic_assert(ranges::move_constructible<const int &&>);\n\nstatic_assert(ranges::constructible_from<moveonly, moveonly>);\nstatic_assert(ranges::move_constructible<copyable>);\nstatic_assert(ranges::move_constructible<moveonly>);\nstatic_assert(!ranges::move_constructible<nonmovable>);\nstatic_assert(!ranges::move_constructible<copyonly>);\nstatic_assert(!ranges::move_constructible<explicit_move>);\nstatic_assert(ranges::move_constructible<explicit_copy>);\n\nstatic_assert(ranges::move_constructible<nonmovable &>);\nstatic_assert(ranges::move_constructible<nonmovable &&>);\nstatic_assert(ranges::move_constructible<const nonmovable &>);\nstatic_assert(ranges::move_constructible<const nonmovable &&>);\n\nstatic_assert(!ranges::copy_constructible<void>);\nstatic_assert(ranges::copy_constructible<int>);\nstatic_assert(ranges::copy_constructible<const int>);\nstatic_assert(ranges::copy_constructible<int&>);\nstatic_assert(!ranges::copy_constructible<int&&>);\nstatic_assert(ranges::copy_constructible<const int&>);\nstatic_assert(!ranges::copy_constructible<const int&&>);\nstatic_assert(!ranges::copy_constructible<int[4]>);\nstatic_assert(!ranges::copy_constructible<void()>);\n\nstatic_assert(ranges::copy_constructible<copyable>);\nstatic_assert(!ranges::copy_constructible<moveonly>);\nstatic_assert(!ranges::copy_constructible<nonmovable>);\nstatic_assert(!ranges::copy_constructible<copyonly>);\nstatic_assert(!ranges::copy_constructible<explicit_move>);\nstatic_assert(!ranges::copy_constructible<explicit_copy>);\nstatic_assert(ranges::copy_constructible<nonmovable &>);\nstatic_assert(!ranges::copy_constructible<nonmovable &&>);\nstatic_assert(ranges::copy_constructible<const nonmovable &>);\nstatic_assert(!ranges::copy_constructible<const nonmovable &&>);\n\n#if STL2_WORKAROUND_MSVC_106654\n// j/k, there's no workaround\n#else // ^^^ \"workaround\" / no workaround vvv\n// https://github.com/ericniebler/stl2/issues/301\nstruct not_mutable_ref {\n\tnot_mutable_ref() = default;\n\tnot_mutable_ref(const not_mutable_ref&) = default;\n\tnot_mutable_ref(not_mutable_ref&&) = default;\n\tnot_mutable_ref(not_mutable_ref&) = delete;\n};\nstruct not_const_ref_ref {\n\tnot_const_ref_ref() = default;\n\tnot_const_ref_ref(const not_const_ref_ref&) = default;\n\tnot_const_ref_ref(not_const_ref_ref&&) = default;\n\tnot_const_ref_ref(const not_const_ref_ref&&) = delete;\n};\nstatic_assert(!ranges::copy_constructible<not_mutable_ref>);\nstatic_assert(!ranges::copy_constructible<not_const_ref_ref>);\n#endif // STL2_WORKAROUND_MSVC_106654\n\nstatic_assert(ranges::movable<int>);\nstatic_assert(!ranges::movable<const int>);\nstatic_assert(ranges::movable<double>);\nstatic_assert(!ranges::movable<void>);\nstatic_assert(ranges::movable<copyable>);\nstatic_assert(ranges::movable<moveonly>);\nstatic_assert(!ranges::movable<nonmovable>);\nstatic_assert(!ranges::movable<copyonly>);\n\nstatic_assert(ranges::copyable<int>);\nstatic_assert(!ranges::copyable<const int>);\nstatic_assert(ranges::copyable<double>);\nstatic_assert(!ranges::copyable<void>);\nstatic_assert(ranges::copyable<copyable>);\nstatic_assert(!ranges::copyable<moveonly>);\nstatic_assert(!ranges::copyable<nonmovable>);\nstatic_assert(!ranges::copyable<copyonly>);\n\nstatic_assert(ranges::semiregular<int>);\nstatic_assert(ranges::semiregular<double>);\nstatic_assert(!ranges::semiregular<void>);\nstatic_assert(!ranges::semiregular<int&>);\nstatic_assert(ranges::semiregular<semiregular>);\nstatic_assert(ranges::semiregular<regular>);\nstatic_assert(ranges::semiregular<copyable>);\nstatic_assert(!ranges::semiregular<moveonly>);\nstatic_assert(!ranges::semiregular<nonmovable>);\nstatic_assert(!ranges::semiregular<copyonly>);\nstatic_assert(!ranges::semiregular<explicit_move>);\nstatic_assert(!ranges::semiregular<explicit_copy>);\n\nstatic_assert(ranges::regular<int>);\nstatic_assert(ranges::regular<double>);\nstatic_assert(!ranges::regular<void>);\nstatic_assert(!ranges::regular<int&>);\nstatic_assert(!ranges::regular<semiregular>);\nstatic_assert(ranges::regular<regular>);\nstatic_assert(!ranges::regular<copyable>);\nstatic_assert(!ranges::regular<moveonly>);\nstatic_assert(!ranges::regular<nonmovable>);\nstatic_assert(!ranges::regular<copyonly>);\nstatic_assert(!ranges::regular<explicit_move>);\nstatic_assert(!ranges::regular<explicit_copy>);\n\nstatic_assert(ranges::constructible_from<std::initializer_list<int>>);\nstatic_assert(ranges::default_initializable<std::initializer_list<int>>);\n\nstatic_assert(ranges::constructible_from<int*>);\nstatic_assert(ranges::default_initializable<int*>);\n\n// https://github.com/ericniebler/stl2/issues/301\nstatic_assert(!ranges::constructible_from<int&, long&>);\n\n// https://github.com/ericniebler/stl2/issues/310\nstatic_assert(!ranges::movable<int&&>);\n\nint main() {}\n"
  },
  {
    "path": "test/concepts/range.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <set>\n#include <unordered_set>\n#include <vector>\n#include <stl2/detail/range/access.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = std::experimental::ranges;\n\ntemplate<bool allow_nonconst, bool allow_const, bool allow_size>\nstruct arbitrary_range {\n\tint* begin() requires allow_nonconst;\n\tint* end() requires allow_nonconst;\n\tconst int* begin() const requires allow_const;\n\tconst int* end() const requires allow_const;\n\n\tunsigned char size() const requires allow_size;\n};\n\ntemplate<class>\nconstexpr bool always_false = false;\n\nusing mutable_unsized_range = arbitrary_range<true, true, false>;\nusing mutable_only_no_size_range = arbitrary_range<true, false, false>;\nusing immutable_unsized_range = arbitrary_range<false, true, false>;\nusing mutable_sized_range = arbitrary_range<true, true, true>;\nusing mutable_only_sized_range = arbitrary_range<true, false, true>;\nusing immutable_sized_range = arbitrary_range<false, true, true>;\n\n// size() launches the missiles.\ntemplate<class Base>\nstruct bad_sized_range : Base {\n\t[[noreturn]] int size() const {\n\t\tstatic_assert(always_false<Base>);\n\t}\n\t[[noreturn]] friend int size(const bad_sized_range&) {\n\t\tstatic_assert(always_false<Base>);\n\t}\n};\n\nusing mutable_badsized_range = bad_sized_range<mutable_sized_range>;\nusing mutable_only_badsized_range = bad_sized_range<mutable_only_sized_range>;\nusing immutable_badsized_range = bad_sized_range<immutable_sized_range>;\n\nnamespace std::experimental::ranges {\n\ttemplate<class Base>\n\tconstexpr bool disable_sized_range<bad_sized_range<Base>> = true;\n} // namespace std::experimental::ranges\n\nstruct strange_view\n{\n\tstd::vector<int>::iterator begin();\n\tstd::vector<int>::const_iterator begin() const;\n\n\tstd::vector<int>::iterator end();\n\tstd::vector<int>::const_iterator end() const;\n};\n\nstruct strange_view2 : strange_view, ranges::view_base {};\nstruct strange_view3 : strange_view2 {};\n\nnamespace std::experimental::ranges {\n\ttemplate<>\n\tinline constexpr bool enable_view<strange_view> = true;\n\ttemplate<>\n\tinline constexpr bool enable_view<strange_view3> = false;\n} // namespace std::experimental::ranges\n\nvoid ridiculously_exhaustive_range_property_test() {\n\tstatic_assert(!ranges::range<void>);\n\tstatic_assert(!ranges::sized_range<void>);\n\tstatic_assert(!ranges::_ContainerLike<void>);\n\tstatic_assert(!ranges::view<void>);\n\n\tusing I = int*;\n\tusing CI = const int*;\n\n\tstatic_assert(ranges::input_or_output_iterator<I>);\n\tstatic_assert(ranges::input_or_output_iterator<CI>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<int[2]>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<int[2]>, I>);\n\tstatic_assert(ranges::range<int[2]>);\n\tstatic_assert(ranges::sized_range<int[2]>);\n\tstatic_assert(ranges::_ContainerLike<int[2]>);\n\tstatic_assert(!ranges::view<int[2]>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<int(&)[2]>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<int(&)[2]>, I>);\n\tstatic_assert(ranges::range<int(&)[2]>);\n\tstatic_assert(ranges::sized_range<int(&)[2]>);\n\tstatic_assert(!ranges::_ContainerLike<int(&)[2]>);\n\tstatic_assert(!ranges::view<int(&)[2]>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const int[2]>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const int[2]>, CI>);\n\tstatic_assert(ranges::range<const int[2]>);\n\tstatic_assert(ranges::sized_range<const int[2]>);\n\tstatic_assert(!ranges::_ContainerLike<const int[2]>);\n\tstatic_assert(!ranges::view<const int[2]>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const int(&)[2]>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const int(&)[2]>, CI>);\n\tstatic_assert(ranges::range<const int(&)[2]>);\n\tstatic_assert(ranges::sized_range<const int(&)[2]>);\n\tstatic_assert(!ranges::_ContainerLike<const int(&)[2]>);\n\tstatic_assert(!ranges::view<const int(&)[2]>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_unsized_range>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_unsized_range>, I>);\n\tstatic_assert(ranges::range<mutable_unsized_range>);\n\tstatic_assert(ranges::sized_range<mutable_unsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_unsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(ranges::_ContainerLike<mutable_unsized_range>);\n\tstatic_assert(!ranges::view<mutable_unsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_unsized_range&>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_unsized_range&>, I>);\n\tstatic_assert(ranges::range<mutable_unsized_range&>);\n\tstatic_assert(ranges::sized_range<mutable_unsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_unsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_unsized_range&>);\n\tstatic_assert(!ranges::view<mutable_unsized_range&>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const mutable_unsized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const mutable_unsized_range>, CI>);\n\tstatic_assert(ranges::range<const mutable_unsized_range>);\n\tstatic_assert(ranges::sized_range<const mutable_unsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const mutable_unsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_unsized_range>);\n\tstatic_assert(!ranges::view<const mutable_unsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const mutable_unsized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const mutable_unsized_range&>, CI>);\n\tstatic_assert(ranges::range<const mutable_unsized_range&>);\n\tstatic_assert(ranges::sized_range<const mutable_unsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const mutable_unsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_unsized_range&>);\n\tstatic_assert(!ranges::view<const mutable_unsized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_only_no_size_range>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_only_no_size_range>, I>);\n\tstatic_assert(ranges::range<mutable_only_no_size_range>);\n\tstatic_assert(ranges::sized_range<mutable_only_no_size_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_only_no_size_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_only_no_size_range>);\n\tstatic_assert(ranges::view<mutable_only_no_size_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_only_no_size_range&>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_only_no_size_range&>, I>);\n\tstatic_assert(ranges::range<mutable_only_no_size_range&>);\n\tstatic_assert(ranges::sized_range<mutable_only_no_size_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_only_no_size_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_only_no_size_range&>);\n\tstatic_assert(!ranges::view<mutable_only_no_size_range&>);\n\n\tstatic_assert(!ranges::range<const mutable_only_no_size_range>);\n\tstatic_assert(!ranges::sized_range<const mutable_only_no_size_range>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_only_no_size_range>);\n\tstatic_assert(!ranges::view<const mutable_only_no_size_range>);\n\n\tstatic_assert(!ranges::range<const mutable_only_no_size_range&>);\n\tstatic_assert(!ranges::sized_range<const mutable_only_no_size_range&>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_only_no_size_range&>);\n\tstatic_assert(!ranges::view<const mutable_only_no_size_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<immutable_unsized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<immutable_unsized_range>, CI>);\n\tstatic_assert(ranges::range<immutable_unsized_range>);\n\tstatic_assert(ranges::sized_range<immutable_unsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<immutable_unsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<immutable_unsized_range>);\n\tstatic_assert(ranges::view<immutable_unsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<immutable_unsized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<immutable_unsized_range&>, CI>);\n\tstatic_assert(ranges::range<immutable_unsized_range&>);\n\tstatic_assert(ranges::sized_range<immutable_unsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<immutable_unsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<immutable_unsized_range&>);\n\tstatic_assert(!ranges::view<immutable_unsized_range&>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const immutable_unsized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const immutable_unsized_range>, CI>);\n\tstatic_assert(ranges::range<const immutable_unsized_range>);\n\tstatic_assert(ranges::sized_range<const immutable_unsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const immutable_unsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const immutable_unsized_range>);\n\tstatic_assert(!ranges::view<const immutable_unsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const immutable_unsized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const immutable_unsized_range&>, CI>);\n\tstatic_assert(ranges::range<const immutable_unsized_range&>);\n\tstatic_assert(ranges::sized_range<const immutable_unsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const immutable_unsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const immutable_unsized_range&>);\n\tstatic_assert(!ranges::view<const immutable_unsized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_sized_range>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_sized_range>, I>);\n\tstatic_assert(ranges::range<mutable_sized_range>);\n\tstatic_assert(ranges::sized_range<mutable_sized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_sized_range>())), unsigned char>);\n\tstatic_assert(ranges::_ContainerLike<mutable_sized_range>);\n\tstatic_assert(!ranges::view<mutable_sized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_sized_range&>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_sized_range&>, I>);\n\tstatic_assert(ranges::range<mutable_sized_range&>);\n\tstatic_assert(ranges::sized_range<mutable_sized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_sized_range&>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_sized_range&>);\n\tstatic_assert(!ranges::view<mutable_sized_range&>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const mutable_sized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const mutable_sized_range>, CI>);\n\tstatic_assert(ranges::range<const mutable_sized_range>);\n\tstatic_assert(ranges::sized_range<const mutable_sized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const mutable_sized_range>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_sized_range>);\n\tstatic_assert(!ranges::view<const mutable_sized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const mutable_sized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const mutable_sized_range&>, CI>);\n\tstatic_assert(ranges::range<const mutable_sized_range&>);\n\tstatic_assert(ranges::sized_range<const mutable_sized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const mutable_sized_range&>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_sized_range&>);\n\tstatic_assert(!ranges::view<const mutable_sized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_only_sized_range>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_only_sized_range>, I>);\n\tstatic_assert(ranges::range<mutable_only_sized_range>);\n\tstatic_assert(ranges::sized_range<mutable_only_sized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_only_sized_range>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_only_sized_range>);\n\tstatic_assert(ranges::view<mutable_only_sized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_only_sized_range&>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_only_sized_range&>, I>);\n\tstatic_assert(ranges::range<mutable_only_sized_range&>);\n\tstatic_assert(ranges::sized_range<mutable_only_sized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_only_sized_range&>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_only_sized_range&>);\n\tstatic_assert(!ranges::view<mutable_only_sized_range&>);\n\n\tstatic_assert(!ranges::range<const mutable_only_sized_range>);\n\tstatic_assert(!ranges::sized_range<const mutable_only_sized_range>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_only_sized_range>);\n\tstatic_assert(!ranges::view<const mutable_only_sized_range>);\n\n\tstatic_assert(!ranges::range<const mutable_only_sized_range&>);\n\tstatic_assert(!ranges::sized_range<const mutable_only_sized_range&>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_only_sized_range&>);\n\tstatic_assert(!ranges::view<const mutable_only_sized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<immutable_sized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<immutable_sized_range>, CI>);\n\tstatic_assert(ranges::range<immutable_sized_range>);\n\tstatic_assert(ranges::sized_range<immutable_sized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<immutable_sized_range>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<immutable_sized_range>);\n\tstatic_assert(ranges::view<immutable_sized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<immutable_sized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<immutable_sized_range&>, CI>);\n\tstatic_assert(ranges::range<immutable_sized_range&>);\n\tstatic_assert(ranges::sized_range<immutable_sized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<immutable_sized_range&>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<immutable_sized_range&>);\n\tstatic_assert(!ranges::view<immutable_sized_range&>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const immutable_sized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const immutable_sized_range>, CI>);\n\tstatic_assert(ranges::range<const immutable_sized_range>);\n\tstatic_assert(ranges::sized_range<const immutable_sized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const immutable_sized_range>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<const immutable_sized_range>);\n\tstatic_assert(!ranges::view<const immutable_sized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const immutable_sized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const immutable_sized_range&>, CI>);\n\tstatic_assert(ranges::range<const immutable_sized_range&>);\n\tstatic_assert(ranges::sized_range<const immutable_sized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const immutable_sized_range&>())), unsigned char>);\n\tstatic_assert(!ranges::_ContainerLike<const immutable_sized_range&>);\n\tstatic_assert(!ranges::view<const immutable_sized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_badsized_range>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_badsized_range>, I>);\n\tstatic_assert(ranges::range<mutable_badsized_range>);\n\tstatic_assert(ranges::sized_range<mutable_badsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_badsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(ranges::_ContainerLike<mutable_badsized_range>);\n\tstatic_assert(!ranges::view<mutable_badsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_badsized_range&>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_badsized_range&>, I>);\n\tstatic_assert(ranges::range<mutable_badsized_range&>);\n\tstatic_assert(ranges::sized_range<mutable_badsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_badsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_badsized_range&>);\n\tstatic_assert(!ranges::view<mutable_badsized_range&>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const mutable_badsized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const mutable_badsized_range>, CI>);\n\tstatic_assert(ranges::range<const mutable_badsized_range>);\n\tstatic_assert(ranges::sized_range<const mutable_badsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const mutable_badsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_badsized_range>);\n\tstatic_assert(!ranges::view<const mutable_badsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const mutable_badsized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const mutable_badsized_range&>, CI>);\n\tstatic_assert(ranges::range<const mutable_badsized_range&>);\n\tstatic_assert(ranges::sized_range<const mutable_badsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const mutable_badsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_badsized_range&>);\n\tstatic_assert(!ranges::view<const mutable_badsized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_only_badsized_range>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_only_badsized_range>, I>);\n\tstatic_assert(ranges::range<mutable_only_badsized_range>);\n\tstatic_assert(ranges::sized_range<mutable_only_badsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_only_badsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_only_badsized_range>);\n\tstatic_assert(ranges::view<mutable_only_badsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<mutable_only_badsized_range&>, I>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<mutable_only_badsized_range&>, I>);\n\tstatic_assert(ranges::range<mutable_only_badsized_range&>);\n\tstatic_assert(ranges::sized_range<mutable_only_badsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<mutable_only_badsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<mutable_only_badsized_range&>);\n\tstatic_assert(!ranges::view<mutable_only_badsized_range&>);\n\n\tstatic_assert(!ranges::range<const mutable_only_badsized_range>);\n\tstatic_assert(!ranges::sized_range<const mutable_only_badsized_range>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_only_badsized_range>);\n\tstatic_assert(!ranges::view<const mutable_only_badsized_range>);\n\n\tstatic_assert(!ranges::range<const mutable_only_badsized_range&>);\n\tstatic_assert(!ranges::sized_range<const mutable_only_badsized_range&>);\n\tstatic_assert(!ranges::_ContainerLike<const mutable_only_badsized_range&>);\n\tstatic_assert(!ranges::view<const mutable_only_badsized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<immutable_badsized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<immutable_badsized_range>, CI>);\n\tstatic_assert(ranges::range<immutable_badsized_range>);\n\tstatic_assert(ranges::sized_range<immutable_badsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<immutable_badsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<immutable_badsized_range>);\n\tstatic_assert(ranges::view<immutable_badsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<immutable_badsized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<immutable_badsized_range&>, CI>);\n\tstatic_assert(ranges::range<immutable_badsized_range&>);\n\tstatic_assert(ranges::sized_range<immutable_badsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<immutable_badsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<immutable_badsized_range&>);\n\tstatic_assert(!ranges::view<immutable_badsized_range&>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const immutable_badsized_range>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const immutable_badsized_range>, CI>);\n\tstatic_assert(ranges::range<const immutable_badsized_range>);\n\tstatic_assert(ranges::sized_range<const immutable_badsized_range>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const immutable_badsized_range>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const immutable_badsized_range>);\n\tstatic_assert(!ranges::view<const immutable_badsized_range>);\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<const immutable_badsized_range&>, CI>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<const immutable_badsized_range&>, CI>);\n\tstatic_assert(ranges::range<const immutable_badsized_range&>);\n\tstatic_assert(ranges::sized_range<const immutable_badsized_range&>);\n\tstatic_assert(ranges::same_as<decltype(ranges::size(std::declval<const immutable_badsized_range&>())), std::ptrdiff_t>);\n\tstatic_assert(!ranges::_ContainerLike<const immutable_badsized_range&>);\n\tstatic_assert(!ranges::view<const immutable_badsized_range&>);\n\n\n\tstatic_assert(ranges::same_as<ranges::iterator_t<std::vector<int>>, std::vector<int>::iterator>);\n\tstatic_assert(ranges::same_as<ranges::sentinel_t<std::vector<int>>, std::vector<int>::iterator>);\n\tstatic_assert(ranges::range<std::vector<int>>);\n\tstatic_assert(ranges::sized_range<std::vector<int>>);\n\tstatic_assert(ranges::_ContainerLike<std::vector<int>>);\n\tstatic_assert(!ranges::view<std::vector<int>>);\n\n\n\tstatic_assert(ranges::range<strange_view>);\n\tstatic_assert(ranges::range<strange_view&>);\n\tstatic_assert(ranges::view<strange_view>);\n\tstatic_assert(!ranges::view<strange_view&>);\n\tstatic_assert(!ranges::view<const strange_view>);\n\n\tstatic_assert(ranges::range<strange_view2>);\n\tstatic_assert(ranges::range<strange_view2&>);\n\tstatic_assert(ranges::view<strange_view2>);\n\tstatic_assert(!ranges::view<strange_view2&>);\n\tstatic_assert(!ranges::view<const strange_view2>);\n\n\tstatic_assert(ranges::range<strange_view3>);\n\tstatic_assert(ranges::range<strange_view3&>);\n\tstatic_assert(!ranges::view<strange_view3>);\n\tstatic_assert(!ranges::view<strange_view3&>);\n\tstatic_assert(!ranges::view<const strange_view3>);\n}\n\ntemplate<ranges::input_iterator I, ranges::sentinel_for<I> S>\nI complicated_algorithm(I i, S s) {\n\tstatic constexpr bool output = false;\n\tif (output) std::cout << '{';\n\tif (i != s) {\n\t\tif (output) std::cout << *i;\n\t\twhile (++i != s) {\n\t\t\tif (output) std::cout << \", \" << *i;\n\t\t}\n\t}\n\tif (output) std::cout << \"}\\n\";\n\treturn i;\n}\n\ntemplate<ranges::input_range R>\nranges::iterator_t<R> complicated_algorithm(R&& r) {\n\treturn complicated_algorithm(ranges::begin(r), ranges::end(r));\n}\n\ntemplate<class T>\nstruct array_view {\n\tT* first_;\n\tstd::size_t n_;\n\n\tarray_view() = default;\n\ttemplate<std::size_t N>\n\tarray_view(T (&a)[N]) : first_{a}, n_{N} {}\n\n\tauto begin() const { return first_; }\n\tauto end() const { return first_ + n_; }\n\tauto size() const { return n_; }\n};\n\nvoid complicated_algorithm_test() {\n\tstatic int some_ints[] = {2, 3, 5, 7};\n\tstatic_assert(ranges::range<decltype(some_ints)>);\n\tstatic_assert(ranges::sized_range<decltype(some_ints)>);\n\tstatic_assert(ranges::_ContainerLike<decltype(some_ints)>);\n\tstatic_assert(!ranges::view<decltype(some_ints)>);\n\tCHECK(complicated_algorithm(some_ints) == ranges::end(some_ints));\n\tstatic_assert(ranges::range<array_view<int>>);\n\tstatic_assert(ranges::sized_range<array_view<int>>);\n\tstatic_assert(!ranges::_ContainerLike<array_view<int>>);\n\tstatic_assert(ranges::view<array_view<int>>);\n\tCHECK(complicated_algorithm(array_view<int>{some_ints}) == ranges::end(some_ints));\n}\n\nint main() {\n\tridiculously_exhaustive_range_property_test();\n\tcomplicated_algorithm_test();\n\n\t{\n\t\tusing T = int[2];\n\t\tstatic_assert(ranges::common_range<T>);\n\t\tstatic_assert(ranges::output_range<T, int>);\n\t\tstatic_assert(ranges::output_range<T, const int&>);\n\t\tstatic_assert(ranges::input_range<T>);\n\t\tstatic_assert(ranges::forward_range<T>);\n\t\tstatic_assert(ranges::bidirectional_range<T>);\n\t\tstatic_assert(ranges::random_access_range<T>);\n\t\tstatic_assert(ranges::contiguous_range<T>);\n\t}\n\n\tstatic_assert(!ranges::view<std::vector<int>>);\n\tstatic_assert(!ranges::view<std::set<int>>);\n\tstatic_assert(!ranges::view<std::multiset<int>>);\n\tstatic_assert(!ranges::view<std::unordered_set<int>>);\n\tstatic_assert(!ranges::view<std::unordered_multiset<int>>);\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/concepts/swap.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <cstddef>\n#include <stl2/detail/concepts/object.hpp>\n#include <stl2/utility.hpp>\n#include \"../simple_test.hpp\"\n\nusing namespace std::experimental::ranges;\nusing ext::is_nothrow_swappable_v;\n\nnamespace swappable_test {\n\tstatic_assert(swappable<int>);\n\tstatic_assert(swappable_with<int&, int&>);\n\tstatic_assert(swappable<int[4]>);\n\tstatic_assert(swappable_with<int(&)[4], int(&)[4]>);\n\tstatic_assert(!swappable_with<int, int>);\n\tstatic_assert(!swappable_with<int&, double&>);\n\tstatic_assert(!swappable_with<int(&)[4], bool(&)[4]>);\n\tstatic_assert(!swappable<int[]>);\n\tstatic_assert(!swappable<int[][4]>);\n\n\tstatic_assert(noexcept(swap(std::declval<int&>(), std::declval<int&>())));\n\tstatic_assert(is_nothrow_swappable_v<int&, int&>);\n\tstatic_assert(is_nothrow_swappable_v<int(&)[42], int(&)[42]>);\n\n\tstatic_assert(swappable<int[3][4]>);\n\tstatic_assert(swappable_with<int(&)[3][4], int(&)[3][4]>);\n\tstatic_assert(swappable<int[3][4][1][2]>);\n\tstatic_assert(swappable_with<int(&)[3][4][1][2], int(&)[3][4][1][2]>);\n\tstatic_assert(!swappable_with<int(&)[3][4][1][2], int(&)[4][4][1][2]>);\n\tstatic_assert(is_nothrow_swappable_v<int(&)[6][7], int(&)[6][7]>);\n\n\tstruct unswappable : std::string { // Has std:: as an associated namespace\n\t\tunswappable() = default;\n\t\tunswappable(const unswappable&) = delete;\n\t\tunswappable(unswappable&&) = delete;\n\t};\n\tstatic_assert(!swappable_with<unswappable&, unswappable&>);\n\tnamespace __constrained_swappable {\n\t\t// Has a constrained swap findable via ADL:\n\t\tstruct constrained_swappable {\n\t\t\tconstrained_swappable() = default;\n\t\t\tconstrained_swappable(const constrained_swappable&) = default;\n\t\t\tconstrained_swappable(constrained_swappable&&) = default;\n\t\t};\n\t\ttemplate<class T>\n\t\tMETA_CONCEPT ConstrainedSwappable = same_as<T, constrained_swappable>;\n\t\ttemplate<ConstrainedSwappable T, ConstrainedSwappable U>\n\t\tvoid swap(T&, U&) {}\n\t\ttemplate<ConstrainedSwappable T>\n\t\tvoid swap(T &, T &) {}\n\t}\n\tusing __constrained_swappable::constrained_swappable;\n\tstatic_assert(swappable_with<constrained_swappable&, constrained_swappable&>);\n\tstatic_assert(!swappable_with<const volatile constrained_swappable&, const volatile constrained_swappable&>);\n\n\tnamespace {\n\t\tstruct A {\n\t\t\tA() = default;\n\t\t\tA(A&&) = delete;\n\t\t\tA& operator=(A&&) = delete;\n\t\t\tfriend void swap(A&, A&) noexcept {}\n\t\t};\n\n\t\tstatic_assert(swappable<A>);\n\t\tstatic_assert(noexcept(swap(std::declval<A&>(), std::declval<A&>())));\n\t\tstatic_assert(is_nothrow_swappable_v<A&, A&>);\n\t}\n\n\tnamespace {\n\t\tstruct B {\n\t\t\tfriend void swap(B&, B&) {}\n\t\t};\n\n\t\tstatic_assert(swappable<B>);\n\t\tstatic_assert(!noexcept(swap(std::declval<B&>(), std::declval<B&>())));\n\t\tstatic_assert(!is_nothrow_swappable_v<B&, B&>);\n\t}\n} // namespace swappable_test\n\nnamespace example {\n\ttemplate<class T, ranges::swappable_with<T> U>\n\tvoid value_swap(T&& t, U&& u) {\n\t\tranges::swap(std::forward<T>(t), std::forward<U>(u));\n\t}\n\n\ttemplate<ranges::swappable T>\n\tvoid lv_swap(T& t1, T& t2) {\n\t\tranges::swap(t1, t2);\n\t}\n\n\tnamespace N {\n\t\tstruct A { int m; };\n\t\tstruct Proxy {\n\t\t\tA* a;\n\n\t\t\tProxy(A& a) : a{&a} {}\n\n\t\t\tfriend void swap(Proxy&& x, Proxy&& y) {\n\t\t\t\tranges::swap(*x.a, *y.a);\n\t\t\t}\n\t\t};\n\t\tProxy proxy(A& a) { return Proxy(a); }\n\t}\n\n\tvoid test() {\n\t\tint i = 1, j = 2;\n\t\tlv_swap(i, j);\n\t\tCHECK(i == 2);\n\t\tCHECK(j == 1);\n\n\t\tN::A a1 = { 5 }, a2 = { -5 };\n\t\tvalue_swap(a1, proxy(a2));\n\t\tCHECK(a1.m == -5);\n\t\tCHECK(a2.m == 5);\n\n\t\t// Additional checks for paths not exercised by the example\n\t\tvalue_swap(proxy(a1), a2);\n\t\tCHECK(a1.m == 5);\n\t\tCHECK(a2.m == -5);\n\n\t\tvalue_swap(proxy(a1), proxy(a2));\n\t\tCHECK(a1.m == -5);\n\t\tCHECK(a2.m == 5);\n\n\t\tN::Proxy p1{a1}, p2{a2};\n\t\tranges::swap(p1, p2);\n\t\tCHECK(a1.m == -5);\n\t\tCHECK(a2.m == 5);\n\t\tCHECK(p1.a == &a2);\n\t\tCHECK(p2.a == &a1);\n\t}\n}\n\nnamespace union_customizable {\n\tunion U {\n\t\tint i = 42;\n\t\tdouble d;\n\t\tU() = default;\n\t\tU(U&&) = delete;\n\t};\n\n\tint count = 0;\n\n\tvoid swap(U&, U&) {\n\t\t++count;\n\t}\n\n\tvoid test() {\n\t\tstatic_assert(swappable<U>);\n\t\tU u0, u1;\n\t\tCHECK(count == 0);\n\t\tranges::swap(u0, u1);\n\t\tCHECK(count == 1);\n\t}\n} // namespace union_customizable\n\nint main() {\n\t{\n\t\tint a[2][2] = {{0, 1}, {2, 3}};\n\t\tint b[2][2] = {{4, 5}, {6, 7}};\n\n\t\tstatic_assert(swappable_with<decltype((a)),decltype((b))>);\n\t\tswap(a, b);\n\t\tstatic_assert(noexcept(swap(a, b)));\n\n\t\tCHECK(a[0][0] == 4);\n\t\tCHECK(a[0][1] == 5);\n\t\tCHECK(a[1][0] == 6);\n\t\tCHECK(a[1][1] == 7);\n\n\t\tCHECK(b[0][0] == 0);\n\t\tCHECK(b[0][1] == 1);\n\t\tCHECK(b[1][0] == 2);\n\t\tCHECK(b[1][1] == 3);\n\t}\n\n\texample::test();\n\tunion_customizable::test();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/detail/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_stl2_test(detail.temporary_vector temporary_vector temporary_vector.cpp)\nadd_stl2_test(detail.raw_ptr raw_ptr raw_ptr.cpp)\n"
  },
  {
    "path": "test/detail/raw_ptr.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/detail/concepts/object.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nusing ranges::detail::raw_ptr;\n\nstruct A { int i; };\nstruct B : A { int j; };\n\nint main() {\n\tusing RA = raw_ptr<A>;\n\tusing RB = raw_ptr<B>;\n\n\tstatic_assert(ranges::regular<RA>);\n\tstatic_assert(ranges::totally_ordered<RA>);\n\tstatic_assert(ranges::regular<RB>);\n\tstatic_assert(ranges::totally_ordered<RB>);\n\n\tCHECK(RA{} == RA{});\n\tCHECK(!(RA{} != RA{}));\n\tCHECK(RA{} == RB{});\n\tCHECK(!(RA{} != RB{}));\n\n\tRA ra{RB{}};\n\tCHECK(ra == nullptr);\n\tra = RB{};\n\tCHECK(ra == nullptr);\n\n\tA a{42};\n\tra = &a;\n\tCHECK(ra == &a);\n\tCHECK(ra->i == 42);\n\tB b;\n\tb.i = 13;\n\tb.j = 42;\n\tra = &b;\n\tCHECK(ra == &b);\n\tCHECK(ra->i == 13);\n\n\tB array[4]{};\n\tRA r0 = &array[0];\n\tRA r1 = &array[1];\n\tCHECK(r0 != r1);\n\tCHECK(r0 < r1);\n\tCHECK(r0 <= r1);\n\tCHECK(r1 > r0);\n\tCHECK(r1 >= r0);\n\n\tCHECK(r0);\n\tCHECK(!!r1);\n\tCHECK((r0 ? true : false));\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/detail/temporary_vector.cpp",
    "content": "#include <stl2/detail/temporary_vector.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nusing ranges::detail::temporary_buffer;\nusing ranges::detail::temporary_vector;\n\nnamespace {\n\ttemplate<std::size_t Alignment>\n\tvoid test_single_alignment() {\n\t\tstruct alignas(Alignment) foo {\n\t\t\tchar space[Alignment + 1];\n\t\t};\n\t\tstatic_assert(alignof(foo) == Alignment);\n\t\tstatic_assert(sizeof(foo) == 2 * Alignment);\n\n\t\tauto buf = temporary_buffer<foo>{32};\n\t\tCHECK(buf.size() == 32);\n\n\t\t// Verify alignment\n\t\tvoid* const data = buf.data();\n\t\tvoid* ptr = data;\n\t\tstd::size_t size = sizeof(foo);\n\t\tCHECK(std::align(Alignment, sizeof(foo), ptr, size) == data);\n\t}\n\n\ttemplate<std::size_t... Alignments>\n\tvoid test_alignments() {\n\t\t(test_single_alignment<Alignments>(), ...);\n\t}\n}\n\nint main() {\n\ttest_alignments<1, 2, 4, 8, 16, 32, 64, 128>();\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/functional/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_stl2_test(functional.invoke invoke invoke.cpp)\nadd_stl2_test(functional.not_fn not_fn not_fn.cpp)\n"
  },
  {
    "path": "test/functional/invoke.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/functional/invoke.hpp>\n#include <memory>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nstatic_assert(ranges::copyable<ranges::reference_wrapper<int>>);\n\nconstexpr struct {\n\ttemplate<class T>\n\tconstexpr auto&& operator()(T&& arg) const noexcept {\n\t\treturn static_cast<T&&>(arg);\n\t}\n} h;\n\nstruct A {\n\tint i = 13;\n\tconstexpr int f() const noexcept { return 42; }\n\tconstexpr int g(int i) { return 2 * i; }\n};\n\nconstexpr int f() noexcept { return 13; }\nconstexpr int g(int i) { return 2 * i + 1; }\n\nint main() {\n\tCHECK(ranges::invoke(f) == 13);\n\tCHECK(noexcept(ranges::invoke(f) == 13));\n\tCHECK(ranges::invoke(g, 2) == 5);\n\tCHECK(ranges::invoke(h, 42) == 42);\n\tCHECK(noexcept(ranges::invoke(h, 42) == 42));\n\t{\n\t\tint i = 13;\n\t\tCHECK(&ranges::invoke(h, i) == &i);\n\t\tCHECK(noexcept(&ranges::invoke(h, i) == &i));\n\t}\n\n\tCHECK(ranges::invoke(&A::f, A{}) == 42);\n\tCHECK(noexcept(ranges::invoke(&A::f, A{}) == 42));\n\tCHECK(ranges::invoke(&A::g, A{}, 2) == 4);\n\t{\n\t\tA a;\n\t\tconst auto& ca = a;\n\t\tCHECK(ranges::invoke(&A::f, a) == 42);\n\t\tCHECK(noexcept(ranges::invoke(&A::f, a) == 42));\n\t\tCHECK(ranges::invoke(&A::f, ca) == 42);\n\t\tCHECK(noexcept(ranges::invoke(&A::f, ca) == 42));\n\t\tCHECK(ranges::invoke(&A::g, a, 2) == 4);\n\t}\n\n\t{\n\t\tA a;\n\t\tconst auto& ca = a;\n\t\tCHECK(ranges::invoke(&A::f, &a) == 42);\n\t\tCHECK(noexcept(ranges::invoke(&A::f, &a) == 42));\n\t\tCHECK(ranges::invoke(&A::f, &ca) == 42);\n\t\tCHECK(noexcept(ranges::invoke(&A::f, &ca) == 42));\n\t\tCHECK(ranges::invoke(&A::g, &a, 2) == 4);\n\t}\n\t{\n\t\tauto up = std::make_unique<A>();\n\t\tCHECK(ranges::invoke(&A::f, up) == 42);\n\t\tCHECK(ranges::invoke(&A::g, up, 2) == 4);\n\t}\n\t{\n\t\tauto sp = std::make_shared<A>();\n\t\tCHECK(ranges::invoke(&A::f, sp) == 42);\n\t\tCHECK(noexcept(ranges::invoke(&A::f, sp) == 42));\n\t\tCHECK(ranges::invoke(&A::g, sp, 2) == 4);\n\t}\n\n\tCHECK(ranges::invoke(&A::i, A{}) == 13);\n\tCHECK(noexcept(ranges::invoke(&A::i, A{}) == 13));\n\t{ int&& tmp = ranges::invoke(&A::i, A{}); (void)tmp; }\n\n\t{\n\t\tA a;\n\t\tconst auto& ca = a;\n\t\tCHECK(ranges::invoke(&A::i, a) == 13);\n\t\tCHECK(noexcept(ranges::invoke(&A::i, a) == 13));\n\t\tCHECK(ranges::invoke(&A::i, ca) == 13);\n\t\tCHECK(noexcept(ranges::invoke(&A::i, ca) == 13));\n\t\tCHECK(ranges::invoke(&A::i, &a) == 13);\n#if !STL2_WORKAROUND_MSVC_836487 // \"workaround\"\n\t\tCHECK(noexcept(ranges::invoke(&A::i, &a) == 13));\n#endif // !STL2_WORKAROUND_MSVC_836487\n\t\tCHECK(ranges::invoke(&A::i, &ca) == 13);\n\t\tCHECK(noexcept(ranges::invoke(&A::i, &ca) == 13));\n\n\t\tranges::invoke(&A::i, a) = 0;\n\t\tCHECK(a.i == 0);\n\t\tranges::invoke(&A::i, &a) = 1;\n\t\tCHECK(a.i == 1);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::invoke(&A::i, ca)), const int&>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::invoke(&A::i, &ca)), const int&>);\n\t}\n\n\t{\n\t\tauto up = std::make_unique<A>();\n\t\tCHECK(ranges::invoke(&A::i, up) == 13);\n\t\tranges::invoke(&A::i, up) = 0;\n\t\tCHECK(up->i == 0);\n\t}\n\n\t{\n\t\tauto sp = std::make_shared<A>();\n\t\tCHECK(ranges::invoke(&A::i, sp) == 13);\n\t\tranges::invoke(&A::i, sp) = 0;\n\t\tCHECK(sp->i == 0);\n\t}\n\n\t{\n\t\tstruct B { int i = 42; constexpr int f() const { return i; } };\n\t\tconstexpr B b;\n\t\tstatic_assert(b.i == 42);\n\t\tstatic_assert(b.f() == 42);\n\t\tstatic_assert(ranges::invoke(&B::i, b) == 42);\n#if !STL2_WORKAROUND_MSVC_836487 // \"workaround\"\n\t\tstatic_assert(ranges::invoke(&B::i, &b) == 42);\n#endif // !STL2_WORKAROUND_MSVC_836487\n\t\tstatic_assert(ranges::invoke(&B::i, B{}) == 42);\n\t\tstatic_assert(ranges::invoke(&B::f, b) == 42);\n\t\tstatic_assert(ranges::invoke(&B::f, &b) == 42);\n\t\tstatic_assert(ranges::invoke(&B::f, B{}) == 42);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/functional/not_fn.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/functional.hpp>\n#include <algorithm>\n#include <iterator>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n\nnamespace stl2 = __stl2;\n\nconstexpr struct {\n\ttemplate<stl2::integral T>\n\tconstexpr bool operator()(T i) const {\n\t\treturn i % 2 != 0;\n\t}\n} is_odd{};\n\nstruct A {\n\tint i;\n\tconstexpr bool is_odd() const { return ::is_odd(i); }\n\tconstexpr operator int() const { return i; }\n};\n\nint main() {\n\t{\n\t\tint some_ints[] = {0,1,2,3,4,5,6,7};\n\t\tint result[sizeof(some_ints)/sizeof(some_ints[0])];\n\t\tauto e = std::copy_if(std::begin(some_ints), std::end(some_ints), result, stl2::not_fn(is_odd));\n\t\tCHECK_EQUAL(stl2::subrange(result, e), {0,2,4,6});\n\t}\n\n\t{\n\t\tA some_As[] = {0,1,2,3,4,5,6,7};\n\t\tA result[sizeof(some_As)/sizeof(some_As[0])];\n\t\tauto e = std::copy_if(std::begin(some_As), std::end(some_As), result, stl2::not_fn(&A::is_odd));\n\t\tCHECK_EQUAL(stl2::subrange(result, e), {0,2,4,6});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/headers1.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n\n#include \"all_public_headers.hpp\"\n"
  },
  {
    "path": "test/headers2.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015-2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n\n#include \"all_public_headers.hpp\"\n\nint main() {}\n"
  },
  {
    "path": "test/iterator/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_stl2_test(test.iterator.misc iterator iterator.cpp)\nadd_stl2_test(test.iterator.move move_iterator move_iterator.cpp)\nadd_stl2_test(test.iterator.reverse reverse_iterator reverse_iterator.cpp)\nadd_stl2_test(test.iterator.basic basic_iterator basic_iterator.cpp)\nadd_stl2_test(test.iterator.common common_iterator common_iterator.cpp)\nadd_stl2_test(test.iterator.counted counted_iterator counted_iterator.cpp)\nadd_stl2_test(test.iterator.unreachable unreachable unreachable.cpp)\nadd_stl2_test(test.iterator.istream istream_iterator istream_iterator.cpp)\nadd_stl2_test(test.iterator.ostream ostream_iterator ostream_iterator.cpp)\nadd_stl2_test(test.iterator.istreambuf istreambuf_iterator istreambuf_iterator.cpp)\nadd_stl2_test(test.iterator.ostreambuf ostreambuf_iterator ostreambuf_iterator.cpp)\nadd_stl2_test(test.iterator.make_range make_range make_range.cpp)\nadd_stl2_test(test.iterator.incomplete iter.incomplete incomplete.cpp)\nadd_stl2_test(test.iterator.operations iter.operations operations.cpp)\nadd_stl2_test(test.iterator.any iter.any any_iterator.cpp)\n# silence -Wstrict-aliasing false positives from GCC 7.1\ntarget_compile_options(iter.any PRIVATE\n    $<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,7.0>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7.2>>:\n    -Wno-error=strict-aliasing>)\n"
  },
  {
    "path": "test/iterator/any_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/iterator/any_iterator.hpp>\n#include <iterator>\n#include <iostream>\n#include <string>\n#include <sstream>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nvoid test_small() {\n\tint rg[]{0,1,2,3,4,5,6,7,8,9};\n\tusing AI = ranges::ext::any_input_iterator<int&>;\n\tAI first{rg};\n\tAI const last{rg+10};\n\tauto a1 = first, a2 = a1; (void)a2; // makin' copies\n\tCHECK(&rg[5] == &*ranges::next(first, 5));\n\tCHECK(&rg[5] == &(int const&)ranges::iter_move(ranges::next(first, 5)));\n\tint i = 0;\n\tfor (; first != last; ++first, ++i) {\n\t\tCHECK(!(first == last));\n\t\tCHECK(*first == rg[i]);\n\t\tCHECK(&*first == &rg[i]);\n\t}\n\tCHECK(i == 10);\n\tfirst = rg;\n\tCHECK(*first == 0);\n}\n\nvoid test_big() {\n\tstd::stringstream sin{\"now is the time for all good personages\"};\n\tusing I = std::istream_iterator<std::string>;\n\tusing AI = ranges::ext::any_input_iterator<std::string const &>;\n\tAI first{I{sin}};\n\tAI const last{I{}};\n\tauto a1 = first, a2 = a1; (void)a2; // makin' aliases\n\tCHECK(first != last);\n\tif (first != last) {\n\t\tCHECK(*first == \"now\");\n\t\tfirst = ranges::next(first, 7, last);\n\t\tCHECK(first != last);\n\t\tif (first != last) {\n\t\t\tCHECK(*first == \"personages\");\n\t\t\tCHECK(++first == last);\n\t\t}\n\t}\n}\n\nint main() {\n\ttest_small();\n\ttest_big();\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/basic_iterator.cpp",
    "content": "#include <stl2/detail/iterator/basic_iterator.hpp>\n#include <stl2/algorithm.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n#include <stl2/view/repeat.hpp>\n#include <initializer_list>\n#include <iostream>\n#include <memory>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class> class show_type;\n\ntemplate<ranges::destructible T>\nclass forward_list {\n\tstruct node {\n\t\tstd::unique_ptr<node> next_;\n\t\tT data_;\n\n\t\ttemplate<class... Args>\n\t\trequires ranges::constructible_from<T, Args...>\n\t\tconstexpr node(Args&&... args)\n\t\tnoexcept(std::is_nothrow_constructible<T, Args...>::value)\n\t\t: data_(std::forward<Args>(args)...) {}\n\n\t\tnode(node&&) = delete;\n\t\tnode(const node&) = delete;\n\t};\n\n\ttemplate<bool IsConst>\n\tclass cursor {\n\tpublic:\n\t\ttemplate<bool> friend class cursor;\n\n\t\tcursor() = default;\n\t\ttemplate<bool B>\n\t\trequires (IsConst && !B)\n\t\tcursor(cursor<B> that) noexcept\n\t\t: ptr_{that.ptr_} {}\n\n\t\tstruct mixin : protected ranges::basic_mixin<cursor> {\n\t\t\tmixin() = default;\n\t\t\tusing ranges::basic_mixin<cursor>::basic_mixin;\n\t\t\tconstexpr mixin(ranges::default_sentinel_t) noexcept\n\t\t\t: mixin{cursor{}}\n\t\t\t{}\n\t\t};\n\n\t\tconstexpr meta::if_c<IsConst, const T, T>& read() const noexcept {\n\t\t\treturn ptr_->data_;\n\t\t}\n\t\tconstexpr void next() noexcept { ptr_ = ptr_->next_.get(); }\n\t\tconstexpr bool equal(ranges::default_sentinel_t) const noexcept { return !ptr_; }\n\t\tconstexpr bool equal(const cursor& that) const noexcept { return ptr_ == that.ptr_; }\n\n\tprivate:\n\t\tranges::detail::raw_ptr<node> ptr_ = nullptr;\n\n\t\tfriend forward_list;\n\t\tconstexpr cursor(node* ptr) noexcept\n\t\t: ptr_{ptr} {}\n\t};\n\n\tstd::unique_ptr<node> head_ = nullptr;\n\npublic:\n\tusing value_type = T;\n\tusing iterator = ranges::basic_iterator<cursor<false>>;\n\tusing const_iterator = ranges::basic_iterator<cursor<true>>;\n\n\tforward_list() = default;\n\tforward_list(std::initializer_list<T> il)\n\trequires ranges::copy_constructible<T>\n\t{ ranges::reverse_copy(il, ranges::front_inserter(*this)); }\n\n\tconstexpr iterator begin() noexcept {\n\t\treturn iterator{cursor<false>{head_.get()}};\n\t}\n\tconstexpr const_iterator begin() const noexcept {\n\t\treturn const_iterator{cursor<true>{head_.get()}};\n\t}\n\tconstexpr ranges::default_sentinel_t end() const noexcept { return {}; }\n\n\ttemplate<class... Args>\n\trequires ranges::constructible_from<T, Args...>\n\tvoid emplace(Args&&... args) {\n\t\tauto p = std::make_unique<node>(std::forward<Args>(args)...);\n\t\tp->next_ = std::move(head_);\n\t\thead_ = std::move(p);\n\t}\n\n\tvoid push_front(T&& t)\n\trequires ranges::move_constructible<T>\n\t{ emplace(std::move(t)); }\n\tvoid push_front(const T& t)\n\trequires ranges::copy_constructible<T>\n\t{ emplace(t); }\n};\n\ntemplate<class T>\nclass pointer_cursor {\npublic:\n\tusing contiguous = std::true_type;\n\tclass mixin : protected ranges::basic_mixin<pointer_cursor> {\n\t\tusing base_t = ranges::basic_mixin<pointer_cursor>;\n\tpublic:\n\t\tmixin() = default;\n\t\tconstexpr mixin(T* ptr) noexcept\n\t\t: base_t{pointer_cursor{ptr}}\n\t\t{}\n\t\tusing base_t::base_t;\n\t};\n\n\tpointer_cursor() = default;\n\tconstexpr pointer_cursor(T* ptr) noexcept\n\t: ptr_{ptr} {}\n\n\ttemplate<class U>\n\trequires ranges::convertible_to<U*, T*>\n\tconstexpr pointer_cursor(const pointer_cursor<U>& that) noexcept\n\t: ptr_{that.arrow()} {}\n\n\tconstexpr T& read() const noexcept {\n\t\tSTL2_EXPECT(ptr_);\n\t\treturn *ptr_;\n\t}\n\n\tconstexpr T* arrow() const noexcept {\n\t\tSTL2_EXPECT(ptr_);\n\t\treturn ptr_;\n\t}\n\n\tconstexpr void next() noexcept {\n\t\tSTL2_EXPECT(ptr_);\n\t\t++ptr_;\n\t}\n\n\tconstexpr bool equal(const pointer_cursor& that) const noexcept {\n\t\treturn ptr_ == that.ptr_;\n\t}\n\n\tconstexpr void prev() noexcept {\n\t\tSTL2_EXPECT(ptr_);\n\t\t--ptr_;\n\t}\n\n\tconstexpr void advance(std::ptrdiff_t n) noexcept {\n\t\tSTL2_EXPECT(ptr_);\n\t\tptr_ += n;\n\t}\n\n\tconstexpr std::ptrdiff_t distance_to(const pointer_cursor& that) const noexcept {\n\t\tSTL2_EXPECT(!that.ptr_ == !ptr_);\n\t\treturn that.ptr_ - ptr_;\n\t}\n\nprivate:\n\tT* ptr_;\n};\n\ntemplate<ranges::semiregular T, std::size_t N>\nclass array {\npublic:\n\tusing value_type = T;\n\tusing iterator = ranges::basic_iterator<pointer_cursor<T>>;\n\tusing const_iterator = ranges::basic_iterator<pointer_cursor<const T>>;\n\n\t// These should be constexpr, except for PR67376.\n\titerator begin() noexcept { return {elements_ + 0}; }\n\titerator end() noexcept { return {elements_ + N}; }\n\tconst_iterator begin() const noexcept { return {elements_ + 0}; }\n\tconst_iterator end() const noexcept { return {elements_ + N}; }\n\n\tT elements_[N];\n};\n\ntemplate<class T, T Value>\nstruct always_cursor {\n\tconstexpr T read() const\n\t\tnoexcept(std::is_nothrow_copy_constructible<T>::value) {\n\t\treturn Value;\n\t}\n\tconstexpr bool equal(always_cursor) const noexcept { return true; }\n\tconstexpr void next() const noexcept {}\n\tconstexpr void prev() const noexcept {}\n\tconstexpr void advance(std::ptrdiff_t) const noexcept {}\n\tconstexpr std::ptrdiff_t distance_to(always_cursor) const noexcept { return 0; }\n};\ntemplate<class T, T Value>\nusing always_iterator = ranges::basic_iterator<always_cursor<T, Value>>;\n\ntemplate<ranges::ext::object T>\nstruct proxy_wrapper {\n\tranges::detail::raw_ptr<T> ptr_ = nullptr;\n\n\tproxy_wrapper() = default;\n\tproxy_wrapper(T& t) noexcept : ptr_{std::addressof(t)} {}\n\tproxy_wrapper(T&&) = delete; // LWG 2993?\n\n\tT& get() const noexcept { return *ptr_; }\n\n\tproxy_wrapper& operator=(const T& t)\n\tnoexcept(std::is_nothrow_copy_assignable<T>::value)\n\trequires ranges::copy_constructible<T>\n\t{\n\t\tget() = t;\n\t\treturn *this;\n\t}\n\n\tproxy_wrapper& operator=(T&& t)\n\tnoexcept(std::is_nothrow_move_assignable<T>::value)\n\trequires ranges::move_constructible<T>\n\t{\n\t\tget() = std::move(t);\n\t\treturn *this;\n\t}\n\n\tproxy_wrapper const& operator=(const T& t) const\n\tnoexcept(std::is_nothrow_copy_assignable<T>::value)\n\trequires ranges::copyable<T>\n\t{\n\t\tget() = t;\n\t\treturn *this;\n\t}\n\n\tproxy_wrapper const& operator=(T&& t) const\n\tnoexcept(std::is_nothrow_move_assignable<T>::value)\n\trequires ranges::movable<T>\n\t{\n\t\tget() = std::move(t);\n\t\treturn *this;\n\t}\n\n\toperator T&() const noexcept { return get(); }\n};\n\nSTL2_OPEN_NAMESPACE {\n\ttemplate<class T, class U, template<class> class TQual,\n\t\ttemplate<class> class UQual>\n\tstruct basic_common_reference<::proxy_wrapper<T>, U, TQual, UQual>\n\t: common_reference<T&, UQual<U>> {};\n\n\ttemplate<class T, class U, template<class> class TQual,\n\t\ttemplate<class> class UQual>\n\tstruct basic_common_reference<T, ::proxy_wrapper<U>, TQual, UQual>\n\t: common_reference<TQual<T>, U&> {};\n\n\ttemplate<class T, class U, template<class> class TQual,\n\t\ttemplate<class> class UQual>\n\tstruct basic_common_reference<\n\t\t::proxy_wrapper<T>, ::proxy_wrapper<U>, TQual, UQual>\n\t: common_reference<T&, U&> {};\n} STL2_CLOSE_NAMESPACE\n\n// std::array-ish container with proxy iterators.\ntemplate<class T, std::size_t N>\nstruct proxy_array {\n\ttemplate<bool IsConst>\n\tstruct cursor {\n\t\tusing value_type = T;\n\n\t\tusing O = meta::if_c<IsConst, const T, T>;\n\t\tO* ptr_;\n\n\t\tcursor(O* p = nullptr) : ptr_{p} {}\n\t\ttemplate<bool B>\n\t\trequires (IsConst && !B)\n\t\tcursor(const cursor<B>& that) : ptr_{that.ptr_} {}\n\n\t\ttemplate<bool B>\n\t\tbool equal(const cursor<B>& that) const noexcept { return ptr_ == that.ptr_; }\n\t\tproxy_wrapper<O> read() const noexcept { return {*ptr_}; }\n\t\tvoid next() noexcept { ++ptr_; }\n\t\tvoid prev() noexcept { --ptr_; }\n\t\tvoid advance(std::ptrdiff_t n) noexcept { ptr_ += n; }\n\t\ttemplate<bool B>\n\t\tstd::ptrdiff_t distance_to(const cursor<B>& that) const noexcept {\n\t\t\treturn that.ptr_ - ptr_;\n\t\t}\n\t\tO&& indirect_move() const noexcept { return std::move(*ptr_); }\n\t};\n\n\tstatic_assert(ranges::cursor::readable<cursor<false>>);\n\tstatic_assert(ranges::cursor::IndirectMove<cursor<false>>);\n\tstatic_assert(ranges::same_as<T&&, ranges::cursor::rvalue_reference_t<cursor<false>>>);\n\n\tstatic_assert(ranges::cursor::readable<cursor<true>>);\n\tstatic_assert(ranges::cursor::IndirectMove<cursor<true>>);\n\tstatic_assert(ranges::same_as<const T&&, ranges::cursor::rvalue_reference_t<cursor<true>>>);\n\n\tusing iterator = ranges::basic_iterator<cursor<false>>;\n\tusing const_iterator = ranges::basic_iterator<cursor<true>>;\n\tusing reference = proxy_wrapper<T>;\n\tusing const_reference = proxy_wrapper<const T>;\n\n\tT e_[N];\n\n\tauto begin() { return iterator{&e_[0]}; }\n\tauto end() { return iterator{&e_[0] + N}; }\n\n\tauto begin() const { return const_iterator{&e_[0]}; }\n\tauto end() const { return const_iterator{&e_[0] + N}; }\n\tauto cbegin() const { return begin(); }\n\tauto cend() const { return end(); }\n\n\treference operator[](const std::size_t n) noexcept {\n\t\treturn {e_[n]};\n\t}\n\tconst_reference operator[](const std::size_t n) const noexcept {\n\t\treturn {e_[n]};\n\t}\n};\n\ntemplate<ranges::input_range R>\nrequires\n\t(ranges::StreamInsertable<ranges::iter_value_t<ranges::iterator_t<R>>> &&\n\t !ranges::same_as<char, std::remove_cv_t<\n\t\tstd::remove_all_extents_t<std::remove_reference_t<R>>>>)\nstd::ostream& operator<<(std::ostream& os, R&& rng) {\n\tos << '{';\n\tauto i = rng.begin();\n\tauto e = rng.end();\n\tif (i != e) {\n\t\tfor (;;) {\n\t\t\tos << *i;\n\t\t\tif (++i == e) break;\n\t\t\tos << \", \";\n\t\t}\n\t}\n\tos << '}';\n\treturn os;\n}\n\nvoid test_fl() {\n\tstd::cout << \"test_fl:\\n\";\n\t::forward_list<int> list = {0, 1, 2, 3};\n\tusing Rng = decltype(list);\n\tusing I = decltype(list.begin());\n\tusing S = decltype(list.end());\n\tstatic_assert(ranges::weakly_incrementable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(ranges::readable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_value_t<I>, int>);\n\tstatic_assert(ranges::same_as<ranges::iter_reference_t<I>, int&>);\n\tstatic_assert(ranges::same_as<ranges::iter_rvalue_reference_t<I>, int&&>);\n\tstatic_assert(ranges::copyable<I>);\n\tstatic_assert(ranges::default_initializable<I>);\n\tstatic_assert(ranges::semiregular<I>);\n\tstatic_assert(ranges::incrementable<I>);\n\tstatic_assert(ranges::equality_comparable<I>);\n\tstatic_assert(ranges::forward_iterator<I>);\n\tstatic_assert(ranges::sentinel_for<S, I>);\n\tstatic_assert(ranges::forward_range<Rng>);\n\tstatic_assert(ranges::common_with<S, I>);\n\tstatic_assert(ranges::same_as<ranges::common_type_t<S, I>, I>);\n\tstd::cout << list << '\\n';\n\t*ranges::front_inserter(list) = 3.14;\n\tstd::cout << list << '\\n';\n\tCHECK(list.begin() != list.end());\n\tCHECK(noexcept(list.begin() != list.end()));\n\tCHECK(!(list.begin() == list.end()));\n\tCHECK(noexcept(list.begin() == list.end()));\n\tCHECK(list.begin() != ranges::next(list.begin()));\n\tCHECK(!(list.begin() == ranges::next(list.begin())));\n\tstatic_assert(I{} == I{});\n\tCHECK(noexcept(I{} == I{}));\n\tCHECK(noexcept(ranges::front_inserter(list)));\n\tCHECK(sizeof(I) == sizeof(void*));\n\tCHECK(ranges::begin(list) == ranges::cbegin(list));\n\t{ auto i = ranges::cbegin(list); i = ranges::begin(list); }\n\t{ auto i = ranges::begin(list); i = ranges::end(list); }\n\t{ auto i = ranges::cbegin(list); i = ranges::end(list); }\n}\n\nvoid test_rv() {\n\tstd::cout << \"test_rv:\\n\";\n\tranges::ext::repeat_view rv{42};\n\n\tusing Rng = decltype(rv);\n\tusing I = decltype(rv.begin());\n\tstatic_assert(ranges::weakly_incrementable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(ranges::readable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_value_t<I>, int>);\n\tstatic_assert(ranges::same_as<ranges::iter_reference_t<I>, int&>);\n\tstatic_assert(ranges::same_as<ranges::iter_rvalue_reference_t<I>, int&&>);\n\tstatic_assert(ranges::random_access_iterator<I>);\n\tstatic_assert(ranges::random_access_range<Rng>);\n\tCHECK(I{} == I{});\n\n\tauto i = rv.begin();\n\tfor (auto n = 0; i != rv.end() && n < 13; ++i, ++n) {\n\t\tstd::cout << *i << ' ';\n\t}\n\tstd::cout << '\\n';\n\n\tranges::copy_n(rv.begin(), 13, ranges::ostream_iterator<>{std::cout, \" \"});\n\tstd::cout << '\\n';\n\tCHECK(rv.begin() != rv.end());\n\tCHECK(!(rv.begin() == rv.end()));\n\n\tCHECK(rv.begin() == rv.begin());\n\tCHECK(!(rv.begin() != rv.begin()));\n\tCHECK(rv.begin() == rv.begin() + 1);\n\tCHECK(rv.begin() == rv.begin() - 1);\n\tCHECK(!(rv.begin() < rv.begin()));\n\tCHECK(!(rv.begin() > rv.begin()));\n\tCHECK(rv.begin() <= rv.begin());\n\tCHECK(rv.begin() >= rv.begin());\n}\n\nvoid test_array() {\n\tstd::cout << \"test_array:\\n\";\n\n\t::array<int, 13> a;\n\n\tusing Rng = decltype(a);\n\tusing I = decltype(a.begin());\n\tCHECK(noexcept(a.begin()));\n\tstatic_assert(ranges::weakly_incrementable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(ranges::readable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_value_t<I>, int>);\n\tstatic_assert(ranges::same_as<ranges::iter_reference_t<I>, int&>);\n\tstatic_assert(ranges::same_as<ranges::iter_rvalue_reference_t<I>, int&&>);\n\tstatic_assert(ranges::contiguous_iterator<I>);\n\tstatic_assert(ranges::random_access_range<Rng>);\n\tstatic_assert(ranges::random_access_range<const Rng>);\n\tstatic_assert(ranges::common_range<Rng>);\n\tstatic_assert(ranges::common_range<const Rng>);\n\tCHECK(I{} == I{});\n\tCHECK(noexcept(I{} == I{}));\n\n\t{\n\t\tauto first = a.begin();\n\t\tauto last = a.end() - 1;\n\t\tCHECK(!(first == last));\n\t\tCHECK((first != last));\n\t\tCHECK((first < last));\n\t\tCHECK(!(first > last));\n\t\tCHECK((first <= last));\n\t\tCHECK(!(first >= last));\n\t}\n\t{\n\t\tauto first = ranges::begin(a);\n\t\tauto last = ranges::cend(a) - 1;\n\t\tCHECK(!(first == last));\n\t\tCHECK((first != last));\n\t\tCHECK((first < last));\n\t\tCHECK(!(first > last));\n\t\tCHECK((first <= last));\n\t\tCHECK(!(first >= last));\n\t}\n\n\tranges::fill(a, 42);\n}\n\nvoid test_counted() {\n\tusing ranges::counted_iterator;\n\tstd::cout << \"test_counted:\\n\";\n\tint some_ints[] = {0,1,2,3};\n\tusing I = counted_iterator<const int*>;\n\tstatic_assert(ranges::weakly_incrementable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(ranges::readable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_value_t<I>, int>);\n\tstatic_assert(ranges::same_as<ranges::iter_reference_t<I>, const int&>);\n\tstatic_assert(ranges::same_as<ranges::iter_rvalue_reference_t<I>, const int&&>);\n\tstatic_assert(ranges::random_access_iterator<I>);\n\tstatic_assert(ranges::contiguous_iterator<I>);\n\tCHECK(I{} == I{});\n\tauto first = I{some_ints, 4};\n\tCHECK(first.base() == some_ints);\n\tCHECK(first.count() == 4);\n\tauto last = I{some_ints + 4, 0};\n\tCHECK(last.base() == some_ints + 4);\n\tCHECK(last.count() == 0);\n\tstatic_assert(ranges::sized_sentinel_for<I, I>);\n\tCHECK((last - first) == 4);\n\tstatic_assert(ranges::sized_sentinel_for<ranges::default_sentinel_t, I>);\n\tCHECK((ranges::default_sentinel - first) == 4);\n\tauto out = ranges::ostream_iterator<>{std::cout, \" \"};\n\tranges::copy(first, last, out);\n\tstd::cout << '\\n';\n\tranges::copy(first, ranges::default_sentinel, out);\n\tstd::cout << '\\n';\n\n\tauto second = first + 1;\n\tCHECK(*first == 0);\n\tCHECK(*second == 1);\n\tCHECK(*++first == 1);\n\tCHECK(*first-- == 1);\n\tCHECK(*first == 0);\n\n\t{\n\t\tauto one = counted_iterator<const int*>{some_ints + 1, ranges::distance(some_ints) - 1};\n\t\tauto three = counted_iterator<int*>{some_ints + 3, ranges::distance(some_ints) - 3};\n\t\tCHECK(!(one == three));\n\t\tCHECK((one != three));\n\t\tCHECK((one < three));\n\t\tCHECK(!(one > three));\n\t\tCHECK((one <= three));\n\t\tCHECK(!(one >= three));\n\t}\n }\n\nvoid test_always() {\n\tstd::cout << \"test_always:\\n\";\n\t// Iterates over life, the universe, and everything.\n\tauto i = always_iterator<int, 42>{};\n\tusing I = decltype(i);\n\tstatic_assert(std::is_empty<I>());\n\tstatic_assert(sizeof(I) == 1);\n\tstatic_assert(ranges::weakly_incrementable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(ranges::readable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_value_t<I>, int>);\n\tstatic_assert(ranges::same_as<ranges::iter_reference_t<I>, int>);\n\tstatic_assert(ranges::same_as<ranges::iter_rvalue_reference_t<I>, int>);\n\tstatic_assert(ranges::random_access_iterator<I>);\n\tCHECK(I{} == I{});\n\tranges::copy_n(i, 13, ranges::ostream_iterator<>{std::cout, \" \"});\n\tstd::cout << '\\n';\n\tCHECK(*i == 42);\n\tCHECK(*(i + 42) == 42);\n\tCHECK(*(i - 42) == 42);\n\tCHECK(i[42] == 42);\n}\n\nvoid test_back_inserter() {\n\tstd::cout << \"test_back_inserter:\\n\";\n\tauto vec = std::vector<int>{};\n\tauto i = ranges::back_inserter(vec);\n\tusing I = decltype(i);\n\tstatic_assert(ranges::weakly_incrementable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(ranges::same_as<ranges::iter_reference_t<I>, I&>);\n\tstatic_assert(!ranges::readable<I>);\n\tstatic_assert(ranges::output_iterator<I, int>);\n\tstatic_assert(!ranges::input_iterator<I>);\n\tstatic_assert(!ranges::equality_comparable<I>);\n\tranges::copy_n(always_iterator<int, 42>{}, 13, i);\n\tCHECK(vec.size() == 13u);\n}\n\nvoid test_proxy_array() {\n\tstd::cout << \"test_proxy_array:\\n\";\n\n\tauto a = proxy_array<int, 4>{0,1,2,3};\n\n\t{\n\t\tauto ci = a.cbegin();\n\t\tCHECK((ci == a.begin()));\n\t\tci = a.begin();\n\t}\n\n\tusing Rng = decltype(a);\n\n\tusing I = ranges::iterator_t<Rng>;\n\tstatic_assert(ranges::weakly_incrementable<I>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(ranges::readable<I>);\n\tusing R = ranges::iter_reference_t<I>;\n\tstatic_assert(ranges::same_as<proxy_wrapper<int>, R>);\n\tusing V = ranges::iter_value_t<I>;\n\tstatic_assert(ranges::same_as<int, V>);\n\tstatic_assert(ranges::same_as<int&&, decltype(iter_move(std::declval<const I&>()))>);\n\tstatic_assert(ranges::same_as<int&&, decltype(iter_move(std::declval<I&>()))>);\n\n\tstatic_assert(ranges::__iter_move::has_customization<const I&>);\n\tstatic_assert(ranges::__iter_move::has_customization<I&>);\n\tusing RR = ranges::iter_rvalue_reference_t<I>;\n\tstatic_assert(ranges::same_as<int&&, RR>);\n\tstatic_assert(ranges::random_access_iterator<I>);\n\tstatic_assert(!ranges::contiguous_iterator<I>);\n\tstatic_assert(ranges::random_access_range<Rng>);\n\tstatic_assert(ranges::common_range<Rng>);\n\n\tusing CI = ranges::iterator_t<const Rng>;\n\tstatic_assert(ranges::weakly_incrementable<CI>);\n\tstatic_assert(ranges::same_as<ranges::iter_difference_t<CI>, std::ptrdiff_t>);\n\tusing CR = ranges::iter_reference_t<CI>;\n\tstatic_assert(ranges::same_as<proxy_wrapper<const int>, CR>);\n\tusing CV = ranges::iter_value_t<CI>;\n\tstatic_assert(ranges::same_as<int, CV>);\n\n\tstatic_assert(ranges::__iter_move::has_customization<const CI&>);\n\tstatic_assert(ranges::__iter_move::has_customization<CI&>);\n\tusing CRR = ranges::iter_rvalue_reference_t<CI>;\n\tstatic_assert(ranges::same_as<const int&&, CRR>);\n\n\tstatic_assert(ranges::common_reference_with<CR, CV&>);\n\tstatic_assert(ranges::common_reference_with<CR, CRR>);\n\tstatic_assert(ranges::common_reference_with<CRR, const CV&>);\n\tstatic_assert(ranges::readable<CI>);\n\tstatic_assert(ranges::same_as<const int&&, decltype(iter_move(std::declval<const CI&>()))>);\n\tstatic_assert(ranges::same_as<const int&&, decltype(iter_move(std::declval<CI&>()))>);\n\n\tstatic_assert(ranges::random_access_iterator<CI>);\n\tstatic_assert(!ranges::contiguous_iterator<CI>);\n\tstatic_assert(ranges::random_access_range<const Rng>);\n\tstatic_assert(ranges::common_range<const Rng>);\n\n\tstatic_assert(ranges::same_as<I, decltype(a.begin() + 2)>);\n\tstatic_assert(ranges::common_reference_with<const R&, const R&>);\n\tstatic_assert(!ranges::swappable_with<R, R>);\n\tstatic_assert(ranges::indirectly_movable_storable<I, I>);\n\n\t// swappable<R, R> is not satisfied, and\n\t// indirectly_movable_storable<I, I> is satisfied,\n\t// so this should resolve to the second overload of iter_swap.\n\tranges::iter_swap(a.begin() + 1, a.begin() + 3);\n\tCHECK(a[0] == 0);\n\tCHECK(a[1] == 3);\n\tCHECK(a[2] == 2);\n\tCHECK(a[3] == 1);\n}\n\nint main() {\n\ttest_rv();\n\ttest_fl();\n\ttest_array();\n\ttest_counted();\n\ttest_always();\n\ttest_back_inserter();\n\ttest_proxy_array();\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/common_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2015\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <algorithm>\n#include <numeric>\n#include <stl2/iterator.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tstruct silly_arrow_cursor {\n\t\tint read() const { return 42; }\n\t\tvoid next() {}\n\t\tint arrow() const { return 42; }\n\t};\n\n\tint forty_two = 42;\n\tstruct lvalue_iterator {\n\t\tusing iterator_category = ranges::input_iterator_tag;\n\t\tusing difference_type = int;\n\t\tusing value_type = int;\n\t\tint& operator*() const { return forty_two; }\n\t\tlvalue_iterator& operator++() &;\n\t\tlvalue_iterator operator++(int) &;\n\t};\n\tstruct xvalue_iterator : lvalue_iterator {\n\t\tint&& operator*() const { return std::move(forty_two); }\n\t\txvalue_iterator& operator++() &;\n\t\txvalue_iterator operator++(int) &;\n\t};\n\n\tstruct proxy_cursor {\n\t\tint read() const { return 42; }\n\t\tvoid next();\n\t};\n\tstruct sz {\n\t\tfriend bool operator==(const char* p, sz) { return !*p;\t}\n\t\tfriend bool operator!=(const char* p, sz) { return *p; }\n\t\tfriend bool operator==(sz, const char* p) { return !*p; }\n\t\tfriend bool operator!=(sz, const char* p) {\treturn *p; }\n\t};\n\n\tvoid test_operator_arrow() {\n\t\t// I is a pointer type\n\t\t{\n\t\t\tint i = 42;\n\t\t\tauto ci = ranges::common_iterator<int*, ranges::unreachable_sentinel_t>{&i};\n\t\t\tstatic_assert(ranges::same_as<int* const&, decltype(ci.operator->())>);\n\t\t\tCHECK(ci.operator->() == &i);\n\t\t}\n\t\t// the expression i.operator->() is well-formed\n\t\t{\n\t\t\tusing I = ranges::basic_iterator<silly_arrow_cursor>;\n\t\t\tauto ci = ranges::common_iterator<I, ranges::unreachable_sentinel_t>{};\n\t\t\tstatic_assert(ranges::same_as<const I&, decltype(ci.operator->())>);\n\t\t\tCHECK(ci.operator->().operator->() == 42);\n\t\t}\n\t\t// the expression *i is a glvalue [lvalue case]\n\t\t{\n\t\t\tauto ci = ranges::common_iterator<lvalue_iterator, ranges::unreachable_sentinel_t>{};\n\t\t\tstatic_assert(ranges::same_as<int*, decltype(ci.operator->())>);\n\t\t\tCHECK(ci.operator->() == &forty_two);\n\t\t}\n\t\t// the expression *i is a glvalue [xvalue case]\n\t\t{\n\t\t\tauto ci = ranges::common_iterator<xvalue_iterator, ranges::unreachable_sentinel_t>{};\n\t\t\tstatic_assert(ranges::same_as<int*, decltype(ci.operator->())>);\n\t\t\tCHECK(ci.operator->() == &forty_two);\n\t\t}\n\t\t// Otherwise, returns a proxy object\n\t\t{\n\t\t\tusing I = ranges::basic_iterator<proxy_cursor>;\n\t\t\tauto ci = ranges::common_iterator<I, ranges::unreachable_sentinel_t>{};\n\t\t\tusing A = decltype(ci.operator->());\n\t\t\tstatic_assert(std::is_class<A>::value);\n\t\t\tstatic_assert(!std::is_same<I, A>::value);\n\t\t\tCHECK(*ci.operator->().operator->() == 42);\n\t\t}\n\t}\n\n\tvoid test_constexpr() {\n\t\tstatic int i = 42;\n\n\t\tusing ranges::common_iterator;\n\t\tusing ranges::counted_iterator;\n\t\tusing ranges::default_sentinel_t, ranges::default_sentinel;\n\n\t\tusing CI = common_iterator<counted_iterator<int*>, default_sentinel_t>;\n\t\tconstexpr CI foo{ranges::counted_iterator{&i, 1}}; (void)foo;\n\t\tconstexpr CI bar{default_sentinel}; (void)bar;\n\t\tusing CCI = common_iterator<counted_iterator<const int*>, default_sentinel_t>;\n\t\tconstexpr CCI baz{foo};\n\t\tconstexpr CCI bang{bar};\n\t}\n}\n\nint main() {\n\t{\n\t\tstatic_assert(\n\t\t\tranges::forward_iterator<\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\tbidirectional_iterator<const char *>,\n\t\t\t\t\tsentinel<const char *>>>);\n\t\tstatic_assert(\n\t\t\t!ranges::bidirectional_iterator<\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\tbidirectional_iterator<const char *>,\n\t\t\t\t\tsentinel<const char *>>>);\n\t\tstatic_assert(\n\t\t\tstd::is_same<\n\t\t\t\t__stl2::common_reference<\n\t\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\t\tbidirectional_iterator<const char *>,\n\t\t\t\t\t\tsentinel<const char *>\n\t\t\t\t\t>&,\n\t\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\t\tbidirectional_iterator<const char *>,\n\t\t\t\t\t\tsentinel<const char *>\n\t\t\t\t\t>\n\t\t\t\t>::type,\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\tbidirectional_iterator<const char *>,\n\t\t\t\t\tsentinel<const char *>\n\t\t\t\t>\n\t\t\t>::value);\n\t\t// Sized iterator range tests\n\t\tstatic_assert(\n\t\t\t!ranges::sized_sentinel_for<\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\tforward_iterator<int*>,\n\t\t\t\t\tsentinel<int*, true> >,\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\tforward_iterator<int*>,\n\t\t\t\t\tsentinel<int*, true> > >);\n\t\tstatic_assert(\n\t\t\tranges::sized_sentinel_for<\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\trandom_access_iterator<int*>,\n\t\t\t\t\tsentinel<int*, true> >,\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\trandom_access_iterator<int*>,\n\t\t\t\t\tsentinel<int*, true> > >);\n\t\tstatic_assert(\n\t\t\t!ranges::sized_sentinel_for<\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\trandom_access_iterator<int*>,\n\t\t\t\t\tsentinel<int*, false> >,\n\t\t\t\t__stl2::common_iterator<\n\t\t\t\t\trandom_access_iterator<int*>,\n\t\t\t\t\tsentinel<int*, false> > >);\n\t}\n\t{\n\t\tint rgi[] {0,1,2,3,4,5,6,7,8,9};\n\t\tusing CI = __stl2::common_iterator<\n\t\t\trandom_access_iterator<int*>,\n\t\t\tsentinel<int*>>;\n\t\tCI first{random_access_iterator<int*>{rgi}};\n\t\tCI last{sentinel<int*>{rgi+10}};\n\t\tCHECK(std::accumulate(first, last, 0, std::plus<int>{}) == 45);\n\t}\n\t// Check conversions:\n\t{\n\t\tchar buff[] = \"abcd\";\n\t\t__stl2::common_iterator<char*, sz> ci(buff);\n\t\t__stl2::common_iterator<const char*, sz> ci2(ci);\n\t\tci2 = ci;\n\t\tCHECK(ci2 == ci);\n\t\t++ci2;\n\t\tCHECK(ci2 != ci);\n\t}\n\ttest_operator_arrow();\n\ttest_constexpr();\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/iterator/counted_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n#include <stl2/algorithm.hpp>\n#include <list>\n#include \"../test_iterators.hpp\"\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nconstexpr bool test_constexpr() {\n\tint some_ints[] = {0,1,2,3};\n\tconstexpr int n = ranges::size(some_ints);\n\tstatic_assert(n >= 4);\n\n\t{ ranges::counted_iterator<int*> unused{}; (void)unused; }\n\tauto first = ranges::counted_iterator{ranges::begin(some_ints), n};\n\tif (first.base() != ranges::begin(some_ints)) return false;\n\tif (first.count() != n) return false;\n\tauto last = ranges::counted_iterator{ranges::end(some_ints), 0};\n\tif (last.base() != ranges::end(some_ints)) return false;\n\n\tif (first == last) return false;\n\tif (!(first != last)) return false;\n\tif (!(first < last)) return false;\n\tif (first > last) return false;\n\tif (!(first <= last)) return false;\n\tif (first >= last) return false;\n\tif (last - first != n) return false;\n\tif (first - last != -n) return false;\n\tif (*(first + 2) != 2) return false;\n\n\t{\n\t\tranges::counted_iterator<int const*> tmp{first};\n\t\ttmp = first;\n\t\tif (tmp == last) return false;\n\t\tif (!(tmp != last)) return false;\n\t\tif (!(tmp < last)) return false;\n\t\tif (tmp > last) return false;\n\t\tif (!(tmp <= last)) return false;\n\t\tif (tmp >= last) return false;\n\t\tif (last - tmp != n) return false;\n\t\tif (tmp - last != -n) return false;\n\t}\n\n\tauto end = ranges::default_sentinel;\n\n\tif (first == end) return false;\n\tif (end == first) return false;\n\tif (last != end) return false;\n\tif (end != last) return false;\n\tif (end - first != n) return false;\n\tif (first - end != -n) return false;\n\n\tauto pos = first;\n\t++pos;\n\tif (pos != first + 1) return false;\n\t--pos;\n\tif (pos != last - n) return false;\n\tpos += n;\n\tif (pos != last) return false;\n\tpos -= n;\n\tif (pos != first) return false;\n\tif (pos + 2 != 2 + pos) return false;\n\n\tif (first[3] != 3) return false;\n\n\tranges::advance(pos, 2);\n\tif (pos != first + 2) return false;\n\n\treturn true;\n}\nstatic_assert(test_constexpr());\n\nint main()\n{\n\tusing ranges::counted_iterator, ranges::common_iterator;\n\tusing ranges::default_sentinel, ranges::default_sentinel_t, ranges::sized_sentinel_for;\n\tusing ranges::distance;\n\tusing ranges::begin, ranges::size;\n\n\t{\n\t\tint rgi[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\t\tauto i = counted_iterator{forward_iterator<int*>{rgi}, size(rgi)};\n\t\tstatic_assert(std::is_same<decltype(i),counted_iterator<forward_iterator<int*>>>());\n\t\tstatic_assert(sized_sentinel_for<default_sentinel_t, decltype(i)>);\n\t\tCHECK(static_cast<std::size_t>(default_sentinel - i) == size(rgi));\n\t\tCHECK(&*i.base() == begin(rgi));\n\t\tCHECK(std::size_t(i.count()) == size(rgi));\n\t\tCHECK(std::size_t(distance(i, default_sentinel)) == size(rgi));\n\n\t\tcounted_iterator<forward_iterator<const int*>> j{i};\n\t\tusing C = common_iterator<decltype(i), default_sentinel_t>;\n\t\tCHECK(std::equal(C{i}, C{default_sentinel}, rgi));\n\t}\n\n\t{\n\t\tstd::list<int> l;\n\t\tauto a = counted_iterator{l.begin(), 0};\n\t\tauto b = counted_iterator{l.cbegin(), 0};\n\t\tstatic_assert(std::is_same<ranges::common_type_t<decltype(a), decltype(b)>, decltype(b)>());\n\t\tCHECK((a - a) == 0);\n\t\tCHECK((b - b) == 0);\n\t\tCHECK((a - b) == 0);\n\t\tCHECK((b - a) == 0);\n\t}\n\n\t{\n\t\tcounted_iterator<char*> c{nullptr, 0};\n\t\tcounted_iterator<char const*> d{c};\n\t\tstatic_assert(!ranges::assignable_from<decltype(c)&, decltype(d)>);\n\t\tCHECK((c - c) == 0);\n\t\tCHECK((d - d) == 0);\n\t\tCHECK((c - d) == 0);\n\t\tCHECK((d - c) == 0);\n\t}\n\n\t{\n\t\tint rgi[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\t\tcounted_iterator<output_iterator<int*>> e{output_iterator<int*>{rgi}, 10};\n\t\tranges::fill(e, default_sentinel, 0);\n\t\tint expected[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\t\tCHECK(std::equal(rgi, rgi + size(rgi), expected));\n\t\t// Make sure advance compiles\n\t\tranges::advance(e, 4);\n\t\tCHECK(e.base().base() == rgi + 4);\n\t\tCHECK(e.count() == 10 - 4);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/incomplete.cpp",
    "content": "#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n\nnamespace ranges = __stl2;\n\nstruct foo;\nstatic_assert(ranges::same_as<std::ptrdiff_t,ranges::iter_difference_t<foo*>>);\nstatic_assert(ranges::same_as<foo*,ranges::common_type_t<foo*, foo*>>);\nstruct foo {};\n\nstatic_assert(ranges::contiguous_iterator<foo*>);\n\nint main() {}\n"
  },
  {
    "path": "test/iterator/istream_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/iterator/istream_iterator.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n#include <sstream>\n#include \"../simple_test.hpp\"\n\nusing namespace __stl2;\n\nstruct Int {\n\tint value_;\n\n\tfriend std::istream& operator>>(std::istream& is, Int& i) {\n\t\treturn is >> i.value_;\n\t}\n};\n\nint main() {\n\t{\n\t\tusing I = istream_iterator<int>;\n\t\tstatic_assert(weakly_incrementable<I>);\n\t\tstatic_assert(same_as<iter_difference_t<I>, std::ptrdiff_t>);\n\t\tstatic_assert(readable<I>);\n\t\tstatic_assert(same_as<iter_value_t<I>, int>);\n\t\tstatic_assert(same_as<iter_reference_t<I>, const int&>);\n\t\tstatic_assert(same_as<iter_rvalue_reference_t<I>, const int&&>);\n\t\tstatic_assert(input_or_output_iterator<I>);\n\t\tstatic_assert(input_iterator<I>);\n\t\tstatic_assert(!forward_iterator<I>);\n\n\t\tstatic_assert(sentinel_for<I, I>);\n\t\tstatic_assert(sentinel_for<default_sentinel_t, I>);\n\t\tstatic_assert(common_with<default_sentinel_t, I>);\n\t\tstatic_assert(same_as<I, common_type_t<I, default_sentinel_t>>);\n\n\t\tstatic_assert(same_as<I::difference_type, std::ptrdiff_t>);\n\t\tstatic_assert(same_as<I::iterator_category, input_iterator_tag>);\n\t\tstatic_assert(same_as<I::value_type, int>);\n\t\tstatic_assert(same_as<I::reference, const int&>);\n\t\tstatic_assert(same_as<I::pointer, const int*>);\n\t\tstatic_assert(same_as<I::char_type, char>);\n\t\tstatic_assert(same_as<I::traits_type, std::char_traits<char>>);\n\t\tstatic_assert(same_as<I::istream_type, std::istream>);\n\n\t\tI{};\n\t\tI{default_sentinel};\n\t\tstd::istringstream is(\"42 13\");\n\t\tI i{is};\n\t\tI{i};\n\t\tstatic_assert(std::is_trivially_copy_constructible<I>());\n\n\t\tstatic_assert(same_as<const int&, decltype(*i)>);\n\t\tCHECK(*i == 42);\n\t\tstatic_assert(same_as<const int*, decltype(i.operator->())>);\n\t\tCHECK(&*i == i.operator->());\n\t\tstatic_assert(same_as<I&, decltype(++i)>);\n\t\tCHECK(&++i == &i);\n\t\tCHECK(*i == 13);\n\t\tstatic_assert(same_as<I, decltype(i++)>);\n\t\t{ I j{i}; CHECK(j == i++); }\n\n\t\tstatic_assert(same_as<bool, decltype(i == i)>);\n\t\tCHECK(i == i);\n\t\tstatic_assert(same_as<bool, decltype(default_sentinel == i)>);\n\t\tCHECK(default_sentinel == i);\n\t\tstatic_assert(same_as<bool, decltype(i == default_sentinel)>);\n\t\tCHECK(i == default_sentinel);\n\t\tstatic_assert(same_as<bool, decltype(i != i)>);\n\t\tCHECK(!(i != i));\n\t\tstatic_assert(same_as<bool, decltype(default_sentinel != i)>);\n\t\tCHECK(!(default_sentinel != i));\n\t\tstatic_assert(same_as<bool, decltype(i != default_sentinel)>);\n\t\tCHECK(!(i != default_sentinel));\n\t}\n\t{\n\t\tstd::istringstream is(\"5 4 3 2 1 0\");\n\t\tCHECK_EQUAL(\n\t\t\tsubrange(istream_iterator<int>{is}, default_sentinel),\n\t\t\t\t{5, 4, 3, 2, 1, 0});\n\t}\n\t{\n\t\tstd::istringstream is(\"0.9 1.8 2.4 3.3\");\n\t\tCHECK_EQUAL(\n\t\t\tsubrange(istream_iterator<double>{is}, default_sentinel),\n\t\t\t\t{0.9, 1.8, 2.4, 3.3});\n\t}\n\n\t{\n\t\tstd::istringstream is(\"5 4 3 2 1 0\");\n\t\tauto i = istream_iterator<Int>{is};\n\t\tfor (auto n = 5; i != default_sentinel && n >= 0; --n, ++i) {\n\t\t\tCHECK(i->value_ == n);\n\t\t}\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/istreambuf_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/iterator/istreambuf_iterator.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n#include <sstream>\n#include \"../simple_test.hpp\"\n\nusing namespace __stl2;\n\nnamespace {\n\ttemplate<class charT, class traits = std::char_traits<charT>>\n\tvoid validate_one() {\n\t\tusing C = __istreambuf_iterator::cursor<charT, traits>;\n\t\tstatic_assert(cursor::Cursor<C>);\n\t\tstatic_assert(same_as<typename traits::off_type, cursor::difference_type_t<C>>);\n\t\tstatic_assert(cursor::Next<C>);\n\t\tstatic_assert(same_as<charT, cursor::value_type_t<C>>);\n\t\tstatic_assert(cursor::readable<C>);\n\t\tstatic_assert(same_as<charT, cursor::reference_t<C>>);\n\t\tstatic_assert(cursor::Input<C>);\n\t\tstatic_assert(cursor::sentinel_for<C, C>);\n\t\tstatic_assert(cursor::sentinel_for<default_sentinel_t, C>);\n\t\tstatic_assert(!cursor::Forward<C>);\n\t\tstatic_assert(cursor::PostIncrement<C>);\n\n\t\tusing I = istreambuf_iterator<charT, traits>;\n\t\tstatic_assert(weakly_incrementable<I>);\n\t\tstatic_assert(same_as<typename traits::off_type, iter_difference_t<I>>);\n\t\tstatic_assert(same_as<charT, iter_value_t<I>>);\n\t\tstatic_assert(readable<I>);\n\t\tstatic_assert(same_as<charT, iter_reference_t<I>>);\n\t\tstatic_assert(same_as<charT, iter_rvalue_reference_t<I>>);\n\t\tstatic_assert(input_or_output_iterator<I>);\n\t\tstatic_assert(same_as<input_iterator_tag, iterator_category_t<I>>);\n\t\tstatic_assert(input_iterator<I>);\n\t\tstatic_assert(!forward_iterator<I>);\n\t\tstatic_assert(sentinel_for<I, I>);\n\t\tstatic_assert(sentinel_for<default_sentinel_t, I>);\n\t\tstatic_assert(common_with<I, default_sentinel_t>);\n\t\tstatic_assert(same_as<I, common_type_t<I, default_sentinel_t>>);\n\n\t\tstatic_assert(same_as<iter_value_t<I>, typename I::value_type>);\n\t\tstatic_assert(same_as<iter_difference_t<I>, typename I::difference_type>);\n\t\tstatic_assert(same_as<input_iterator_tag, typename I::iterator_category>);\n\t\tstatic_assert(same_as<charT, typename I::reference>);\n\t\tstatic_assert(same_as<traits, typename I::traits_type>);\n\t\tstatic_assert(same_as<typename traits::int_type, typename I::int_type>);\n\t\tstatic_assert(same_as<std::basic_streambuf<charT, traits>, typename I::streambuf_type>);\n\t\tstatic_assert(same_as<std::basic_istream<charT, traits>, typename I::istream_type>);\n\n\t\tauto i = I{};\n\t\tauto ci = const_cast<const I&>(i);\n\t\tCHECK(ci.equal(i));\n\t\tCHECK(ci == i);\n\t\tCHECK(!(ci != i));\n\t\tCHECK(ci == default_sentinel);\n\t\tCHECK(i == default_sentinel);\n\t\tCHECK(!(ci != default_sentinel));\n\t\tCHECK(!(i != default_sentinel));\n\n\t\tstatic_assert(same_as<decltype(i.operator->()), typename C::pointer>);\n#if 1 // FIXME: remove\n\t\tstatic_assert(!__stl2::detail::PostIncrementCursor<C>);\n\t\tstatic_assert(same_as<decltype(std::declval<C&>().post_increment()),\n\t\t\ttypename C::__proxy>);\n\t\tstatic_assert(!same_as<decltype(i++), I>);\n#endif\n\t\tstatic_assert(same_as<decltype(i++), typename C::__proxy>);\n\n\t\tstatic_assert(constructible_from<I, default_sentinel_t>);\n\t\tstatic_assert(convertible_to<default_sentinel_t, I>);\n\t\tstatic_assert(constructible_from<I, std::basic_istream<charT, traits>&>);\n\t\tstatic_assert(constructible_from<I, std::basic_streambuf<charT, traits>*>);\n\t\tstatic_assert(constructible_from<I, decltype(i++)>);\n\t}\n\n\ttemplate<class... Cs>\n\tvoid validate() {\n\t\t(validate_one<Cs>(), ...);\n\t}\n}\n\nint main() {\n\tvalidate<char, wchar_t, char16_t, char32_t>();\n\n\tusing I = istreambuf_iterator<char>;\n\t{\n\t\tstatic const char hw[] = \"Hello, world!\";\n\t\tstd::istringstream is(hw);\n\t\tCHECK_EQUAL(subrange(I{is}, default_sentinel),\n\t\t\t\t\t\t\t\t\tsubrange(hw + 0, hw + size(hw) - 1));\n\t\tCHECK(I{is} == default_sentinel);\n\t}\n\n\t{\n\t\t// Test the postincrement proxy type.\n\t\tstd::istringstream is(\"123\");\n\t\tauto i = I{is};\n\t\tCHECK(*i++ == '1');\n\t\tauto j = i++;\n\t\tCHECK(*j == '2');\n\t\tauto k = I{j};\n\t\tCHECK(*k++ == '3');\n\t\tCHECK(k == I{});\n\t\tCHECK(k == default_sentinel);\n\t}\n\n\t{\n\t\t// Test the operator-> proxy type.\n\t\tstd::istringstream is(\"123\");\n\t\tauto i = I{is};\n\t\tCHECK(*i.operator->().operator->() == '1');\n\t\t++i;\n\t\tCHECK(*i.operator->().operator->() == '2');\n\t}\n\n\t{\n\t\t// regression test for #149\n\t\tauto in = std::istringstream{};\n\t\tusing I = std::istreambuf_iterator<char>;\n\t\tCHECK(in.rdbuf() != nullptr);\n\t\tCHECK(I{in} == I{});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <cstring>\n#include <iostream>\n\n#include <stl2/iterator.hpp>\n#include <stl2/memory.hpp>\n#include <stl2/detail/raw_ptr.hpp>\n\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class T>\nstruct reference_wrapper {\nprivate:\n\tranges::detail::raw_ptr<T> ptr_;\n\n\tstatic T* f(T& t) noexcept { return std::addressof(t); }\n\tstatic void f(T&&) = delete;\npublic:\n\treference_wrapper() = default;\n\n\ttemplate<ranges::_NotSameAs<reference_wrapper> U>\n\treference_wrapper(U&& u)\n\tnoexcept(noexcept(f(static_cast<U&&>(u))))\n\trequires requires { f(static_cast<U&&>(u)); }\n\t: ptr_{f(static_cast<U&&>(u))} {}\n\n\tT& get() const noexcept {\n\t\treturn *ptr_;\n\t}\n\n\treference_wrapper& operator=(const T& t)\n\t\tnoexcept(std::is_nothrow_copy_assignable<T>::value) {\n\t\tget() = t;\n\t\treturn *this;\n\t}\n\treference_wrapper& operator=(T&& t)\n\t\tnoexcept(std::is_nothrow_move_assignable<T>::value) {\n\t\tget() = std::move(t);\n\t\treturn *this;\n\t}\n\n\tconst reference_wrapper& operator=(const T& t) const\n\t\tnoexcept(std::is_nothrow_copy_assignable<T>::value) {\n\t\tget() = t;\n\t\treturn *this;\n\t}\n\tconst reference_wrapper& operator=(T&& t) const\n\t\tnoexcept(std::is_nothrow_move_assignable<T>::value) {\n\t\tget() = std::move(t);\n\t\treturn *this;\n\t}\n\n\toperator T&() const noexcept { return get(); }\n};\n\ntemplate<class T, std::size_t N>\nstruct array {\n\tT e_[N];\n\n\tusing reference = reference_wrapper<T>;\n\tusing const_reference = reference_wrapper<const T>;\n\n\treference operator[](const std::size_t n) noexcept {\n\t\treturn {e_[n]};\n\t}\n\tconst_reference operator[](const std::size_t n) const noexcept {\n\t\treturn {e_[n]};\n\t}\n\n\tstruct iterator {\n\t\tusing iterator_category = ranges::random_access_iterator_tag;\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = T;\n\n\t\tT* ptr_;\n\n\t\titerator() = default;\n\t\titerator(T* p) noexcept : ptr_{p} {}\n\n\t\treference operator*() const noexcept {\n\t\t\tSTL2_EXPECT(ptr_);\n\t\t\treturn {*ptr_};\n\t\t}\n\n\t\tT* operator->() const noexcept\n\t\trequires std::is_class<T>::value || std::is_union<T>::value\n\t\t{\n\t\t\tSTL2_EXPECT(ptr_);\n\t\t\treturn ptr_;\n\t\t}\n\n\t\titerator& operator++() noexcept {\n\t\t\t++ptr_;\n\t\t\treturn *this;\n\t\t}\n\n\t\titerator operator++(int) noexcept {\n\t\t\tauto tmp = *this;\n\t\t\t++*this;\n\t\t\treturn tmp;\n\t\t}\n\n\t\tbool operator==(const iterator& other) const noexcept {\n\t\t\treturn ptr_ == other.ptr_;\n\t\t}\n\n\t\tbool operator!=(const iterator& other) const noexcept {\n\t\t\treturn !(*this == other);\n\t\t}\n\n\t\titerator operator+(std::ptrdiff_t n) const noexcept {\n\t\t\treturn {ptr_ + n};\n\t\t}\n\n\t\tfriend T&& iter_move(iterator i) noexcept {\n\t\t\t//std::cout << \"iter_move(\" << static_cast<void*>(i.ptr_) << \")\\n\";\n\t\t\tSTL2_EXPECT(i.ptr_);\n\t\t\treturn static_cast<T&&>(*i.ptr_);\n\t\t}\n\t};\n\n\titerator begin() { return {&e_[0]}; }\n\titerator end() { return {&e_[0] + N}; }\n};\n\nenum class category {\n\tnone, output, input, forward, bidirectional, random_access, contiguous\n};\n\nstd::ostream& operator<<(std::ostream& sout, category c) {\n\tswitch(c) {\n\tcase category::output:\n\t\treturn sout << \"category::output\";\n\tcase category::input:\n\t\treturn sout << \"category::input\";\n\tcase category::forward:\n\t\treturn sout << \"category::forward\";\n\tcase category::bidirectional:\n\t\treturn sout << \"category::bidirectional\";\n\tcase category::random_access:\n\t\treturn sout << \"category::random_access\";\n\tcase category::contiguous:\n\t\treturn sout << \"category::contiguous\";\n\tdefault:\n\t\treturn sout << \"category::none\";\n\t}\n}\n\ntemplate<class>\nconstexpr category iterator_dispatch() { return category::none; }\ntemplate<ranges::output_iterator<const int&> I>\nrequires (!ranges::input_iterator<I>)\nconstexpr category iterator_dispatch() { return category::output; }\ntemplate<ranges::input_iterator>\nconstexpr category iterator_dispatch() { return category::input; }\ntemplate<ranges::forward_iterator>\nconstexpr category iterator_dispatch() { return category::forward; }\ntemplate<ranges::bidirectional_iterator>\nconstexpr category iterator_dispatch() { return category::bidirectional; }\ntemplate<ranges::random_access_iterator>\nconstexpr category iterator_dispatch() { return category::random_access; }\ntemplate<ranges::contiguous_iterator>\nconstexpr category iterator_dispatch() { return category::contiguous; }\n\ntemplate<class C, bool EC, class R = int&>\nstruct arbitrary_iterator {\n\tusing difference_type = std::ptrdiff_t;\n\n\tarbitrary_iterator& operator*();\n\tarbitrary_iterator& operator=(std::remove_reference_t<R>);\n\n\tarbitrary_iterator& operator++();\n\tarbitrary_iterator& operator++(int);\n\n\tbool operator==(arbitrary_iterator) const\n\trequires EC;\n\tbool operator!=(arbitrary_iterator) const\n\trequires EC;\n};\n\ntemplate<ranges::derived_from<ranges::input_iterator_tag> C, bool EC, class R>\nstruct arbitrary_iterator<C, EC, R> {\n\tusing iterator_category = C;\n\tusing value_type = std::remove_reference_t<R>;\n\tusing difference_type = std::ptrdiff_t;\n\n\tR operator*() const;\n\n\tarbitrary_iterator& operator++();\n\tarbitrary_iterator operator++(int);\n\n\tbool operator==(arbitrary_iterator) const\n\trequires EC || ranges::derived_from<C, ranges::forward_iterator_tag>;\n\tbool operator!=(arbitrary_iterator) const\n\trequires EC || ranges::derived_from<C, ranges::forward_iterator_tag>;\n\n\tarbitrary_iterator& operator--()\n\trequires ranges::derived_from<C, ranges::bidirectional_iterator_tag>;\n\tarbitrary_iterator operator--(int)\n\trequires ranges::derived_from<C, ranges::bidirectional_iterator_tag>;\n\n\tbool operator<(arbitrary_iterator) const\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\tbool operator>(arbitrary_iterator) const\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\tbool operator<=(arbitrary_iterator) const\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\tbool operator>=(arbitrary_iterator) const\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\n\tarbitrary_iterator& operator+=(difference_type)\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\tarbitrary_iterator& operator-=(difference_type)\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\n\tarbitrary_iterator operator-(difference_type) const\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\tdifference_type operator-(arbitrary_iterator) const\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n\n\tvalue_type& operator[](difference_type) const\n\trequires ranges::derived_from<C, ranges::random_access_iterator_tag>;\n};\n\ntemplate<ranges::derived_from<ranges::random_access_iterator_tag> C, bool B, class R>\narbitrary_iterator<C, B, R> operator+(\n\tarbitrary_iterator<C, B, R>, typename arbitrary_iterator<C, B, R>::difference_type);\n\ntemplate<ranges::derived_from<ranges::random_access_iterator_tag> C, bool B, class R>\narbitrary_iterator<C, B, R> operator+(\n\ttypename arbitrary_iterator<C, B, R>::difference_type, arbitrary_iterator<C, B, R>);\n\nvoid test_iterator_dispatch() {\n\tCHECK(iterator_dispatch<void>() == category::none);\n\tstatic_assert(ranges::contiguous_iterator<int*>);\n\tCHECK(iterator_dispatch<int*>() == category::contiguous);\n\n\t{\n\t\tstatic_assert(ranges::readable<int* const>);\n\t}\n\n\t{\n\t\tusing I = arbitrary_iterator<ranges::input_iterator_tag, false>;\n\t\tstatic_assert(ranges::input_iterator<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::input);\n\t}\n\t{\n\t\tusing I = arbitrary_iterator<ranges::input_iterator_tag, true>;\n\t\tstatic_assert(ranges::input_iterator<I>);\n\t\tstatic_assert(ranges::equality_comparable<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::input);\n\t}\n\t{\n\t\tusing I = arbitrary_iterator<ranges::forward_iterator_tag, true>;\n\t\tstatic_assert(ranges::forward_iterator<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::forward);\n\t}\n\t{\n\t\tusing I = arbitrary_iterator<ranges::bidirectional_iterator_tag, true>;\n\t\tstatic_assert(ranges::bidirectional_iterator<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::bidirectional);\n\t}\n\t{\n\t\tusing I = arbitrary_iterator<ranges::random_access_iterator_tag, true>;\n\t\tstatic_assert(ranges::random_access_iterator<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::random_access);\n\t}\n\t{\n\t\tusing I = arbitrary_iterator<ranges::contiguous_iterator_tag, true>;\n\t\tstatic_assert(ranges::contiguous_iterator<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::contiguous);\n\t}\n\n\t{\n\t\tusing I = arbitrary_iterator<void, false>;\n\t\tstatic_assert(ranges::output_iterator<I, const int&>);\n\t\tstatic_assert(!ranges::input_iterator<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::output);\n\t}\n\t{\n\t\tusing I = arbitrary_iterator<void, true>;\n\t\tstatic_assert(ranges::output_iterator<I, const int&>);\n\t\tstatic_assert(ranges::equality_comparable<I>);\n\t\tstatic_assert(!ranges::input_iterator<I>);\n\t\tCHECK(iterator_dispatch<I>() == category::output);\n\t}\n}\n\ntemplate<ranges::input_iterator I, ranges::sentinel_for<I> S, class O>\nrequires ranges::indirectly_copyable<I, O>\nbool copy(I first, S last, O o) {\n\tfor (; first != last; ++first, ++o) {\n\t\t*o = *first;\n\t}\n\treturn false;\n}\n\ntemplate<ranges::contiguous_iterator I, ranges::sized_sentinel_for<I> S,\n\tranges::contiguous_iterator O>\nrequires\n\tranges::indirectly_copyable<I, O> &&\n\tranges::same_as<ranges::iter_value_t<I>, ranges::iter_value_t<O>> &&\n\tstd::is_trivially_copyable<ranges::iter_value_t<I>>::value\nbool copy(I first, S last, O o) {\n\tauto n = last - first;\n\tSTL2_EXPECT(n >= 0);\n\tif (n) {\n\t\tstd::memmove(std::addressof(*o), std::addressof(*first),\n\t\t\tn * sizeof(ranges::iter_value_t<I>));\n\t}\n\treturn true;\n}\n\nvoid test_copy() {\n\t{\n\t\tstruct A {\n\t\t\tint value;\n\t\t\tA(int i) : value{i} {}\n\t\t\tA(const A& that) :\n\t\t\t\tvalue{that.value} {}\n\t\t\tA& operator=(const A&) = default;\n\t\t};\n\t\tA a[] = {0,1,2,3}, b[] = {4,5,6,7};\n\t\tCHECK(!copy(ranges::begin(a) + 1, ranges::end(a) - 1, ranges::begin(b) + 1));\n\t\tCHECK(b[0].value == 4);\n\t\tCHECK(b[1].value == 1);\n\t\tCHECK(b[2].value == 2);\n\t\tCHECK(b[3].value == 7);\n\t}\n\n\t{\n\t\tint a[] = {0,1,2,3,4,5,6,7}, b[] = {7,6,5,4,3,2,1,0};\n\t\tCHECK(copy(ranges::begin(a) + 2, ranges::end(a) - 2, ranges::begin(b) + 2));\n\t\tCHECK(b[0] == 7);\n\t\tCHECK(b[1] == 6);\n\t\tCHECK(b[2] == 2);\n\t\tCHECK(b[3] == 3);\n\t\tCHECK(b[4] == 4);\n\t\tCHECK(b[5] == 5);\n\t\tCHECK(b[6] == 1);\n\t\tCHECK(b[7] == 0);\n\t}\n}\n\nvoid test_iter_swap2() {\n\t{\n\t\tint a[] = { 42, 13 };\n\t\tranges::iter_swap(a + 0, a + 1);\n\t\tCHECK(a[0] == 13);\n\t\tCHECK(a[1] == 42);\n\t\tranges::iter_swap(a + 0, a + 1);\n\t\tCHECK(a[0] == 42);\n\t\tCHECK(a[1] == 13);\n\t}\n\n\t{\n\t\tauto a = std::make_unique<int>(42);\n\t\tauto b = std::make_unique<int>(13);\n\t\tusing I = decltype(a);\n\t\tstatic_assert(ranges::same_as<I, decltype(b)>);\n\t\tstatic_assert(ranges::readable<I>);\n\t\tusing R = ranges::iter_reference_t<I>;\n\t\tstatic_assert(ranges::same_as<int&, R>);\n\t\tusing RR = ranges::iter_rvalue_reference_t<I>;\n\t\tstatic_assert(ranges::same_as<int&&, RR>);\n\t\tstatic_assert(ranges::swappable_with<R, R>);\n\n\t\t// swappable<R, R> is true, calls the first overload of\n\t\t// iter_swap (which delegates to swap(*a, *b)):\n\t\tranges::iter_swap(a, b);\n\t\tCHECK(*a == 13);\n\t\tCHECK(*b == 42);\n\t\tranges::iter_swap(a, b);\n\t\tCHECK(*a == 42);\n\t\tCHECK(*b == 13);\n\t}\n\n\t{\n\t\tauto a = array<int, 4>{0,1,2,3};\n\t\tusing I = decltype(a.begin());\n\t\tstatic_assert(ranges::readable<I>);\n\t\tusing V = ranges::iter_value_t<I>;\n\t\tstatic_assert(ranges::same_as<int, V>);\n\t\tusing R = ranges::iter_reference_t<I>;\n\t\tstatic_assert(ranges::same_as<reference_wrapper<int>, R>);\n\t\tusing RR = ranges::iter_rvalue_reference_t<I>;\n\t\tstatic_assert(ranges::same_as<int&&, RR>);\n\n\t\tstatic_assert(ranges::same_as<I, decltype(a.begin() + 2)>);\n\t\tstatic_assert(ranges::common_reference_with<const R&, const R&>);\n\t\tstatic_assert(!ranges::swappable_with<R, R>);\n\t\tstatic_assert(ranges::indirectly_movable_storable<I, I>);\n\n\t\t// swappable<R, R> is not satisfied, and\n\t\t// indirectly_movable_storable<I, I> is satisfied,\n\t\t// so this should resolve to the second overload of iter_swap.\n\t\tranges::iter_swap(a.begin() + 1, a.begin() + 3);\n\t\tCHECK(a[0] == 0);\n\t\tCHECK(a[1] == 3);\n\t\tCHECK(a[2] == 2);\n\t\tCHECK(a[3] == 1);\n\t}\n}\n\ntemplate<class T>\nconstexpr bool has_category = false;\ntemplate<class T>\nrequires requires { typename T::iterator_category; }\nconstexpr bool has_category<T> = true;\n\nvoid test_std_traits() {\n#if STL2_HOOK_ITERATOR_TRAITS\n\tusing WO = arbitrary_iterator<void, false>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<WO>::iterator_category,\n\t\tstd::output_iterator_tag>);\n\n\tusing O = arbitrary_iterator<void, true>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<O>::iterator_category,\n\t\tstd::output_iterator_tag>);\n\n\tusing WI = arbitrary_iterator<ranges::input_iterator_tag, false>;\n\tstatic_assert(!has_category<std::iterator_traits<WI>>);\n\n\tusing I = arbitrary_iterator<ranges::input_iterator_tag, true>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<I>::iterator_category,\n\t\tstd::input_iterator_tag>);\n\n\tusing F = arbitrary_iterator<ranges::forward_iterator_tag, true>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<F>::iterator_category,\n\t\tstd::forward_iterator_tag>);\n\n\tusing B = arbitrary_iterator<ranges::bidirectional_iterator_tag, true>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<B>::iterator_category,\n\t\tstd::bidirectional_iterator_tag>);\n\n\tusing R = arbitrary_iterator<ranges::random_access_iterator_tag, true>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<R>::iterator_category,\n\t\tstd::random_access_iterator_tag>);\n\n\tusing C = arbitrary_iterator<ranges::contiguous_iterator_tag, true>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<C>::iterator_category,\n\t\tstd::random_access_iterator_tag>);\n\n\tusing IV = arbitrary_iterator<ranges::input_iterator_tag, true, int>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<IV>::iterator_category,\n\t\tstd::input_iterator_tag>);\n\n\tusing FV = arbitrary_iterator<ranges::forward_iterator_tag, true, int>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<FV>::iterator_category,\n\t\tstd::input_iterator_tag>);\n\n\tusing BV = arbitrary_iterator<ranges::bidirectional_iterator_tag, true, int>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<BV>::iterator_category,\n\t\tstd::input_iterator_tag>);\n\n\tusing RV = arbitrary_iterator<ranges::random_access_iterator_tag, true, int>;\n\tstatic_assert(ranges::same_as<std::iterator_traits<RV>::iterator_category,\n\t\tstd::input_iterator_tag>);\n#endif // STL2_HOOK_ITERATOR_TRAITS\n}\n\nstruct MakeString {\n\tusing value_type = std::string;\n\tstd::string operator*() const;\n};\n\nstatic_assert(ranges::readable<MakeString>);\nstatic_assert(!ranges::writable<MakeString, std::string>);\nstatic_assert(!ranges::writable<MakeString, const std::string &>);\nstatic_assert(!ranges::indirectly_movable<MakeString, MakeString>);\nstatic_assert(!ranges::indirectly_copyable<MakeString, MakeString>);\nstatic_assert(!ranges::indirectly_swappable<MakeString, MakeString>);\n\nint main() {\n\ttest_iter_swap2();\n\ttest_iterator_dispatch();\n\ttest_copy();\n\ttest_std_traits();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/make_range.cpp",
    "content": "#include <stl2/iterator.hpp>\n#include \"../simple_test.hpp\"\n\nusing namespace __stl2;\n\nint main() {\n\t{\n\t\tusing I = subrange<int*, int*>;\n\t\tusing CI = subrange<const int*, const int*>;\n\t\tstatic_assert(view<I>);\n\t\tstatic_assert(sized_range<I>);\n\t\tstatic_assert(contiguous_range<I>);\n\t\tstatic_assert(common_range<I>);\n\t\tstatic_assert(view<CI>);\n\t\tstatic_assert(sized_range<CI>);\n\t\tstatic_assert(contiguous_range<CI>);\n\t\tstatic_assert(common_range<CI>);\n\t}\n\n\t{\n\t\tstatic constexpr int some_ints[] = {2, 3, 5, 7, 11, 13};\n\t\tstatic constexpr std::size_t n = size(some_ints);\n\t\tauto r = subrange(some_ints + 0, some_ints + n);\n\t\tusing R = decltype(r);\n\t\tstatic_assert(view<R>);\n\t\tstatic_assert(sized_range<R>);\n\t\tstatic_assert(contiguous_range<R>);\n\t\tstatic_assert(common_range<R>);\n\n\t\tCHECK(begin(r) == some_ints + 0);\n\t\tCHECK(end(r) == some_ints + n);\n\t\tCHECK(!empty(r));\n\t\tCHECK(std::size_t(size(r)) == n);\n\t\tCHECK(data(r) == some_ints);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/iterator/move_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <numeric>\n#include <memory>\n#include <utility>\n#include <vector>\n#include <stl2/iterator.hpp>\n#include <stl2/functional.hpp>\n#include <stl2/detail/algorithm/copy.hpp>\n#include <stl2/detail/algorithm/equal.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/take.hpp>\n#include <stl2/view/repeat_n.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nstruct A {\n\tstatic std::size_t copy_count;\n\tstatic std::size_t move_count;\n\tint i{0};\n\n\tstatic void clear() { copy_count = move_count = 0; }\n\n\tA() = default;\n\tA(int i) : i(i) {}\n\tA(const A& that) : i(that.i) { ++copy_count; }\n\tA(A&& that) noexcept : i(that.i) { ++move_count; that.i = -1; }\n\tA& operator=(const A& that) & { ++copy_count; i = that.i; return *this; }\n\tA& operator=(A&& that) & noexcept {\n\t\t++move_count;\n\t\ti = that.i;\n\t\tthat.i = -1;\n\t\treturn *this;\n\t}\n\tfriend bool operator==(A a, A b) {\n\t\treturn a.i == b.i;\n\t}\n\tfriend bool operator!=(A a, A b) {\n\t\treturn !(a == b);\n\t}\n};\n\nstd::size_t A::copy_count;\nstd::size_t A::move_count;\n\nvoid test_move_iterator() {\n\tstatic constexpr std::size_t N = 42;\n\tstd::vector<A> vec(N);\n\tstd::vector<A> vec2;\n\tvec2.reserve(ranges::size(vec));\n\n\tA::clear();\n\n\t{\n\t\tauto first = ranges::make_move_iterator(ranges::begin(vec)),\n\t\t\tlast = ranges::make_move_iterator(ranges::end(vec));\n\t\tstatic_assert(ranges::random_access_iterator<decltype(ranges::begin(vec))>);\n\t\tstatic_assert(ranges::input_iterator<decltype(first)>);\n\t\tstatic_assert(!ranges::forward_iterator<decltype(first)>);\n\t\tauto out = ranges::back_inserter(vec2);\n\n\t\tfor (; first != last; ++first, ++out) {\n\t\t\t*out = *first;\n\t\t}\n\t}\n\n\tCHECK(ranges::size(vec2) == N);\n\tCHECK(A::copy_count == std::size_t{0});\n\tCHECK(A::move_count == N);\n}\n\nvoid test_iter_move() {\n\tstatic constexpr std::size_t N = 42;\n\tstd::vector<A> vec(N);\n\tstd::vector<A> vec2;\n\tvec2.reserve(ranges::size(vec));\n\n\tA::clear();\n\n\t{\n\t\tauto first = ranges::begin(vec),\n\t\t\tlast = ranges::end(vec);\n\t\tauto out = ranges::back_inserter(vec2);\n\n\t\tfor (; first != last; ++first, ++out) {\n\t\t\t*out = ranges::iter_move(first);\n\t\t}\n\t}\n\n\tCHECK(ranges::size(vec2) == N);\n\tCHECK(A::copy_count == std::size_t{0});\n\tCHECK(A::move_count == N);\n}\n\nvoid test_both() {\n\tstatic constexpr std::size_t N = 42;\n\tstd::vector<A> vec(N);\n\tstd::vector<A> vec2;\n\tvec2.reserve(ranges::size(vec));\n\n\tA::clear();\n\n\t{\n\t\tauto first = ranges::make_move_iterator(ranges::begin(vec)),\n\t\t\tlast = ranges::make_move_iterator(ranges::end(vec));\n\t\tauto out = ranges::back_inserter(vec2);\n\n\t\tfor (; first != last; ++first, ++out) {\n\t\t\t*out = ranges::iter_move(first);\n\t\t}\n\t}\n\n\tCHECK(ranges::size(vec2) == N);\n\tCHECK(A::copy_count == std::size_t{0});\n\tCHECK(A::move_count == N);\n}\n\ntemplate<class T>\nclass proxy_iterator {\npublic:\n\tusing value_type = T;\n\tusing difference_type = std::ptrdiff_t;\n\tusing iterator_category = ranges::input_iterator_tag;\n\n\tproxy_iterator() = default;\n\texplicit proxy_iterator(T* p) :\n\t\tptr_{std::make_shared<T*>(p)} {}\n\n\tstruct readable_proxy {\n\t\tusing value_type = T;\n\t\tmutable T cache_;\n\t\tT& operator*() const noexcept {\n\t\t\treturn cache_;\n\t\t}\n\t\tfriend T&& iter_move(const readable_proxy& p) noexcept {\n\t\t\treturn std::move(p.cache_);\n\t\t}\n\t};\n\n\tranges::reference_wrapper<T> operator*() const {\n\t\treturn ranges::reference_wrapper<T>{**ptr_};\n\t}\n\n\tbool operator==(const proxy_iterator& that) const {\n\t\treturn *ptr_ == *that.ptr_;\n\t}\n\tbool operator!=(const proxy_iterator& that) const {\n\t\treturn !(*this == that);\n\t}\n\n\tproxy_iterator& operator++() & {\n\t\t// Input iterator is destructive!\n\t\t(*ptr_)->i = -1;\n\t\t++*ptr_;\n\t\treturn *this;\n\t}\n\treadable_proxy operator++(int) & {\n\t\tstruct guard { // Just a weeee hack.\n\t\t\tproxy_iterator& self_;\n\t\t\t~guard() { ++self_; }\n\t\t} _{*this};\n\t\treturn readable_proxy{ranges::iter_move(*ptr_)};\n\t}\n\n\tfriend T&& iter_move(const proxy_iterator& p) {\n\t\treturn ranges::iter_move(*p.ptr_);\n\t}\n\nprivate:\n\tstd::shared_ptr<T*> ptr_;\n};\n\nvoid test_proxy_iterator() {\n\tstatic constexpr std::size_t N = 42;\n\tstd::vector<A> vec(N);\n\tstd::vector<A> vec2;\n\tvec2.reserve(ranges::size(vec));\n\n\tstatic_assert(\n\t\tranges::same_as<\n\t\t\tranges::iter_reference_t<proxy_iterator<A>>,\n\t\t\tranges::reference_wrapper<A>>);\n\tstatic_assert(\n\t\tranges::same_as<\n\t\t\tranges::iter_reference_t<const proxy_iterator<A>>,\n\t\t\tranges::reference_wrapper<A>>);\n\tstatic_assert(\n\t\tranges::same_as<\n\t\t\tranges::iter_rvalue_reference_t<proxy_iterator<A>>,\n\t\t\tA&&>);\n\n\t{\n\t\tstatic_assert(\n\t\t\tranges::same_as<\n\t\t\t\tranges::iter_rvalue_reference_t<\n\t\t\t\t\tranges::move_iterator<proxy_iterator<A>>>,\n\t\t\t\tA&&>);\n\t\tauto first = ranges::make_move_iterator(proxy_iterator<A>{ranges::data(vec)}),\n\t\t\tlast = ranges::make_move_iterator(proxy_iterator<A>{ranges::data(vec) + ranges::size(vec)});\n\t\tauto out = ranges::back_inserter(vec2);\n\n\t\tstd::iota(vec.begin(), vec.end(), 0);\n\t\tvec2.clear();\n\t\tA::clear();\n\t\tstd::copy(first, last, out);\n\n\t\tCHECK(ranges::size(vec2) == N);\n\t\tCHECK(A::copy_count == std::size_t{0});\n\t\tCHECK(A::move_count == N);\n\t\tCHECK(ranges::equal(vec2, ranges::views::iota(0) | ranges::views::take(N), std::equal_to{}));\n\t\tCHECK(ranges::equal(vec, ranges::views::ext::repeat_n(-1, N), std::equal_to{}));\n\n\t\tfirst = ranges::make_move_iterator(proxy_iterator<A>{ranges::data(vec)});\n\t\tstd::iota(vec.begin(), vec.end(), 0);\n\t\tvec2.clear();\n\t\tA::clear();\n\t\twhile (first != last) // Test post-increment\n\t\t\t*out++ = *first++;\n\n\t\tCHECK(ranges::size(vec2) == N);\n\t\tCHECK(A::copy_count == std::size_t{0});\n\t\tCHECK(A::move_count == 2*N);\n\t\tCHECK(ranges::equal(vec2, ranges::views::iota(0) | ranges::views::take(N), std::equal_to{}));\n\t\tCHECK(ranges::equal(vec, ranges::views::ext::repeat_n(-1, N), std::equal_to{}));\n\t}\n\n\t{\n\t\tstatic_assert(\n\t\t\tranges::same_as<\n\t\t\t\tranges::iter_rvalue_reference_t<\n\t\t\t\t\tranges::counted_iterator<proxy_iterator<A>>>,\n\t\t\t\tA&&>);\n\t\tstatic_assert(\n\t\t\tranges::same_as<\n\t\t\t\tranges::iter_rvalue_reference_t<\n\t\t\t\t\tranges::move_iterator<\n\t\t\t\t\t\tranges::counted_iterator<proxy_iterator<A>>>>,\n\t\t\t\tA&&>);\n\t\tauto first = ranges::make_move_iterator(\n\t\t\tranges::counted_iterator{\n\t\t\t\tproxy_iterator<A>{ranges::data(vec)}, ranges::distance(vec)});\n\t\tauto out = ranges::back_inserter(vec2);\n\n\t\tstd::iota(vec.begin(), vec.end(), 0);\n\t\tvec2.clear();\n\t\tA::clear();\n\t\tranges::copy(first, ranges::move_sentinel<ranges::default_sentinel_t>{}, out);\n\n\t\tCHECK(ranges::size(vec2) == N);\n\t\tCHECK(A::copy_count == std::size_t{0});\n\t\tCHECK(A::move_count == N);\n\t}\n\n\t{\n\t\tauto first = ranges::counted_iterator(vec.begin(), vec.size());\n\t\tauto last = ranges::default_sentinel;\n\t\tstatic_assert(ranges::sized_sentinel_for<decltype(last), decltype(first)>);\n\t\tCHECK((static_cast<std::size_t>(last - first) == vec.size()));\n\t\tauto mfirst = ranges::make_move_iterator(first);\n\t\tauto mlast = ranges::make_move_sentinel(last);\n\t\tstatic_assert(ranges::sized_sentinel_for<decltype(mlast), decltype(mfirst)>);\n\t\tCHECK((static_cast<std::size_t>(mlast - mfirst) == vec.size()));\n\t}\n}\n\nconstexpr bool test_constexpr() {\n\tstruct Int {\n\t\tint i_;\n\t\tconstexpr Int(int i) noexcept\n\t\t: i_{i}\n\t\t{}\n\t\tconstexpr Int(const Int&) noexcept = default;\n\t\tconstexpr Int& operator=(const Int&) & noexcept = default;\n\t\tconstexpr Int(Int&& that) noexcept\n\t\t: i_{that.i_}\n\t\t{ that.i_ = -1; }\n\t\tconstexpr Int& operator=(Int&& that) & noexcept {\n\t\t\ti_ = that.i_;\n\t\t\tthat.i_ = -1;\n\t\t\treturn *this;\n\t\t}\n\t\tconstexpr operator int() const { return i_; }\n\t};\n\tInt some_ints[] = {0,1,2,3};\n\n\t{ constexpr ranges::move_iterator<int*> unused{}; (void)unused; }\n\n\tauto const first = ranges::make_move_iterator(ranges::begin(some_ints));\n\tif (first.base() != ranges::begin(some_ints)) return false;\n\tauto const last = ranges::make_move_iterator(ranges::end(some_ints));\n\tif (last.base() != ranges::end(some_ints)) return false;\n\n\tif (first == last) return false;\n\tif (!(first != last)) return false;\n\tif (!(first < last)) return false;\n\tif (first > last) return false;\n\tif (!(first <= last)) return false;\n\tif (first >= last) return false;\n\tif (last - first != 4) return false;\n\tif (first - last != -4) return false;\n#if !STL2_WORKAROUND_MSVC_849755 // \"workaround\"\n\tif (Int{*(first + 2)} != 2) return false;\n\tif (*(first + 2) != -1) return false;\n#endif // STL2_WORKAROUND_MSVC_849755\n\t{\n\t\tranges::move_iterator<Int const*> tmp{first};\n\t\ttmp = first;\n\t\tif (tmp == last) return false;\n\t\tif (!(tmp != last)) return false;\n\t\tif (!(tmp < last)) return false;\n\t\tif (tmp > last) return false;\n\t\tif (!(tmp <= last)) return false;\n\t\tif (tmp >= last) return false;\n\t\tif (last - tmp != 4) return false;\n\t\tif (tmp - last != -4) return false;\n\t\tif (Int{*(tmp + 3)} != 3) return false;\n\t\tif (*(tmp + 3) != 3) return false;\n\t}\n\n\tauto end = ranges::make_move_sentinel(ranges::end(some_ints));\n\n\tif (first == end) return false;\n\tif (end == first) return false;\n\tif (last != end) return false;\n\tif (end != last) return false;\n\tif (end - first != 4) return false;\n\tif (first - end != -4) return false;\n\t{\n\t\tranges::move_sentinel<Int const*> tmp{end};\n\t\ttmp = end;\n\t\tif (first == tmp) return false;\n\t\tif (tmp == first) return false;\n\t\tif (last != tmp) return false;\n\t\tif (tmp != last) return false;\n\t\tif (tmp - first != 4) return false;\n\t\tif (first - tmp != -4) return false;\n\t}\n\n\tauto pos = first;\n\t++pos;\n\tif (pos != first + 1) return false;\n\t--pos;\n\tif (pos != last - 4) return false;\n\tpos += 4;\n\tif (pos != last) return false;\n\tpos -= 4;\n\tif (pos != first) return false;\n\tif (pos + 2 != 2 + pos) return false;\n\n#if !STL2_WORKAROUND_MSVC_849755 // \"workaround\"\n\tif (Int{first[3]} != 3) return false;\n\tif (first[3] != -1) return false;\n#endif // STL2_WORKAROUND_MSVC_849755\n\n\treturn true;\n}\nstatic_assert(test_constexpr());\n\nint main() {\n\ttest_move_iterator();\n\ttest_iter_move();\n\ttest_both();\n\ttest_proxy_iterator();\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/operations.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/iterator/operations.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/take_exactly.hpp>\n#include <stl2/detail/iterator/basic_iterator.hpp>\n\nnamespace ranges = __stl2;\n\nnamespace {\n    template<class T, std::size_t N, bool Bidi = true>\n    struct unsized_range {\n        T array_[N];\n\n        struct cursor {\n            const T* ptr_;\n\n            constexpr const T& read() const noexcept { return *ptr_; }\n            constexpr void next() noexcept { ++ptr_; }\n            constexpr void prev() noexcept requires Bidi { --ptr_; }\n            constexpr bool equal(cursor that) const noexcept { return ptr_ == that.ptr_; }\n        };\n\n        using iterator = ranges::basic_iterator<cursor>;\n        constexpr iterator begin() const noexcept { return iterator{cursor{array_ + 0}}; }\n        constexpr iterator end() const noexcept { return iterator{cursor{array_ + N}}; }\n    };\n\n    constexpr bool test_advance() {\n        {\n            constexpr int rng[] = {0,1,2,3};\n            auto pos = ranges::begin(rng);\n            // advance(i, n)\n            ranges::advance(pos, 1);\n            if (pos != rng + 1) return false;\n            ranges::advance(pos, -1);\n            if (pos != rng + 0) return false;\n            ranges::advance(pos, 3);\n            if (pos != rng + 3) return false;\n            // advance(i, s)\n            ranges::advance(pos, ranges::end(rng));\n            if (pos != rng + 4) return false;\n            // advance(i, n, s)\n            pos = ranges::begin(rng);\n            if (ranges::advance(pos, -10, pos) != -10) return false;\n            if (ranges::advance(pos, 2, ranges::end(rng)) != 0) return false;\n            if (pos != rng + 2) return false;\n            if (ranges::advance(pos, 42, ranges::end(rng)) != 40) return false;\n            if (pos != rng + 4) return false;\n            // advance(i, n, i)\n            if (ranges::advance(pos, -2, ranges::begin(rng)) != 0) return false;\n            if (pos != rng + 2) return false;\n            if (ranges::advance(pos, -42, ranges::begin(rng)) != -40) return false;\n            if (pos != rng + 0) return false;\n        }\n\n        {\n            auto rng = ranges::ext::take_exactly_view<ranges::iota_view<int>>{{}, 42};\n            static_assert(ranges::random_access_range<decltype(rng)>);\n            auto pos = ranges::begin(rng);\n            // advance(i, n)\n            ranges::advance(pos, 1);\n            if (*pos != 1) return false;\n            ranges::advance(pos, -1);\n            if (pos != ranges::begin(rng)) return false;\n            ranges::advance(pos, 3);\n            if (*pos != 3) return false;\n            // advance(i, s)\n            ranges::advance(pos, ranges::end(rng));\n            if (pos != ranges::begin(rng) + 42) return false;\n            // advance(i, n, s)\n            pos = ranges::begin(rng);\n            if (ranges::advance(pos, 2, ranges::end(rng)) != 0) return false;\n            if (pos != ranges::begin(rng) + 2) return false;\n            if (ranges::advance(pos, 42, ranges::end(rng)) != 2) return false;\n            if (pos != ranges::begin(rng) + 42) return false;\n            // advance(i, n, i)\n            if (ranges::advance(pos, -2, ranges::begin(rng)) != 0) return false;\n            if (pos != ranges::begin(rng) + 40) return false;\n            if (ranges::advance(pos, -42, ranges::begin(rng)) != -2) return false;\n            if (pos != ranges::begin(rng) + 0) return false;\n        }\n\n        {\n            constexpr unsized_range<int, 4> rng = {0,1,2,3};\n            auto pos = ranges::begin(rng);\n            // advance(i, n)\n            ranges::advance(pos, 1);\n            if (*pos != 1) return false;\n            ranges::advance(pos, -1);\n            if (pos != ranges::begin(rng)) return false;\n            ranges::advance(pos, 3);\n            if (*pos != 3) return false;\n            // advance(i, s)\n            auto saved = pos;\n            ranges::advance(pos, ranges::end(rng));\n            if (pos != ++saved) return false;\n            // advance(i, n, s)\n            pos = ranges::begin(rng);\n            if (ranges::advance(pos, 2, ranges::end(rng)) != 0) return false;\n            if (*pos != 2) return false;\n            if (ranges::advance(pos, 42, ranges::end(rng)) != 40) return false;\n            if (pos != saved) return false;\n            // advance(i, n, i)\n            if (ranges::advance(pos, -2, ranges::begin(rng)) != 0) return false;\n            if (*pos != 2) return false;\n            if (ranges::advance(pos, -42, ranges::begin(rng)) != -40) return false;\n            if (pos != ranges::begin(rng)) return false;\n        }\n\n        {\n            constexpr unsized_range<int, 4, false> rng = {0,1,2,3};\n            auto pos = ranges::begin(rng);\n            // advance(i, n)\n            ranges::advance(pos, 1);\n            if (*pos != 1) return false;\n            pos = ranges::begin(rng);\n            ranges::advance(pos, 3);\n            if (*pos != 3) return false;\n            // advance(i, s)\n            auto saved = pos;\n            ranges::advance(pos, ranges::end(rng));\n            if (pos != ++saved) return false;\n            // advance(i, n, s)\n            pos = ranges::begin(rng);\n            if (ranges::advance(pos, 2, ranges::end(rng)) != 0) return false;\n            if (*pos != 2) return false;\n            if (ranges::advance(pos, 42, ranges::end(rng)) != 40) return false;\n            if (pos != saved) return false;\n        }\n\n        return true;\n    }\n    static_assert(test_advance());\n\n    constexpr bool test_next() {\n        {\n            constexpr int rng[] = {0,1,2,3};\n            // next(i, n)\n            auto pos = ranges::next(ranges::begin(rng), 1);\n            if (pos != rng + 1) return false;\n            pos = ranges::next(pos, -1);\n            if (pos != rng + 0) return false;\n            pos = ranges::next(pos, 3);\n            if (pos != rng + 3) return false;\n            // next(i, s)\n            pos = ranges::next(pos, ranges::end(rng));\n            if (pos != rng + 4) return false;\n            // next(i, n, s)\n            pos = ranges::next(ranges::begin(rng), 2, ranges::end(rng));\n            if (pos != rng + 2) return false;\n            pos = ranges::next(pos, 42, ranges::end(rng));\n            if (pos != rng + 4) return false;\n            // next(i, n, i)\n            pos = ranges::next(pos, -2, ranges::begin(rng));\n            if (pos != rng + 2) return false;\n            pos = ranges::next(pos, -42, ranges::begin(rng));\n            if (pos != rng + 0) return false;\n        }\n\n        {\n            auto rng = ranges::ext::take_exactly_view<ranges::iota_view<int>>{{}, 42};\n            static_assert(ranges::random_access_range<decltype(rng)>);\n            // next(i, n)\n            auto pos = ranges::next(ranges::begin(rng), 1);\n            if (*pos != 1) return false;\n            pos = ranges::next(pos, -1);\n            if (pos != ranges::begin(rng)) return false;\n            pos = ranges::next(pos, 3);\n            if (*pos != 3) return false;\n            // next(i, s)\n            pos = ranges::next(pos, ranges::end(rng));\n            if (pos != ranges::begin(rng) + 42) return false;\n            // next(i, n, s)\n            pos = ranges::next(ranges::begin(rng), 2, ranges::end(rng));\n            if (pos != ranges::begin(rng) + 2) return false;\n            pos = ranges::next(pos, 42, ranges::end(rng));\n            if (pos != ranges::begin(rng) + 42) return false;\n            // next(i, n, i)\n            pos = ranges::next(pos, -2, ranges::begin(rng));\n            if (pos != ranges::begin(rng) + 40) return false;\n            pos = ranges::next(pos, -42, ranges::begin(rng));\n            if (pos != ranges::begin(rng) + 0) return false;\n        }\n\n        {\n            constexpr unsized_range<int, 4> rng = {0,1,2,3};\n            // next(i, n)\n            auto pos = ranges::next(ranges::begin(rng), 1);\n            if (*pos != 1) return false;\n            pos = ranges::next(pos, -1);\n            if (pos != ranges::begin(rng)) return false;\n            pos = ranges::next(pos, 3);\n            if (*pos != 3) return false;\n            // next(i, s)\n            auto saved = pos;\n            pos = ranges::next(pos, ranges::end(rng));\n            if (pos != ++saved) return false;\n            // next(i, n, s)\n            pos = ranges::begin(rng);\n            pos = ranges::next(pos, 2, ranges::end(rng));\n            if (*pos != 2) return false;\n            pos = ranges::next(pos, 42, ranges::end(rng));\n            if (pos != saved) return false;\n            // next(i, n, i)\n            pos = ranges::next(pos, -2, ranges::begin(rng));\n            if (*pos != 2) return false;\n            pos = ranges::next(pos, -42, ranges::begin(rng));\n            if (pos != ranges::begin(rng)) return false;\n        }\n\n        {\n            constexpr unsized_range<int, 4, false> rng = {0,1,2,3};\n            // next(i, n)\n            auto pos = ranges::next(ranges::begin(rng), 1);\n            if (*pos != 1) return false;\n            pos = ranges::begin(rng);\n            pos = ranges::next(pos, 3);\n            if (*pos != 3) return false;\n            // next(i, s)\n            auto saved = pos;\n            pos = ranges::next(pos, ranges::end(rng));\n            if (pos != ++saved) return false;\n            // next(i, n, s)\n            pos = ranges::begin(rng);\n            pos = ranges::next(pos, 2, ranges::end(rng));\n            if (*pos != 2) return false;\n            pos = ranges::next(pos, 42, ranges::end(rng));\n            if (pos != saved) return false;\n        }\n\n        return true;\n    }\n    static_assert(test_next());\n\n    constexpr bool test_prev() {\n        {\n            constexpr int rng[] = {0,1,2,3};\n            // prev(i, n)\n            auto pos = ranges::prev(ranges::end(rng), 1);\n            if (pos != rng + 3) return false;\n            pos = ranges::prev(pos, -1);\n            if (pos != rng + 4) return false;\n            // prev(i, n, i)\n            pos = ranges::prev(pos, 2, ranges::begin(rng));\n            if (pos != rng + 2) return false;\n            pos = ranges::prev(pos, 42, ranges::begin(rng));\n            if (pos != rng + 0) return false;\n        }\n\n        {\n            auto rng = ranges::ext::take_exactly_view<ranges::iota_view<int>>{{}, 42};\n            static_assert(ranges::random_access_range<decltype(rng)>);\n            // prev(i, n)\n            auto pos = ranges::prev(ranges::next(ranges::begin(rng), ranges::end(rng)), 1);\n            if (pos != ranges::begin(rng) + 41) return false;\n            pos = ranges::prev(pos, -1);\n            if (pos != ranges::begin(rng) + 42) return false;\n            // prev(i, n, i)\n            pos = ranges::prev(pos, 2, ranges::begin(rng));\n            if (pos != ranges::begin(rng) + 40) return false;\n            pos = ranges::prev(pos, 42, ranges::begin(rng));\n            if (pos != ranges::begin(rng) + 0) return false;\n        }\n\n        {\n            constexpr unsized_range<int, 4> rng = {0,1,2,3};\n            // prev(i, n)\n            auto pos = ranges::prev(ranges::end(rng), 1);\n            if (*pos != 3) return false;\n            pos = ranges::prev(pos, -1);\n            if (pos != ranges::end(rng)) return false;\n            // prev(i, n, i)\n            pos = ranges::prev(ranges::end(rng), 2, ranges::begin(rng));\n            if (*pos != 2) return false;\n            pos = ranges::prev(pos, 42, ranges::begin(rng));\n            if (pos != ranges::begin(rng)) return false;\n        }\n\n        return true;\n    }\n    static_assert(test_prev());\n\n    constexpr bool test_distance() {\n        {\n            constexpr int rng[] = {0,1,2,3};\n            if (ranges::distance(rng) != 4) return false;\n            if (ranges::distance(ranges::begin(rng), ranges::end(rng)) != 4) return false;\n            {\n                auto [bound, n] = ranges::ext::enumerate(rng);\n                if (bound != ranges::end(rng) || n != 4) return false;\n            }\n            {\n                auto [bound, n] = ranges::ext::enumerate(ranges::begin(rng), ranges::end(rng));\n                if (bound != ranges::end(rng) || n != 4) return false;\n            }\n        }\n\n        {\n            auto rng = ranges::ext::take_exactly_view<ranges::iota_view<int>>{{}, 42};\n            if (ranges::distance(rng) != 42) return false;\n            if (ranges::distance(ranges::begin(rng), ranges::end(rng)) != 42) return false;\n            {\n                auto result = ranges::ext::enumerate(rng);\n                if (result.count != 42) return false;\n                if (result.end != ranges::default_sentinel) return false;\n            }\n            {\n                auto result = ranges::ext::enumerate(ranges::begin(rng), ranges::end(rng));\n                if (result.count != 42) return false;\n                if (result.end != ranges::default_sentinel) return false;\n            }\n        }\n\n        {\n            constexpr unsized_range<int, 4> rng = {0,1,2,3};\n            if (ranges::distance(rng) != 4) return false;\n            if (ranges::distance(ranges::begin(rng), ranges::end(rng)) != 4) return false;\n            {\n                auto [bound, n] = ranges::ext::enumerate(rng);\n                if (bound != ranges::end(rng) || n != 4) return false;\n            }\n            {\n                auto [bound, n] = ranges::ext::enumerate(ranges::begin(rng), ranges::end(rng));\n                if (bound != ranges::end(rng) || n != 4) return false;\n            }\n        }\n\n        {\n            constexpr unsized_range<int, 4, false> rng = {0,1,2,3};\n            if (ranges::distance(rng) != 4) return false;\n            if (ranges::distance(ranges::begin(rng), ranges::end(rng)) != 4) return false;\n            {\n                auto [bound, n] = ranges::ext::enumerate(rng);\n                if (bound != ranges::end(rng) || n != 4) return false;\n            }\n            {\n                auto [bound, n] = ranges::ext::enumerate(ranges::begin(rng), ranges::end(rng));\n                if (bound != ranges::end(rng) || n != 4) return false;\n            }\n        }\n\n        return true;\n    }\n    static_assert(test_distance());\n} // unnamed namespace\n\nint main() {}\n"
  },
  {
    "path": "test/iterator/ostream_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/iterator/ostream_iterator.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/utility.hpp>\n#include <sstream>\n#include \"../simple_test.hpp\"\n\nusing namespace __stl2;\n\nnamespace {\n\ttemplate<class I, class O>\n\tstruct result {\n\t\tI in;\n\t\tO out;\n\t};\n\n\ttemplate<input_iterator I, sentinel_for<I> S, output_iterator<iter_reference_t<I>> O>\n\tconstexpr result<I, O> copy(I first, S last, O out) {\n\t\tfor (; first != last; ++first, void(), ++out) {\n\t\t\t*out = *first;\n\t\t}\n\t\treturn {first, out};\n\t}\n}\n\nint main() {\n\tstd::stringstream ss;\n\tstatic constexpr int some_ints[] = {0, 7, 1, 6, 2, 5, 3, 4};\n\n\tusing I = ostream_iterator<int>;\n\tstatic_assert(weakly_incrementable<I>);\n\tstatic_assert(same_as<iter_difference_t<I>, std::ptrdiff_t>);\n\tstatic_assert(input_or_output_iterator<I>);\n\tstatic_assert(same_as<iter_reference_t<I>, I&>);\n\tstatic_assert(output_iterator<I, const int&>);\n\tstatic_assert(!input_iterator<I>);\n\n\tI i{ss, \" \"};\n\tstatic_assert(same_as<I::difference_type, std::ptrdiff_t>);\n\tstatic_assert(same_as<I::char_type, char>);\n\tstatic_assert(same_as<I::traits_type, std::char_traits<char>>);\n\tstatic_assert(same_as<I::ostream_type, std::ostream>);\n\n\tstatic_assert(same_as<I&, decltype(*i)>);\n\tstatic_assert(same_as<I&, decltype(*i = 42)>);\n\tstatic_assert(same_as<I&, decltype(++i)>);\n\tstatic_assert(same_as<I&, decltype(i++)>);\n\n\tstatic_assert(noexcept(I{}));\n#if defined(__GNUC__) && __GNUC__ < 8 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)\n\t// workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80633\n\tstatic_assert(noexcept(I{std::declval<decltype((ss))>()}));\n\tstatic_assert(noexcept(I{std::declval<decltype((ss))>(), \"some text\"}));\n#else\n\tstatic_assert(noexcept(I{ss}));\n\tstatic_assert(noexcept(I{ss, \"some text\"}));\n#endif\n\tstatic_assert(noexcept(I{I{}}));\n\tstatic_assert(noexcept(I{i}));\n\n\t::copy(begin(some_ints), end(some_ints), i);\n\tCHECK(ss.str() == \"0 7 1 6 2 5 3 4 \");\n\tCHECK_EQUAL(\n\t\tsubrange(istream_iterator<int>{ss}, default_sentinel),\n\t\t\tsome_ints);\n\n\tstatic_assert(same_as<\n\t\tostream_iterator<int>&,\n\t\tdecltype(*std::declval<ostream_iterator<int>&>())>);\n\n\tostream_iterator<std::string>{std::cout} = \"Hello, World!\\n\";\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/ostreambuf_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/iterator/ostreambuf_iterator.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/type_traits.hpp>\n#include <sstream>\n#include \"../simple_test.hpp\"\n\nusing namespace __stl2;\n\nnamespace {\n\ttemplate<class I, class O>\n\tstruct result {\n\t\tI in;\n\t\tO out;\n\t};\n\n\ttemplate<input_iterator I, sentinel_for<I> S, output_iterator<iter_reference_t<I>> O>\n\tconstexpr result<I, O> copy(I first, S last, O out) {\n\t\tfor (; first != last; ++first, void(), ++out) {\n\t\t\t*out = *first;\n\t\t}\n\t\treturn {first, out};\n\t}\n\n\ttemplate<input_range R, output_iterator<iter_reference_t<iterator_t<R>>> O>\n\tconstexpr result<safe_iterator_t<R>, O>\n\tcopy(R&& range, O out) {\n\t\treturn ::copy(begin(range), end(range), std::move(out));\n\t}\n}\n\nint main() {\n\tusing I = ostreambuf_iterator<char>;\n\tstatic_assert(output_iterator<I, const char&>);\n\tstatic_assert(sentinel_for<default_sentinel_t, I>);\n\tstatic_assert(common_with<I, default_sentinel_t>);\n\tstatic_assert(std::is_same<I, common_type_t<I, default_sentinel_t>>());\n\n\t{\n\t\tstatic const char hw[] = \"Hello, world!\";\n\t\tauto hw_range = subrange(begin(hw), end(hw) - 1);\n\t\tstd::ostringstream os;\n\t\tauto r = ::copy(hw_range, I{os});\n\t\tCHECK(r.out != default_sentinel);\n\t\tCHECK_EQUAL(os.str(), hw_range);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/iterator/reverse_iterator.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n//// Adapted (stolen) from: Range v3 library\n////\n////// These tests of reverse_iterator have been adapted from libc++\n////// (http://libcxx.llvm.org).\n//////\n//////===----------------------------------------------------------------------===//\n//////\n//////                     The LLVM Compiler Infrastructure\n//////\n////// This file is dual licensed under the MIT and the University of Illinois Open\n////// Source Licenses. See LICENSE.TXT for details.\n//////\n//////===----------------------------------------------------------------------===//\n//\n#include <stl2/iterator.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class It> void test() { ranges::reverse_iterator<It>{}; }\n\ntemplate<class It> void test2(It i) {\n\tranges::reverse_iterator<It> r(i);\n\tCHECK(r.base() == i);\n}\n\ntemplate<class It, class U> void test3(U u) {\n\tconst ranges::reverse_iterator<U> r2(u);\n\tranges::reverse_iterator<It> r1 = r2;\n\tCHECK(r1.base() == u);\n}\n\nstruct Base {};\nstruct Derived : Base {};\n\ntemplate<class It> void test4(It i) {\n\tconst auto r = ranges::make_reverse_iterator(i);\n\tstatic_assert(std::is_same<decltype(r), const ranges::reverse_iterator<It>>());\n\tCHECK(r.base() == i);\n}\n\ntemplate<class It> void test5(It l, It r, bool x) {\n\tconst ranges::reverse_iterator<It> r1(l);\n\tconst ranges::reverse_iterator<It> r2(r);\n\tCHECK((r1 != r2) == x);\n}\n\ntemplate<class It> void test6(It i, It x) {\n\tranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> rr = r++;\n\tCHECK(r.base() == x);\n\tCHECK(rr.base() == i);\n}\n\ntemplate<class It> void test7(It i, It x) {\n\tranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> &rr = ++r;\n\tCHECK(r.base() == x);\n\tCHECK(&rr == &r);\n}\n\ntemplate<class It>\nvoid test8(It i, ranges::iter_difference_t<It> n, It x) {\n\tconst ranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> rr = r + n;\n\tCHECK(rr.base() == x);\n}\n\ntemplate<class It>\nvoid test9(It i, ranges::iter_difference_t<It> n, It x) {\n\tranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> &rr = r += n;\n\tCHECK(r.base() == x);\n\tCHECK(&rr == &r);\n}\n\ntemplate<class It> void test10(It i, It x) {\n\tranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> rr = r--;\n\tCHECK(r.base() == x);\n\tCHECK(rr.base() == i);\n}\ntemplate<class It> void test11(It i, It x) {\n\tranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> &rr = --r;\n\tCHECK(r.base() == x);\n\tCHECK(&rr == &r);\n}\ntemplate<class It>\nvoid test12(It i, ranges::iter_difference_t<It> n, It x) {\n\tconst ranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> rr = r - n;\n\tCHECK(rr.base() == x);\n}\n\ntemplate<class It>\nvoid test13(It i, ranges::iter_difference_t<It> n, It x) {\n\tranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> &rr = r -= n;\n\tCHECK(r.base() == x);\n\tCHECK(&rr == &r);\n}\n\nclass A {\n\tint data_ = 1;\n\npublic:\n\tA() = default;\n\n\tfriend bool operator==(const A &x, const A &y) { return x.data_ == y.data_; }\n};\n\ntemplate<class It> void test14(It i, ranges::iter_value_t<It> x) {\n\tranges::reverse_iterator<It> r(i);\n\tCHECK(*r == x);\n}\n\ntemplate<class It, class U> void test15(U u) {\n\tconst ranges::reverse_iterator<U> r2(u);\n\tranges::reverse_iterator<It> r1;\n\tranges::reverse_iterator<It> &rr = r1 = r2;\n\tCHECK(r1.base() == u);\n\tCHECK(&rr == &r1);\n}\ntemplate<class It> void test16(It l, It r, bool x) {\n\tconst ranges::reverse_iterator<It> r1(l);\n\tconst ranges::reverse_iterator<It> r2(r);\n\tCHECK((r1 == r2) == x);\n}\n\ntemplate<class It1, class It2> void test17(It1 l, It2 r, std::ptrdiff_t x) {\n\t const ranges::reverse_iterator<It1> r1(l);\n\t const ranges::reverse_iterator<It2> r2(r);\n\t CHECK((r1 - r2) == x);\n}\n\ntemplate<class It> void test18(It l, It r, bool x) {\n\tconst ranges::reverse_iterator<It> r1(l);\n\tconst ranges::reverse_iterator<It> r2(r);\n\tCHECK((r1 > r2) == x);\n}\n\ntemplate<class It> void test19(It l, It r, bool x) {\n\tconst ranges::reverse_iterator<It> r1(l);\n\tconst ranges::reverse_iterator<It> r2(r);\n\tCHECK((r1 >= r2) == x);\n}\n\ntemplate<class It>\nvoid test20(It i, ranges::iter_difference_t<It> n, ranges::iter_value_t<It> x) {\n\tconst ranges::reverse_iterator<It> r(i);\n\tranges::iter_value_t<It> rr = r[n];\n\tCHECK(rr == x);\n}\n\ntemplate<class It> void test21(It l, It r, bool x) {\n\tconst ranges::reverse_iterator<It> r1(l);\n\tconst ranges::reverse_iterator<It> r2(r);\n\tCHECK((r1 < r2) == x);\n}\n\ntemplate<class It>\nvoid\ntest22(It l, It r, bool x) {\n\tconst ranges::reverse_iterator<It> r1(l);\n\tconst ranges::reverse_iterator<It> r2(r);\n\tCHECK((r1 < r2) == x);\n}\n\ntemplate<class It>\nvoid\ntest23(It l, It r, bool x) {\n\tconst ranges::reverse_iterator<It> r1(l);\n\tconst ranges::reverse_iterator<It> r2(r);\n\tCHECK((r1 <= r2) == x);\n}\n\nclass B\n{\n\tint data_ = 1;\npublic:\n\tB() = default;\n\n\tint get() const { return data_; }\n\n\tfriend bool operator==(const B& x, const B& y) {\n\t\treturn x.data_ == y.data_;\n\t}\n};\n\ntemplate<class It>\nvoid\ntest24(It i, ranges::iter_value_t<It> x)\n{\n\tranges::reverse_iterator<It> r(i);\n\tCHECK((*r).get() == x.get());\n}\n\nclass C\n{\n\tint data_ = 1;\npublic:\n\tC(int d) : data_(d) {}\n\tC() = default;\n\n\tint get() const { return data_; }\n\n\tfriend bool operator==(const C& x, const C& y) {\n\t\treturn x.data_ == y.data_;\n\t}\n\tconst C *operator&() const { return nullptr; }\n\tC       *operator&()       { return nullptr; }\n};\n\ntemplate<class It>\nvoid\ntest25(It i, ranges::iter_difference_t<It> n, It x)\n{\n\tconst ranges::reverse_iterator<It> r(i);\n\tranges::reverse_iterator<It> rr = n + r;\n\tCHECK(rr.base() == x);\n}\n\n\nconstexpr bool test_constexpr() {\n\tint rng[] = {0,1,2,3};\n\tauto const first = ranges::make_reverse_iterator(ranges::end(rng));\n\tauto const last = ranges::make_reverse_iterator(ranges::begin(rng));\n\tif (!(first == first)) return false;\n\tif (first != first) return false;\n\tif (last < first) return false;\n\tif (!(last > first)) return false;\n\tif (last <= first) return false;\n\tif (!(last >= first)) return false;\n\tif (*(first + 2) != 1) return false;\n\tif (*(last - 2) != 1) return false;\n\tif (first[3] != 0) return false;\n\tif (first - last != -4) return false;\n\t{\n\t\tranges::reverse_iterator<int const*> foo{first};\n\t\tfoo = first;\n\t\tif (!(foo == first)) return false;\n\t\tif (foo != first) return false;\n\t\tif (last < foo) return false;\n\t\tif (!(last > foo)) return false;\n\t\tif (last <= foo) return false;\n\t\tif (!(last >= foo)) return false;\n\t\tif (*(foo + 2) != 1) return false;\n\t\tif (*(last - 2) != 1) return false;\n\t\tif (foo[3] != 0) return false;\n\t\tif (foo - last != -4) return false;\n\t}\n\tauto pos = first;\n\t++pos;\n\tif (pos.base() != rng + 3) return false;\n\tif (pos + 3 != last) return false;\n\tif (*pos != 2) return false;\n\tif (pos.operator->() != rng + 2) return false;\n\t--pos;\n\tif (pos != first) return false;\n\tpos += 2;\n\tif (*pos != 1) return false;\n\tpos -= -1;\n\tif (*pos != 0) return false;\n\n\treturn true;\n}\nstatic_assert(test_constexpr());\n\nint main() {\n\t{\n\t\tstatic_assert(\n\t\t\t\tranges::bidirectional_iterator<\n\t\t\t\t\tranges::reverse_iterator<bidirectional_iterator<const char *>>>);\n\t\tstatic_assert(\n\t\t\t\tranges::random_access_iterator<\n\t\t\t\t\tranges::reverse_iterator<random_access_iterator<const char *>>>);\n\t}\n\t{ // test\n\t\ttest<bidirectional_iterator<const char *>>();\n\t\ttest<random_access_iterator<char *>>();\n\t\ttest<char *>();\n\t\ttest<const char *>();\n\t}\n\t{ // test 2\n\t\tconst char s[] = \"123\";\n\t\ttest2(bidirectional_iterator<const char *>(s));\n\t\ttest2(random_access_iterator<const char *>(s));\n\t}\n\t{ // test3\n\t\tDerived d;\n\t\ttest3<bidirectional_iterator<Base *>>(\n\t\t\t\tbidirectional_iterator<Derived *>(&d));\n\t\ttest3<random_access_iterator<const Base *>>(\n\t\t\t\trandom_access_iterator<Derived *>(&d));\n\t}\n\t{ // test4\n\t\tconst char *s = \"1234567890\";\n\t\trandom_access_iterator<const char *> b(s);\n\t\trandom_access_iterator<const char *> e(s + 10);\n\t\twhile (b != e)\n\t\t\ttest4(b++);\n\t}\n\t{ // test5\n\t\tconst char *s = \"1234567890\";\n\t\ttest5(bidirectional_iterator<const char *>(s),\n\t\t\t\t\tbidirectional_iterator<const char *>(s), false);\n\t\ttest5(bidirectional_iterator<const char *>(s),\n\t\t\t\t\tbidirectional_iterator<const char *>(s + 1), true);\n\t\ttest5(random_access_iterator<const char *>(s),\n\t\t\t\t\trandom_access_iterator<const char *>(s), false);\n\t\ttest5(random_access_iterator<const char *>(s),\n\t\t\t\t\trandom_access_iterator<const char *>(s + 1), true);\n\t\ttest5(s, s, false);\n\t\ttest5(s, s + 1, true);\n\t}\n\t{\n\t\tconst char *s = \"123\";\n\t\ttest6(bidirectional_iterator<const char *>(s + 1),\n\t\t\t\t\tbidirectional_iterator<const char *>(s));\n\t\ttest6(random_access_iterator<const char *>(s + 1),\n\t\t\t\t\trandom_access_iterator<const char *>(s));\n\t\ttest6(s + 1, s);\n\t}\n\t{\n\t\tconst char *s = \"123\";\n\t\ttest7(bidirectional_iterator<const char *>(s + 1),\n\t\t\t\t\tbidirectional_iterator<const char *>(s));\n\t\ttest7(random_access_iterator<const char *>(s + 1),\n\t\t\t\t\trandom_access_iterator<const char *>(s));\n\t\ttest7(s + 1, s);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest8(random_access_iterator<const char *>(s + 5), 5,\n\t\t\t\t\trandom_access_iterator<const char *>(s));\n\t\ttest8(s + 5, 5, s);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest9(random_access_iterator<const char *>(s + 5), 5,\n\t\t\t\t\trandom_access_iterator<const char *>(s));\n\t\ttest9(s + 5, 5, s);\n\t}\n\t{\n\t\tconst char *s = \"123\";\n\t\ttest10(bidirectional_iterator<const char *>(s + 1),\n\t\t\t\t\t bidirectional_iterator<const char *>(s + 2));\n\t\ttest10(random_access_iterator<const char *>(s + 1),\n\t\t\t\t\t random_access_iterator<const char *>(s + 2));\n\t\ttest10(s + 1, s + 2);\n\t}\n\t{\n\t\tconst char *s = \"123\";\n\t\ttest11(bidirectional_iterator<const char *>(s + 1),\n\t\t\t\t\t bidirectional_iterator<const char *>(s + 2));\n\t\ttest11(random_access_iterator<const char *>(s + 1),\n\t\t\t\t\t random_access_iterator<const char *>(s + 2));\n\t\ttest11(s + 1, s + 2);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest12(random_access_iterator<const char *>(s + 5), 5,\n\t\t\t\t\t random_access_iterator<const char *>(s + 10));\n\t\ttest12(s + 5, 5, s + 10);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest13(random_access_iterator<const char *>(s + 5), 5,\n\t\t\t\t\t random_access_iterator<const char *>(s + 10));\n\t\ttest13(s + 5, 5, s + 10);\n\t}\n\t{\n\t\tA a;\n\t\ttest14(&a + 1, A());\n\t}\n\t{\n\t\tDerived d;\n\n\t\ttest15<bidirectional_iterator<Base *>>(\n\t\t\t\tbidirectional_iterator<Derived *>(&d));\n\t\ttest15<random_access_iterator<const Base *>>(\n\t\t\t\trandom_access_iterator<Derived *>(&d));\n\t\ttest15<Base *>(&d);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest16(bidirectional_iterator<const char *>(s),\n\t\t\t\t\t bidirectional_iterator<const char *>(s), true);\n\t\ttest16(bidirectional_iterator<const char *>(s),\n\t\t\t\t\t bidirectional_iterator<const char *>(s + 1), false);\n\t\ttest16(random_access_iterator<const char *>(s),\n\t\t\t\t\t random_access_iterator<const char *>(s), true);\n\t\ttest16(random_access_iterator<const char *>(s),\n\t\t\t\t\t random_access_iterator<const char *>(s + 1), false);\n\t\ttest16(s, s, true);\n\t\ttest16(s, s + 1, false);\n\t}\n\t{\n\t\tchar s[3] = {0};\n\t\ttest17(random_access_iterator<const char *>(s),\n\t\t\t\t\t random_access_iterator<char *>(s), 0);\n\t\trandom_access_iterator<char *> inp1(s);\n\t\ttest17(random_access_iterator<char *>(s),\n\t\t\t\t\t random_access_iterator<const char *>(s + 1), 1);\n\t\ttest17(random_access_iterator<const char *>(s + 1),\n\t\t\t\t\t random_access_iterator<char *>(s), -1);\n\t\ttest17(s, s, 0);\n\t\ttest17(s, s + 1, 1);\n\t\ttest17(s + 1, s, -1);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest18(random_access_iterator<const char *>(s),\n\t\t\t\t\t random_access_iterator<const char *>(s), false);\n\t\ttest18(random_access_iterator<const char *>(s),\n\t\t\t\t\t random_access_iterator<const char *>(s + 1), true);\n\t\ttest18(random_access_iterator<const char *>(s + 1),\n\t\t\t\t\t random_access_iterator<const char *>(s), false);\n\t\ttest18(s, s, false);\n\t\ttest18(s, s + 1, true);\n\t\ttest18(s + 1, s, false);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest19(random_access_iterator<const char *>(s),\n\t\t\t\t\t random_access_iterator<const char *>(s), true);\n\t\ttest19(random_access_iterator<const char *>(s),\n\t\t\t\t\t random_access_iterator<const char *>(s + 1), true);\n\t\ttest19(random_access_iterator<const char *>(s + 1),\n\t\t\t\t\t random_access_iterator<const char *>(s), false);\n\t\ttest19(s, s, true);\n\t\ttest19(s, s + 1, true);\n\t\ttest19(s + 1, s, false);\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest20(random_access_iterator<const char *>(s + 5), 4, '1');\n\t\ttest20(s + 5, 4, '1');\n\t}\n\t{\n\t\tconst char *s = \"1234567890\";\n\t\ttest21(random_access_iterator<const char *>(s),\n\t\t\t\t random_access_iterator<const char *>(s), false);\n\t\ttest21(random_access_iterator<const char *>(s),\n\t\t\t\t random_access_iterator<const char *>(s + 1), false);\n\t\ttest21(random_access_iterator<const char *>(s + 1),\n\t\t\t\t random_access_iterator<const char *>(s), true);\n\t\ttest21(s, s, false);\n\t\ttest21(s, s + 1, false);\n\t\ttest21(s + 1, s, true);\n\t}\n\t{\n\t\tconst char* s = \"1234567890\";\n\t\ttest22(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), false);\n\t\ttest22(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), false);\n\t\ttest22(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s), true);\n\t\ttest22(s, s, false);\n\t\ttest22(s, s+1, false);\n\t\ttest22(s+1, s, true);\n\t}\n\t{\n\t\tconst char* s = \"1234567890\";\n\t\ttest23(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s), true);\n\t\ttest23(random_access_iterator<const char*>(s), random_access_iterator<const char*>(s+1), false);\n\t\ttest23(random_access_iterator<const char*>(s+1), random_access_iterator<const char*>(s), true);\n\t\ttest23(s, s, true);\n\t\ttest23(s, s+1, false);\n\t\ttest23(s+1, s, true);\n\t}\n\t{\n\t\tB a;\n\t\ttest24(&a+1, B());\n\t}\n\t{\n\t\tC l[3] = {C(0), C(1), C(2)};\n\n\t\tauto ri = ranges::rbegin(l);\n\t\tCHECK ( (*ri).get() == 2 );  ++ri;\n\t\tCHECK ( (*ri).get() == 1 );  ++ri;\n\t\tCHECK ( (*ri).get() == 0 );  ++ri;\n\t\tCHECK ( ri == ranges::rend(l));\n\t}\n\t{\n\t\tconst char* s = \"1234567890\";\n\t\ttest25(random_access_iterator<const char*>(s+5), 5, random_access_iterator<const char*>(s));\n\t\ttest25(s+5, 5, s);\n\t}\n\n\t{\n\t\t// Verify that reverse_iterator's constructor that accepts a base iterator\n\t\t// is explicit.\n\t\tusing RI = ranges::reverse_iterator<char*>;\n\t\tstatic_assert(ranges::constructible_from<RI, char*>);\n\t\tstatic_assert(!ranges::convertible_to<char*, RI>);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/iterator/unreachable.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/iterator.hpp>\n#include <algorithm>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint strlen_test(const char* p) noexcept {\n\tusing C = ranges::common_iterator<const char*, ranges::unreachable_sentinel_t>;\n\treturn ranges::distance(C{p}, std::find(C{p}, C{ranges::unreachable_sentinel}, '\\0'));\n}\n\nint main() {\n\t// Not yet: static_assert(strlen_test(\"Hello, world!\") == 13);\n\tCHECK(strlen_test(\"123This is a test, this is only a test.456\") == 42);\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/memory/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015, 2017\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_stl2_test(memory.destroy destroy destroy.cpp)\nadd_stl2_test(memory.uninitialized_copy uninitialized_copy uninitialized_copy.cpp)\nadd_stl2_test(memory.uninitialized_default_construct uninitialized_default_construct uninitialized_default_construct.cpp)\nadd_stl2_test(memory.uninitialized_fill uninitialized_fill uninitialized_fill.cpp)\nadd_stl2_test(memory.uninitialized_move uninitialized_move uninitialized_move.cpp)\nadd_stl2_test(memory.uninitialized_value_construct uninitialized_value_construct uninitialized_value_construct.cpp)\n"
  },
  {
    "path": "test/memory/common.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef COMMON_HPP\n#define COMMON_HPP\n\n#include <array>\n#include <cstdint>\n#include <string>\n#include <stl2/memory.hpp>\n#include <stl2/utility.hpp>\n\ntemplate<typename T>\nclass raw_buffer {\npublic:\n\tusing value_type = T;\n\n\t~raw_buffer() {\n\t\tif (data_) {\n\t\t\tstd::allocator<T>{}.deallocate(data_, size_);\n\t\t}\n\t}\n\n\texplicit raw_buffer(const std::ptrdiff_t size)\n\t\t: data_{std::allocator<T>{}.allocate(size)}\n\t\t, size_{size}\n\t{}\n\n\traw_buffer(raw_buffer&& that) noexcept\n\t: data_{__stl2::exchange(that.data_, nullptr)}\n\t, size_{__stl2::exchange(that.size_, 0)}\n\t{}\n\n\traw_buffer& operator=(raw_buffer&& that) & noexcept {\n\t\tdata_ = __stl2::exchange(that.data_, nullptr);\n\t\tsize_ = __stl2::exchange(that.size_, 0);\n\t\treturn *this;\n\t}\n\n\tT* begin() noexcept {\n\t\treturn data_;\n\t}\n\n\tconst T* begin() const noexcept {\n\t\treturn data_;\n\t}\n\n\tauto cbegin() const noexcept {\n\t\treturn begin();\n\t}\n\n\tT* end() noexcept {\n\t\treturn data_ + size_;\n\t}\n\n\tconst T* end() const noexcept {\n\t\treturn data_ + size_;\n\t}\n\n\tauto cend() const noexcept {\n\t\treturn end();\n\t}\n\n\tT* data() noexcept {\n\t\treturn data_;\n\t}\n\tconst T* data() const noexcept {\n\t\treturn data_;\n\t}\n\n\tstd::ptrdiff_t size() const noexcept {\n\t\treturn size_;\n\t}\nprivate:\n\tT* data_;\n\tstd::ptrdiff_t size_;\n};\n\ntemplate<typename T>\nauto make_buffer(const std::size_t size) {\n\tSTL2_EXPECT(size <= static_cast<std::size_t>(PTRDIFF_MAX));\n\treturn raw_buffer<T>{static_cast<std::ptrdiff_t>(size)};\n}\n\nclass Book {\npublic:\n\tbool operator==(const Book& b) const noexcept\n\t{\n\t\treturn\n\t\t\tisbn_ == b.isbn_ &&\n\t\t\tprice_ == b.price_ &&\n\t\t\ttitle_ == b.title_ &&\n\t\t\tauthor_ == b.author_;\n\t}\n\n\tbool operator!=(const Book& b) const noexcept\n\t{\n\t\treturn !(*this == b);\n\t}\n\n\tbool empty() const noexcept\n\t{\n\t\treturn title_.empty() && author_.empty();\n\t}\nprivate:\n\tstd::int64_t isbn_{1248163264128-256};\n\tdouble price_{16.64};\n\tstd::string title_{\"The Lord of the Rings: The Ring Goes South\"};\n\tstd::string author_{\"J.R.R Tolkien\"};\n};\n\ntemplate<typename T>\nusing Array = std::array<T, 8>;\n\n#endif // COMMON_HPP\n"
  },
  {
    "path": "test/memory/destroy.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/memory/destroy.hpp>\n#include <stl2/detail/memory/uninitialized_default_construct.hpp>\n#include \"../simple_test.hpp\"\n#include \"common.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tclass Construct {\n\tpublic:\n\t\tConstruct()\n\t\t{\n\t\t\t++instantiated;\n\t\t}\n\n\t\tConstruct(const Construct&)\n\t\t{\n\t\t\t++instantiated;\n\t\t}\n\n\t\tConstruct(Construct&&) noexcept\n\t\t{\n\t\t\t++instantiated;\n\t\t}\n\n\t\t~Construct()\n\t\t{\n\t\t\t--instantiated;\n\t\t}\n\n\t\tstatic int get_instantiated()\n\t\t{\n\t\t\treturn instantiated;\n\t\t}\n\n\t\tConstruct& operator=(Construct&&) noexcept = default;\n\t\tConstruct& operator=(const Construct&) noexcept = default;\n\tprivate:\n\t\tstatic int instantiated;\n\t};\n\n\tint Construct::instantiated{0};\n}\n\nint main()\n{\n\tauto independent = make_buffer<Construct>(1 << 20);\n\tauto test = [&independent](const auto& p) {\n\t\tCHECK(Construct::get_instantiated() == 0);\n\t\tCHECK(p == independent.end());\n\t};\n\n\tranges::uninitialized_default_construct(independent);\n\ttest(ranges::destroy(independent.begin(), independent.end()));\n\n\tranges::uninitialized_default_construct(independent);\n\ttest(ranges::destroy(independent.cbegin(), independent.cend()));\n\n\tranges::uninitialized_default_construct(independent);\n\ttest(ranges::destroy(independent));\n\n\tranges::uninitialized_default_construct(independent);\n\ttest(ranges::destroy_n(independent.begin(), independent.size()));\n\n\tranges::uninitialized_default_construct(independent);\n\ttest(ranges::destroy_n(independent.cbegin(), independent.size()));\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/memory/uninitialized_copy.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/memory/uninitialized_copy.hpp>\n\n#include <stl2/concepts.hpp>\n#include <stl2/detail/algorithm/equal.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/view/repeat.hpp>\n#include <stl2/view/take_exactly.hpp>\n#include <algorithm>\n#include <cstdint>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"common.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\ttemplate<typename T>\n\trequires ranges::copy_constructible<T> && ranges::equality_comparable<T>\n\tvoid uninitialized_copy_test(const Array<T>& control) {\n\t\tauto independent = make_buffer<T>(control.size());\n\t\tauto test = [](const auto& control, const auto& independent, const auto p) {\n\t\t\tconst auto distance_traversed =\n\t\t\t\tstd::min<std::ptrdiff_t>(control.size(), independent.size());\n\t\t\tCHECK(p.in == ranges::next(control.begin(), distance_traversed));\n\t\t\tCHECK(p.out == ranges::next(independent.begin(), distance_traversed));\n\t\t\tCHECK(ranges::equal(control.begin(), p.in, independent.begin(), p.out));\n\t\t\tranges::destroy(independent.begin(), p.out);\n\t\t};\n\n\t\tauto driver = [&test](const auto& in, auto& out) {\n\t\t\ttest(in, out, ranges::uninitialized_copy(in.begin(), in.end(), out.begin(), out.end()));\n\t\t\ttest(in, out, ranges::uninitialized_copy(in, out));\n\t\t\ttest(in, out, ranges::uninitialized_copy(in.cbegin(), in.cend(), out.cbegin(), out.cend()));\n\t\t\ttest(in, out, ranges::uninitialized_copy(in, std::as_const(out)));\n\n\t\t\ttest(in, out, ranges::uninitialized_copy_n(in.begin(), in.size(), out.begin(), out.end()));\n\t\t\ttest(in, out, ranges::uninitialized_copy_n(in.cbegin(), in.size(), out.cbegin(), out.cend()));\n\t\t};\n\n\t\t// check range-based when distance(rng1) == distance(rng2)\n\t\tdriver(control, independent);\n\n\t\t// check double range-based when distance(rng1) < distance(rng2)\n\t\tauto small_input = std::array<T, 1>{control[0]};\n\t\tdriver(small_input, independent);\n\t\t// check double range-based when distance(rng1) > distance(rng2)\n\t\tauto small_output = make_buffer<T>(1);\n\t\tdriver(control, small_output);\n\t}\n\n\tstruct S {\n\t\tstatic constexpr int throw_after = 42;\n\t\tstatic int count;\n\n\t\tstatic void increment() {\n\t\t\tif (++count >= throw_after) {\n\t\t\t\tthrow exception{};\n\t\t\t}\n\t\t}\n\n\t\tstruct exception {};\n\n\t\tS() = default;\n\t\tS(const S&) { increment(); }\n\t\tS& operator=(const S&) & {\n\t\t\tincrement();\n\t\t\treturn *this;\n\t\t}\n\t\tS(S&&) = default;\n\t\tS& operator=(S&&) & = default;\n\t};\n\tconstexpr int S::throw_after;\n\tint S::count;\n\n\tvoid throw_test() {\n\t\tconstexpr int n = 2 * S::throw_after;\n\t\tauto control = ranges::ext::repeat_view<S>{S{}};\n\t\tauto independent = make_buffer<S>(n);\n\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_copy_n(control.begin(), n, independent.begin(), independent.end());\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\n\t\tauto control2 = ranges::ext::take_exactly_view<ranges::ext::repeat_view<S>>{\n\t\t\tstd::move(control), n\n\t\t};\n\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_copy(control2.begin(), control2.end(), independent.begin(), independent.end());\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_copy(control2, independent);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\t}\n}\n\n/**\n * Testing framework:\n * - test an array of fundamentals\n * - test an array of standard containers\n * - test an array of non-standard structures\n *\n * - initial array: using the default constructor\n * - second array:  using a non-default constructor\n */\n\nint main() {\n\tusing Test_type_one = Array<int>;\n\tusing Test_type_two = Array<std::vector<double>>;\n\n\tuninitialized_copy_test(Test_type_one{});\n\tuninitialized_copy_test(Test_type_two{});\n\tuninitialized_copy_test(Array<Book>{});\n\n\tuninitialized_copy_test(Test_type_one{0, 1, 2, 3, 4, 5, 6, 7});\n\tuninitialized_copy_test(Test_type_two{{\n\t\t{0.0, 0.1, 0.2},\n\t\t{1.0, 1.1, 1.2, 1.3, 1.4},\n\t\t{2.0, 2.1, 2.2, 2.3},\n\t\t{3.01, 3.20, 3.33, 3.4},\n\t\t{4.101, 4.102, 4.201, 4.202, 4.311},\n\t\t{5.},\n\t\t{6.1, 3.02, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9},\n\t\tstd::vector<double>(1 << 12, 7.0)}});\n\n\tthrow_test();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/memory/uninitialized_default_construct.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/memory/uninitialized_default_construct.hpp>\n#include <stl2/concepts.hpp>\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n#include <cstdint>\n#include <cstring>\n#include <deque>\n#include <iostream>\n#include <list>\n#include <string>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"common.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tconstexpr int N = 1 << 12;\n\n\ttemplate<typename T>\n\trequires ranges::default_initializable<T> && ranges::equality_comparable<T>\n\tvoid test(const raw_buffer<T>& independent, ranges::iterator_t<const raw_buffer<T>> p) {\n\t\tT t{};\n\t\tCHECK(p == independent.cend());\n\t\tCHECK(ranges::find_if(independent.begin(), p, [&t](const T& i){ return i != t; }) == p);\n\t\tranges::destroy(independent.begin(), p);\n\t}\n\n\ttemplate<typename T>\n\trequires ranges::default_initializable<T> && ranges::equality_comparable<T>\n\tvoid uninitialized_default_construct_test() {\n\t\tauto independent = make_buffer<T>(N);\n\n\t\ttest(independent, ranges::uninitialized_default_construct(independent.begin(), independent.end()));\n\t\ttest(independent, ranges::uninitialized_default_construct(independent.cbegin(), independent.cend()));\n\t\ttest(independent, ranges::uninitialized_default_construct(independent));\n\t\ttest(independent, ranges::uninitialized_default_construct(std::as_const(independent)));\n\t\ttest(independent, ranges::uninitialized_default_construct_n(independent.begin(), independent.size()));\n\t\ttest(independent, ranges::uninitialized_default_construct_n(independent.cbegin(), independent.size()));\n\t}\n\n\ttemplate<typename T>\n\trequires ranges::default_initializable<T> && ranges::equality_comparable<T> && std::is_fundamental<T>::value\n\tvoid test(const raw_buffer<T>& independent, ranges::iterator_t<const raw_buffer<T>> p) {\n\t\tT t;\n\t\tstd::memset(&t, 0xCC, sizeof(T));\n\t\tCHECK(p == independent.cend());\n\t\tCHECK(ranges::find_if(independent.begin(), p, [&t](const T& i){ return i != t; }) == p);\n\t\tranges::destroy(independent.begin(), p);\n\t}\n\n\ttemplate<typename T>\n\trequires ranges::default_initializable<T> && ranges::equality_comparable<T> && std::is_fundamental<T>::value\n\tvoid uninitialized_default_construct_test() {\n\t\tauto independent = make_buffer<T>(N);\n\n\t\tstd::memset(independent.begin(), 0xCC, independent.size() * sizeof(T));\n\n\t\ttest(independent, ranges::uninitialized_default_construct(independent.begin(), independent.end()));\n\t\ttest(independent, ranges::uninitialized_default_construct(independent));\n\t\ttest(independent, ranges::uninitialized_default_construct_n(independent.begin(), independent.size()));\n\t}\n\n\tstruct S {\n\t\tstatic constexpr int throw_after = 42;\n\t\tstatic int count;\n\n\t\tstatic void increment() {\n\t\t\tif (++count >= throw_after) {\n\t\t\t\tthrow exception{};\n\t\t\t}\n\t\t}\n\n\t\tstruct exception {};\n\n\t\tS() { increment(); }\n\t};\n\tconstexpr int S::throw_after;\n\tint S::count;\n\n\tvoid throw_test() {\n\t\tconstexpr int n = 2 * S::throw_after;\n\t\tauto independent = make_buffer<S>(n);\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_default_construct_n(independent.begin(), n);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\t\tS::count = 0;\n\n\t\ttry {\n\t\t\tranges::uninitialized_default_construct(independent);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\t\tS::count = 0;\n\t}\n}\n\nint main() {\n\tuninitialized_default_construct_test<char>();\n\tuninitialized_default_construct_test<int>();\n\tuninitialized_default_construct_test<long long>();\n\tuninitialized_default_construct_test<float>();\n\tuninitialized_default_construct_test<double>();\n\tuninitialized_default_construct_test<std::vector<char>>();\n\tuninitialized_default_construct_test<std::string>();\n\tuninitialized_default_construct_test<std::deque<double>>();\n\tuninitialized_default_construct_test<std::list<std::vector<std::deque<double>>>>();\n\tuninitialized_default_construct_test<std::unique_ptr<std::string>>();\n\n\tthrow_test();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/memory/uninitialized_fill.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/memory/uninitialized_fill.hpp>\n\n#include <cstdint>\n#include <vector>\n#include <stl2/concepts.hpp>\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n#include \"../simple_test.hpp\"\n#include \"common.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tconstexpr auto test_size{1 << 10};\n\n\ttemplate<typename T>\n\trequires ranges::copy_constructible<T> && ranges::equality_comparable<T>\n\tvoid uninitialized_fill_test(const T& x) {\n\t\tconst auto independent = make_buffer<T>(test_size);\n\t\tauto test = [&independent, &x](const auto& p){\n\t\t\tCHECK(p == independent.end());\n\t\t\tCHECK(ranges::find_if(independent.begin(), p, [&x](const T& i){ return i != x; }) == p);\n\t\t\tranges::destroy(independent.begin(), p);\n\t\t};\n\n\t\ttest(ranges::uninitialized_fill(independent.begin(), independent.end(), x));\n\t\ttest(ranges::uninitialized_fill(independent.cbegin(), independent.cend(), x));\n\t\ttest(ranges::uninitialized_fill(independent, x));\n\t\ttest(ranges::uninitialized_fill_n(independent.begin(), independent.size(), x));\n\t\ttest(ranges::uninitialized_fill_n(independent.cbegin(), independent.size(), x));\n\t}\n\n\tstruct S {\n\t\tstatic constexpr int throw_after = 42;\n\t\tstatic int count;\n\n\t\tstatic void increment() {\n\t\t\tif (++count >= throw_after) {\n\t\t\t\tthrow exception{};\n\t\t\t}\n\t\t}\n\n\t\tstruct exception {};\n\n\t\tS() = default;\n\t\tS(const S&) { increment(); }\n\t\tS& operator=(const S&) & {\n\t\t\tincrement();\n\t\t\treturn *this;\n\t\t}\n\t\tS(S&&) = default;\n\t\tS& operator=(S&&) & = default;\n\t};\n\tconstexpr int S::throw_after;\n\tint S::count;\n\n\tvoid throw_test() {\n\t\tconst auto s = S{};\n\t\tconstexpr int n = 2 * S::throw_after;\n\t\tauto independent = make_buffer<S>(n);\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_fill_n(independent.begin(), n, s);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_fill(independent, s);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\t}\n}\n\nint main() {\n\tuninitialized_fill_test(0);\n\tuninitialized_fill_test(0.0);\n\tuninitialized_fill_test('a');\n\tuninitialized_fill_test(std::vector<int>{});\n\tuninitialized_fill_test(std::vector<int>(1 << 10, 0));\n\tuninitialized_fill_test(Book{});\n\n\tthrow_test();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/memory/uninitialized_move.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/memory/uninitialized_move.hpp>\n#include <stl2/concepts.hpp>\n#include <stl2/detail/algorithm/all_of.hpp>\n#include <stl2/detail/algorithm/count_if.hpp>\n#include <stl2/detail/algorithm/equal.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n#include <stl2/detail/span.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/view/repeat.hpp>\n#include <stl2/view/take_exactly.hpp>\n#include <algorithm>\n#include <cstdint>\n#include <memory>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"common.hpp\"\n\nnamespace ranges = __stl2;\nusing ranges::ext::span;\n\nnamespace {\n\ttemplate<ranges::input_range Rng>\n\trequires requires {\n\t\ttypename ranges::iter_value_t<Rng>;\n\t\t&ranges::iter_value_t<Rng>::empty;\n\t\trequires ranges::invocable<\n\t\t\tdecltype(&ranges::iter_value_t<Rng>::empty),\n\t\t\tranges::iter_reference_t<ranges::iterator_t<const Rng>>>;\n\t}\n\tbool empty(const Rng& rng, const std::ptrdiff_t n) {\n\t\treturn ranges::all_of(ranges::counted_iterator{rng.begin(), n}, ranges::default_sentinel,\n\t\t\t&ranges::iter_value_t<Rng>::empty);\n\t}\n\n\ttemplate<ranges::input_range Rng>\n\trequires requires {\n\t\ttypename ranges::iter_value_t<Rng>;\n\t\trequires std::is_fundamental_v<ranges::iter_value_t<Rng>>;\n\t}\n\tbool empty(const Rng&, const std::ptrdiff_t) {\n\t\treturn true;\n\t}\n\n\ttemplate<ranges::copyable T>\n\tvoid uninitialized_move_test(const Array<T>& control) {\n\t\tauto independent = make_buffer<T>(control.size());\n\t\tauto test = [&control](const auto& to_move, const auto& independent, const auto& p) {\n\t\t\tconst auto distance_traversed =\n\t\t\t\tstd::min<std::ptrdiff_t>(to_move.size(), independent.size());\n\t\t\tCHECK(::empty(to_move, distance_traversed));\n\t\t\tCHECK(p.in == ranges::next(to_move.begin(), distance_traversed));\n\t\t\tCHECK(p.out == ranges::next(independent.begin(), distance_traversed));\n\n\t\t\tCHECK(ranges::equal(control.begin(), control.begin() + distance_traversed,\n\t\t\t\t\tindependent.begin(), p.out));\n\t\t\tranges::destroy(independent.begin(), p.out);\n\t\t};\n\n\t\tauto driver = [&test](const auto& in, auto& out) {\n\t\t\tauto to_move = in;\n\t\t\ttest(to_move, out,\n\t\t\t\tranges::uninitialized_move(to_move.begin(), to_move.end(),\n\t\t\t\t\tout.begin(), out.end()));\n\n\t\t\tto_move = in; // to_move.begin(), not to_move.cbegin()\n\t\t\ttest(to_move, out,\n\t\t\t\tranges::uninitialized_move(to_move.begin(), to_move.end(),\n\t\t\t\t\tout.cbegin(), out.cend()));\n\n\t\t\tto_move = in;\n\t\t\ttest(to_move, out,\n\t\t\t\tranges::uninitialized_move(to_move, out));\n\n\t\t\tto_move = in;\n\t\t\ttest(to_move, out,\n\t\t\t\tranges::uninitialized_move(to_move, std::as_const(out)));\n\n\t\t\tto_move = in;\n\t\t\ttest(to_move, out,\n\t\t\t\tranges::uninitialized_move_n(to_move.begin(), to_move.size(),\n\t\t\t\tout.begin(), out.end()));\n\n\t\t\tto_move = in; // to_move.begin(), not to_move.cbegin()\n\t\t\ttest(to_move, out,\n\t\t\t\tranges::uninitialized_move_n(to_move.begin(), to_move.size(),\n\t\t\t\tout.cbegin(), out.cend()));\n\t\t};\n\n\t\t// check range-based when distance(rng1) == distance(rng2)\n\t\tdriver(control, independent);\n\n\t\t// check range-based when distance(rng1) < distance(rng2)\n\t\tauto small_input = std::array<T, 1>{control[0]};\n\t\tdriver(small_input, independent);\n\n\t\t// check range-based when distance(rng1) > distance(rng2)\n\t\tauto small_output = make_buffer<T>(1);\n\t\tdriver(control, small_output);\n\t}\n\n\tusing Move_only_t = Array<std::unique_ptr<std::string>>;\n\tvoid uninitialized_move_test(Move_only_t first) {\n\t\tauto test = [](const auto& s, const auto& d, const auto& p) {\n\t\t\tCHECK(p.in == s.end());\n\t\t\tCHECK(p.out == d.end());\n\t\t\tauto n = ranges::count_if(s.begin(), p.in, [](const auto& i){ return !i; });\n\t\t\tCHECK(static_cast<std::size_t>(n) == static_cast<std::size_t>(s.size()));\n\t\t};\n\n\t\tauto second = make_buffer<Move_only_t::value_type>(first.size());\n\t\ttest(first, second, ranges::uninitialized_move(first.begin(), first.end(),\n\t\t\tsecond.begin(), second.end()));\n\t\ttest(second, first, ranges::uninitialized_move(second.begin(), second.end(),\n\t\t\tfirst.cbegin(), first.cend()));\n\t\ttest(first, second, ranges::uninitialized_move(first, second));\n\t\ttest(second, first, ranges::uninitialized_move(second, std::as_const(first)));\n\t\ttest(first, second, ranges::uninitialized_move_n(first.begin(), first.size(),\n\t\t\tsecond.cbegin(), second.cend()));\n\t\ttest(second, first, ranges::uninitialized_move_n(second.begin(), second.size(),\n\t\t\tfirst.begin(), first.end()));\n\t}\n\n\tstruct S {\n\t\tstatic constexpr int throw_after = 42;\n\t\tstatic int count;\n\n\t\tstatic void increment() {\n\t\t\tif (++count >= throw_after) {\n\t\t\t\tthrow exception{};\n\t\t\t}\n\t\t}\n\n\t\tstruct exception {};\n\n\t\tS() = default;\n\t\tS(const S&) = default;\n\t\tS& operator=(const S&) & = default;\n\t\tS(const S&&) { increment(); }\n\t\tS& operator=(const S&&) & {\n\t\t\tincrement();\n\t\t\treturn *this;\n\t\t}\n\t};\n\tconstexpr int S::throw_after;\n\tint S::count;\n\n\tvoid throw_test() {\n\t\tconstexpr int n = 2 * S::throw_after;\n\t\tauto control = ranges::ext::repeat_view<S>{S{}};\n\t\tauto independent = make_buffer<S>(n);\n\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_move_n(control.begin(), n,\n\t\t\t\tindependent.begin(), independent.end());\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\n\t\tS::count = 0;\n\t\tauto control2 = ranges::ext::take_exactly_view<ranges::ext::repeat_view<S>>{\n\t\t\tstd::move(control), n\n\t\t};\n\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_move(control2, independent);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\t}\n}\n\n/**\n * Testing framework:\n * - test an array of fundamentals\n * - test an array of standard containers\n * - test an array of non-standard structures\n *\n * - initial array: using the default constructor\n * - second array:  using a non-default constructor\n */\nint main() {\n\tusing Test_type_one = Array<int>;\n\tusing Test_type_two = Array<std::vector<double>>;\n\tuninitialized_move_test(Test_type_one{});\n\tuninitialized_move_test(Test_type_two{});\n\tuninitialized_move_test(Array<Book>{});\n\n\tuninitialized_move_test(Test_type_one{0, 1, 2, 3, 4, 5, 6, 7});\n\tuninitialized_move_test(Test_type_two{{\n\t\t{0.0, 0.1, 0.2},\n\t\t{1.0, 1.1, 1.2, 1.3, 1.4},\n\t\t{2.0, 2.1, 2.2, 2.3},\n\t\t{3.01, 3.20, 3.33, 3.4},\n\t\t{4.101, 4.102, 4.201, 4.202, 4.311},\n\t\t{5.},\n\t\t{6.1, 3.02, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9},\n\t\tstd::vector<double>(1 << 12, 7.0)}});\n\n\tuninitialized_move_test(Move_only_t{\n\t\tstd::make_unique<std::string>(\"0\"),\n\t\tstd::make_unique<std::string>(\"0\"),\n\t\tstd::make_unique<std::string>(\"0\"),\n\t\tstd::make_unique<std::string>(\"0\"),\n\t\tstd::make_unique<std::string>(\"0\"),\n\t\tstd::make_unique<std::string>(\"0\"),\n\t\tstd::make_unique<std::string>(\"0\"),\n\t\tstd::make_unique<std::string>(\"0\")});\n\n\tthrow_test();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/memory/uninitialized_value_construct.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//  Copyright Christopher Di Bella 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/detail/memory/uninitialized_value_construct.hpp>\n#include <cstdint>\n#include <deque>\n#include <list>\n#include <memory>\n#include <string>\n#include <vector>\n#include <stl2/concepts.hpp>\n#include <stl2/detail/algorithm/find_if.hpp>\n#include <stl2/detail/memory/destroy.hpp>\n#include \"../simple_test.hpp\"\n#include \"common.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tconstexpr auto N = 1 << 10;\n\n\ttemplate<typename T>\n\trequires\n\t\tranges::default_initializable<T> &&\n\t\tranges::equality_comparable<T>\n\tvoid uninitialized_value_construct_test()\n\t{\n\t\tauto independent = make_buffer<T>(N);\n\t\tauto test = [&independent](const auto& p) {\n\t\t\tauto t = T{};\n\t\t\tCHECK(p == independent.end());\n\t\t\tCHECK(ranges::find_if(independent.begin(), p, [&t](const T& i){ return i != t; }) == p);\n\t\t\tranges::destroy(independent.begin(), p);\n\t\t};\n\n\t\ttest(ranges::uninitialized_value_construct(independent.begin(), independent.end()));\n\t\ttest(ranges::uninitialized_value_construct(independent.cbegin(), independent.cend()));\n\t\ttest(ranges::uninitialized_value_construct(independent));\n\t\ttest(ranges::uninitialized_value_construct_n(independent.begin(), independent.size()));\n\t\ttest(ranges::uninitialized_value_construct_n(independent.cbegin(), independent.size()));\n\t}\n\n\tstruct S {\n\t\tstatic constexpr int throw_after = 42;\n\t\tstatic int count;\n\n\t\tstatic void increment() {\n\t\t\tif (++count >= throw_after) {\n\t\t\t\tthrow exception{};\n\t\t\t}\n\t\t}\n\n\t\tstruct exception {};\n\n\t\tS() { increment(); }\n\t};\n\tconstexpr int S::throw_after;\n\tint S::count;\n\n\tvoid throw_test() {\n\t\tconstexpr int n = 2 * S::throw_after;\n\t\tauto independent = make_buffer<S>(n);\n\t\tS::count = 0;\n\t\ttry {\n\t\t\tranges::uninitialized_value_construct_n(independent.begin(), n);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\t\tS::count = 0;\n\n\t\ttry {\n\t\t\tranges::uninitialized_value_construct(independent);\n\t\t\tCHECK(false);\n\t\t} catch(S::exception&) {\n\t\t\tCHECK(S::count == S::throw_after);\n\t\t}\n\t\tS::count = 0;\n\t}\n}\n\nint main()\n{\n\tusing namespace std;\n\n\tuninitialized_value_construct_test<char>();\n\tuninitialized_value_construct_test<short>();\n\tuninitialized_value_construct_test<int>();\n\tuninitialized_value_construct_test<float>();\n\tuninitialized_value_construct_test<long>();\n\tuninitialized_value_construct_test<double>();\n\tuninitialized_value_construct_test<long long>();\n\tuninitialized_value_construct_test<vector<char>>();\n\tuninitialized_value_construct_test<string>();\n\tuninitialized_value_construct_test<deque<double>>();\n\tuninitialized_value_construct_test<list<vector<deque<double>>>>();\n\tuninitialized_value_construct_test<unique_ptr<string>>();\n\n\tthrow_test();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/meta.cpp",
    "content": "/// \\file meta.cpp Tests for Meta: a tiny metaprogramming library\n// Meta: a tiny metaprogramming library\n//\n//  Copyright Eric Niebler 2013-2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Acknowledgements: Thanks for Paul Fultz for the suggestions that\n//                   concepts can be ordinary boolean metafunctions.\n//\n// Project home: https://github.com/ericniebler/range-v3\n//\n#include <tuple>\n#include <meta/meta.hpp>\n#include \"simple_test.hpp\"\n\nusing namespace meta;\n\n// An implementation of tuple_cat gives Range v3's meta-programming and list\n// utilities a good workout. It's a good compiler stress test, too.\n\nnamespace tc_detail\n{\n\ttemplate<typename Ret, typename... Is, typename... Ks, typename Tuples>\n\tRet tuple_cat_(list<Is...>, list<Ks...>, Tuples tpls)\n\t{\n\t\treturn Ret{std::get<Ks::value>(std::get<Is::value>(tpls))...};\n\t}\n}\n\ntemplate<typename... Tuples,\n\t\t  typename Res = apply<quote<std::tuple>, concat<as_list<Tuples>...>>>\nRes tuple_cat(Tuples &&... tpls)\n{\n\tstatic constexpr std::size_t N = sizeof...(Tuples);\n\t// E.g. [0,0,0,2,2,2,3,3]\n\tusing inner = join<\n\t\ttransform<list<as_list<Tuples>...>,\n\t\t\t\t  transform<as_list<make_index_sequence<N>>, quote<id>>, quote<transform>>>;\n\t// E.g. [0,1,2,0,1,2,0,1]\n\tusing outer = join<\n\t\ttransform<list<as_list<Tuples>...>,\n\t\t\t\t  compose<quote<as_list>, quote_i<std::size_t, make_index_sequence>, quote<size>>>>;\n\treturn tc_detail::tuple_cat_<Res>(inner{}, outer{},\n\t\t\t\t\t\t\t\t\t  std::forward_as_tuple(std::forward<Tuples>(tpls)...));\n}\n\nvoid test_tuple_cat()\n{\n\tstd::tuple<int, short, long> t1;\n\tstd::tuple<> t2;\n\tstd::tuple<float, double, long double> t3;\n\tstd::tuple<void *, char *> t4;\n\n\tauto x = ::tuple_cat(t1, t2, t3, t4);\n\tusing expected_type = std::tuple<int, short, long, float, double, long double, void *, char *>;\n\tstatic_assert(std::is_same<decltype(x), expected_type>::value, \"\");\n}\n\n// Other misc tests\nstatic_assert(std::is_same<reverse<list<int, short, double>>, list<double, short, int>>::value, \"\");\n\nstatic_assert(all_of<list<int, short, long>, quote<std::is_integral>>::value, \"\");\nstatic_assert(none_of<list<int, short, long>, quote<std::is_floating_point>>::value, \"\");\nstatic_assert(!any_of<list<int, short, long>, quote<std::is_floating_point>>::value, \"\");\nstatic_assert(any_of<list<int, short, long, float>, quote<std::is_floating_point>>::value, \"\");\n\nstatic_assert(std::is_same<invoke<uncurry<curry<quote_trait<id>>>, std::tuple<int, short, double>>,\n\t\t\t\t\t\t   list<int, short, double>>::value,\n\t\t\t  \"\");\n\ntemplate<typename, typename, typename = void>\nstruct can_apply_ : std::false_type\n{\n};\n\ntemplate<typename F, typename... As>\nstruct can_apply_<F, meta::list<As...>, meta::void_<meta::invoke<F, As...>>> : std::true_type\n{\n};\n\ntemplate<typename F, typename... As>\nstruct can_apply : can_apply_<F, meta::list<As...>>\n{\n};\n\nstatic_assert(can_apply<meta::quote<std::pair>, int, int>::value, \"\");\n// I'm guessing this failure is due to GCC #64970\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64970\n#if !defined(__GNUC__) || defined(__clang__)\nstatic_assert(!can_apply<meta::quote<std::pair>, int, int, int>::value, \"\");\n#endif\n\n// Sanity-check meta::lambda\nusing Lambda0 = lambda<_a, _b, std::pair<_a, _b>>;\nusing Lambda1 = lambda<_a, _b, std::pair<_b, _a>>;\nusing Lambda2 = lambda<_a, _b, std::pair<_b, std::pair<_a, _a>>>;\nusing Pair0 = invoke<Lambda0, int, short>;\nusing Pair1 = invoke<Lambda1, int, short>;\nusing Pair2 = invoke<Lambda2, int, short>;\nstatic_assert(std::is_same<Pair0, std::pair<int, short>>::value, \"\");\nstatic_assert(std::is_same<Pair1, std::pair<short, int>>::value, \"\");\nstatic_assert(std::is_same<Pair2, std::pair<short, std::pair<int, int>>>::value, \"\");\n\n// Not saying you should do it this way, but it's a good test.\nnamespace l = meta::lazy;\ntemplate<class L>\nusing cart_prod = reverse_fold<\n\tL, list<list<>>,\n\tlambda<\n\t\t_a, _b,\n\t\tl::join<l::transform<\n\t\t\t_b, lambda<_c, l::join<l::transform<_a, lambda<_d, list<l::push_front<_d, _c>>>>>>>>>>;\n\nusing CartProd = cart_prod<meta::list<meta::list<int, short>, meta::list<float, double>>>;\nstatic_assert(\n\tstd::is_same<CartProd, meta::list<meta::list<int, float>, meta::list<int, double>,\n\t\t\t\t\t\t\t\t\t  meta::list<short, float>, meta::list<short, double>>>::value,\n\t\"\");\n\nstatic_assert(can_apply<lambda<_a, lazy::if_<std::is_integral<_a>, _a>>, int>::value, \"\");\n// I'm guessing this failure is due to GCC #64970\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64970\n#if !defined(__GNUC__) || defined(__clang__)\nstatic_assert(!can_apply<lambda<_a, lazy::if_<std::is_integral<_a>, _a>>, float>::value, \"\");\n#endif\n\ntemplate<typename List>\nusing rev = reverse_fold<List, list<>, lambda<_a, _b, defer<push_back, _a, _b>>>;\nstatic_assert(std::is_same<rev<list<int, short, double>>, list<double, short, int>>::value, \"\");\n\nusing uncvref_fn = lambda<_a, l::_t<std::remove_cv<l::_t<std::remove_reference<_a>>>>>;\nstatic_assert(std::is_same<invoke<uncvref_fn, int const &>, int>::value, \"\");\n\nusing L = list<int, short, int, float>;\nstatic_assert(std::is_same<find<L, int>, list<int, short, int, float>>::value, \"\");\nstatic_assert(std::is_same<reverse_find<L, int>, list<int, float>>::value, \"\");\n\nstruct check_integral\n{\n\ttemplate<class T>\n\tconstexpr T operator()(T &&i) const\n\t{\n\t\tstatic_assert(std::is_integral<T>{}, \"\");\n\t\treturn i;\n\t}\n};\n\n// Test for meta::let\ntemplate<typename T, typename List>\nusing find_index_ = let<\n\tvar<_a, List>, var<_b, lazy::find<_a, T>>,\n\tlazy::if_<std::is_same<_b, list<>>, meta::npos, lazy::minus<lazy::size<_a>, lazy::size<_b>>>>;\nstatic_assert(find_index_<int, list<short, int, float>>{} == 1, \"\");\nstatic_assert(find_index_<double, list<short, int, float>>{} == meta::npos{}, \"\");\n\n// Test that the unselected branch does not get evaluated:\ntemplate<typename T>\nusing test_lazy_if_ = let<lazy::if_<std::is_void<T>, T, defer<std::pair, T>>>;\nstatic_assert(std::is_same<test_lazy_if_<void>, void>::value, \"\");\n\n// Test that and_ gets short-circuited:\ntemplate<typename T>\nusing test_lazy_and_ = let<lazy::and_<std::is_void<T>, defer<std::is_convertible, T>>>;\nstatic_assert(std::is_same<test_lazy_and_<int>, std::false_type>::value, \"\");\n\n// Test that and_ gets short-circuited:\ntemplate<typename T>\nusing test_lazy_or_ = let<lazy::or_<std::is_void<T>, defer<std::is_convertible, T>>>;\nstatic_assert(std::is_same<test_lazy_or_<void>, std::true_type>::value, \"\");\n\ntemplate<typename A, int B = 0>\nstruct lambda_test\n{\n};\n\ntemplate<typename N>\nstruct fact\n\t: let<lazy::if_c<(N::value > 0), lazy::multiplies<N, defer<fact, dec<N>>>, meta::size_t<1>>>\n{\n};\n\nstatic_assert(fact<meta::size_t<0>>::value == 1, \"\");\nstatic_assert(fact<meta::size_t<1>>::value == 1, \"\");\nstatic_assert(fact<meta::size_t<2>>::value == 2, \"\");\nstatic_assert(fact<meta::size_t<3>>::value == 6, \"\");\nstatic_assert(fact<meta::size_t<4>>::value == 24, \"\");\n\ntemplate<std::size_t N>\nstruct fact2\n\t: let<lazy::if_c<(N > 0), lazy::multiplies<meta::size_t<N>, defer_i<std::size_t, fact2, N - 1>>,\n\t\t\t\t\t meta::size_t<1>>>\n{\n};\n\nstatic_assert(fact2<0>::value == 1, \"\");\nstatic_assert(fact2<1>::value == 1, \"\");\nstatic_assert(fact2<2>::value == 2, \"\");\nstatic_assert(fact2<3>::value == 6, \"\");\nstatic_assert(fact2<4>::value == 24, \"\");\n\ntemplate<typename N>\nstruct factorial\n\t: let<if_c<N::value == 0, meta::size_t<1>, lazy::multiplies<N, factorial<lazy::dec<N>>>>>\n{\n};\n\nstatic_assert(factorial<meta::size_t<0>>::value == 1, \"\");\nstatic_assert(factorial<meta::size_t<1>>::value == 1, \"\");\nstatic_assert(factorial<meta::size_t<2>>::value == 2, \"\");\nstatic_assert(factorial<meta::size_t<3>>::value == 6, \"\");\nstatic_assert(factorial<meta::size_t<4>>::value == 24, \"\");\n\n// transpose\nstatic_assert(std::is_same<\n\tmeta::transpose<meta::list<meta::list<int, short>, meta::list<int*, short*>, meta::list<int**, short**>>>,\n\tmeta::list<meta::list<int, int*, int**>, meta::list<short, short*, short**>>\n>::value, \"\");\n\nstatic_assert(std::is_same<\n\tmeta::zip_with<meta::quote<meta::list>, meta::list<meta::list<int, short>, meta::list<int*, short*>, meta::list<int**, short**>>>,\n\tmeta::list<meta::list<int, int*, int**>, meta::list<short, short*, short**>>\n>::value, \"\");\n\nint main()\n{\n\t// meta::sizeof_\n\tstatic_assert(meta::sizeof_<int>{} == sizeof(int), \"\");\n\n\t// meta::min\n\tstatic_assert(meta::min<meta::size_t<0>, meta::size_t<1>>{} == 0, \"\");\n\tstatic_assert(meta::min<meta::size_t<0>, meta::size_t<0>>{} == 0, \"\");\n\tstatic_assert(meta::min<meta::size_t<1>, meta::size_t<0>>{} == 0, \"\");\n\n\t// meta::max\n\tstatic_assert(meta::max<meta::size_t<0>, meta::size_t<1>>{} == 1, \"\");\n\tstatic_assert(meta::max<meta::size_t<1>, meta::size_t<0>>{} == 1, \"\");\n\tstatic_assert(meta::max<meta::size_t<1>, meta::size_t<1>>{} == 1, \"\");\n\n\t// meta::filter\n\t{\n\t\tusing l = meta::list<int, double, short, float, long, char>;\n\t\tusing il = meta::list<int, short, long, char>;\n\t\tusing fl = meta::list<double, float>;\n\n\t\tstatic_assert(std::is_same<il, meta::filter<l, meta::quote<std::is_integral>>>{}, \"\");\n\t\tstatic_assert(std::is_same<fl, meta::filter<l, meta::quote<std::is_floating_point>>>{}, \"\");\n\t}\n\n\t// meta::for_each\n\t{\n\t\tusing l = meta::list<int, long, short>;\n\t\tconstexpr auto r = meta::for_each(l{}, check_integral());\n\t\tstatic_assert(std::is_same<meta::_t<std::remove_cv<decltype(r)>>, check_integral>::value,\n\t\t\t\t\t  \"\");\n\t}\n\n\t// meta::find_index\n\t{\n\t\tusing l = meta::list<int, long, short, int>;\n\t\tstatic_assert(meta::find_index<l, int>{} == 0, \"\");\n\t\tstatic_assert(meta::find_index<l, long>{} == 1, \"\");\n\t\tstatic_assert(meta::find_index<l, short>{} == 2, \"\");\n\t\tstatic_assert(meta::find_index<l, double>{} == meta::npos{}, \"\");\n\t\tstatic_assert(meta::find_index<l, float>{} == meta::npos{}, \"\");\n\n\t\tusing l2 = meta::list<>;\n\t\tstatic_assert(meta::find_index<l2, double>{} == meta::npos{}, \"\");\n\n\t\tusing namespace meta::placeholders;\n\n\t\tusing lambda = meta::lambda<_a, _b, meta::lazy::find_index<_b, _a>>;\n\t\tusing result = meta::invoke<lambda, long, l>;\n\t\tstatic_assert(result{} == 1, \"\");\n\t}\n\n\t// meta::reverse_find_index\n\t{\n\t\tusing l = meta::list<int, long, short, int>;\n\n\t\tstatic_assert(meta::reverse_find_index<l, int>{} == 3, \"\");\n\t\tstatic_assert(meta::reverse_find_index<l, long>{} == 1, \"\");\n\t\tstatic_assert(meta::reverse_find_index<l, short>{} == 2, \"\");\n\t\tstatic_assert(meta::reverse_find_index<l, double>{} == meta::npos{}, \"\");\n\t\tstatic_assert(meta::reverse_find_index<l, float>{} == meta::npos{}, \"\");\n\n\t\tusing l2 = meta::list<>;\n\t\tstatic_assert(meta::reverse_find_index<l2, double>{} == meta::npos{}, \"\");\n\n\t\tusing lambda = meta::lambda<_a, _b, meta::lazy::reverse_find_index<_b, _a>>;\n\t\tusing result = meta::invoke<lambda, long, l>;\n\t\tstatic_assert(result{} == 1, \"\");\n\t}\n\n\t// meta::count\n\t{\n\t\tusing l = meta::list<int, long, short, int>;\n\t\tstatic_assert(meta::count<l, int>{} == 2, \"\");\n\t\tstatic_assert(meta::count<l, short>{} == 1, \"\");\n\t\tstatic_assert(meta::count<l, double>{} == 0, \"\");\n\t}\n\n\t// meta::count_if\n\t{\n\t\tusing l = meta::list<int, long, short, int>;\n\t\tstatic_assert(meta::count_if<l, lambda<_a, std::is_same<_a, int>>>{} == 2, \"\");\n\t\tstatic_assert(meta::count_if<l, lambda<_b, std::is_same<_b, short>>>{} == 1, \"\");\n\t\tstatic_assert(meta::count_if<l, lambda<_c, std::is_same<_c, double>>>{} == 0, \"\");\n\t}\n\n\t// pathological lambda test\n\t{\n\t\tusing X = invoke<lambda<_a, lambda_test<_a>>, int>;\n\t\tstatic_assert(std::is_same<X, lambda_test<_a>>::value, \"\");\n\t}\n\n\t// meta::unique\n\t{\n\t\tusing l = meta::list<int, short, int, double, short, double, double>;\n\t\tstatic_assert(std::is_same<meta::unique<l>, list<int, short, double>>::value, \"\");\n\t}\n\n\t// meta::in\n\t{\n\t\tstatic_assert(in<list<int, int, short, float>, int>::value, \"\");\n\t\tstatic_assert(in<list<int, int, short, float>, short>::value, \"\");\n\t\tstatic_assert(in<list<int, int, short, float>, float>::value, \"\");\n\t\tstatic_assert(!in<list<int, int, short, float>, double>::value, \"\");\n\t}\n\n\t// lambda with variadic placeholders\n\t{\n\t\tusing X = invoke<lambda<_args, list<_args>>, int, short, double>;\n\t\tstatic_assert(std::is_same<X, list<int, short, double>>::value, \"\");\n\n\t\tusing X2 = invoke<lambda<_a, lambda_test<_a>>, int>;\n\t\tstatic_assert(std::is_same<X2, lambda_test<_a>>::value, \"\");\n\n\t\tusing Y = invoke<lambda<_args, defer<std::pair, _args>>, int, short>;\n\t\tstatic_assert(std::is_same<Y, std::pair<int, short>>::value, \"\");\n\n\t\tusing Y2 = invoke<lambda<_args, list<_args, list<_args>>>, int, short>;\n\t\tstatic_assert(std::is_same<Y2, list<int, short, list<int, short>>>::value, \"\");\n\n\t\tusing Z = invoke<lambda<_a, _args, list<int, _args, double, _a>>, short *, short, float>;\n\t\tstatic_assert(std::is_same<Z, list<int, short, float, double, short *>>::value, \"\");\n\n\t\t// Nesting variadic lambdas in non-variadic lambdas:\n\t\tusing A = invoke<lambda<_a, lazy::invoke<lambda<_b, _args, list<_args, _b>>, _a,\n\t\t\t\t\t\t\t\t\t\t\t   lazy::_t<std::add_pointer<_a>>,\n\t\t\t\t\t\t\t\t\t\t\t   lazy::_t<std::add_lvalue_reference<_a>>>>,\n\t\t\t\t\t\tint>;\n\t\tstatic_assert(std::is_same<A, list<int *, int &, int>>::value, \"\");\n\n\t\t// Nesting non-variadic lambdas in variadic lambdas:\n\t\tusing B = invoke<lambda<_a, _args, lazy::invoke<lambda<_b, list<_b, _args, _a>>, _a>>, int,\n\t\t\t\t\t\tshort, double>;\n\t\tstatic_assert(std::is_same<B, list<int, short, double, int>>::value, \"\");\n\n\t\t// Nesting variadic lambdas in variadic lambdas:\n\t\tusing ZZ = invoke<\n\t\t\tlambda<_a, _args_a,\n\t\t\t\t   lazy::invoke<lambda<_b, _args_b, list<_b, _a, list<_args_b>, list<_args_a>>>,\n\t\t\t\t\t\t\t   _args_a>>,\n\t\t\tint, short, float, double>;\n\t\tstatic_assert(\n\t\t\tstd::is_same<ZZ,\n\t\t\t\t\t\t list<short, int, list<float, double>, list<short, float, double>>>::value,\n\t\t\t\"\");\n\n// I'm guessing this failure is due to GCC #64970\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64970\n#if !defined(__GNUC__) || defined(__clang__)\n\t\tstatic_assert(!can_apply<lambda<_args, defer<std::pair, _args>>, int>::value, \"\");\n\t\tstatic_assert(!can_apply<lambda<_args, defer<std::pair, _args>>, int, short, double>::value,\n\t\t\t\t\t  \"\");\n\t\tstatic_assert(!can_apply<lambda<_a, defer<std::pair, _a, _a>>, int, short>::value, \"\");\n\t\tstatic_assert(!can_apply<lambda<_a, _b, _c, _args, defer<std::pair, _a, _a>>>::value, \"\");\n#endif\n\t}\n\n\t// Test for meta::sort\n\t{\n\t\tusing L0 = list<char[5], char[3], char[2], char[6], char[1], char[5], char[10]>;\n\t\tusing L2 = meta::sort<L0, lambda<_a, _b, lazy::less<lazy::sizeof_<_a>, lazy::sizeof_<_b>>>>;\n\t\tstatic_assert(\n\t\t\tstd::is_same<\n\t\t\t\tL2, list<char[1], char[2], char[3], char[5], char[5], char[6], char[10]>>::value,\n\t\t\t\"\");\n\t}\n\n\t// Check the _z user-defined literal:\n\tstatic_assert(42_z == 42, \"\");\n\n\t// Check integer_range\n\t{\n\t\tconstexpr std::size_t a = meta::fold<meta::as_list<meta::integer_range<std::size_t, 0, 5>>,\n\t\t\t\t\t\t\t\t\t\t\t meta::size_t<0>, meta::quote<meta::plus>>{};\n\n\t\tstatic_assert(a == 10, \"\");\n\n\t\tconstexpr std::size_t b = meta::fold<meta::as_list<meta::integer_range<std::size_t, 5, 10>>,\n\t\t\t\t\t\t\t\t\t\t\t meta::size_t<0>, meta::quote<meta::plus>>{};\n\n\t\tstatic_assert(b == 35, \"\");\n\n\t\tusing c = meta::integer_range<std::size_t, 5, 10>;\n\t\tstatic_assert(std::is_same<c, meta::integer_sequence<std::size_t, 5, 6, 7, 8, 9>>{}, \"\");\n\t}\n\n\ttest_tuple_cat();\n\n\t{\n\t\tstatic_assert(meta::Integral<std::true_type>);\n\t\tstatic_assert(meta::Integral<std::integral_constant<std::size_t, 42>>);\n\t\tstatic_assert(meta::Integral<std::integral_constant<int, -42>>);\n\n\t\tstruct S1 : std::integral_constant<int, 42>\n\t\t{\n\t\t};\n\t\tstatic_assert(meta::Integral<S1>);\n\n#if !defined(__GNUC__) || defined(__clang__) // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88515\n\t\tstruct S2 : S1\n\t\t{\n\t\t\tconst int value;\n\t\t};\n\t\tstatic_assert(!meta::Integral<S2>);\n#endif\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/move_only_string.hpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#ifndef STL2_MOVE_ONLY_STRING_HPP\n#define STL2_MOVE_ONLY_STRING_HPP\n\n#include <cstring>\n#include <ostream>\n#include <stl2/detail/swap.hpp>\n\nnamespace cmcstl2_test {\n\tnamespace ranges = __stl2;\n\t// a simple type to test move semantics\n\tstruct move_only_string {\n\t\tmove_only_string(char const* sz = \"\") noexcept\n\t\t: sz_(sz)\n\t\t, length_(std::strlen(sz))\n\t\t{}\n\t\tmove_only_string(move_only_string&& that) noexcept\n\t\t: sz_(ranges::exchange(that.sz_, \"\"))\n\t\t, length_(ranges::exchange(that.length_, {}))\n\t\t{}\n\t\tmove_only_string(move_only_string const&) = delete;\n\t\tmove_only_string& operator=(move_only_string&& that) noexcept\n\t\t{\n\t\t\t*this = ranges::exchange(that, {});\n\t\t\treturn *this;\n\t\t}\n\t\tmove_only_string& operator=(move_only_string const&) = delete;\n\n\t\tchar operator[](const std::size_t n) noexcept\n\t\t{ return subscript_impl(*this, n); }\n\n\t\tchar operator[](const std::size_t n) const noexcept\n\t\t{ return subscript_impl(*this, n); }\n\n\t\tfriend bool operator==(const move_only_string& x, const move_only_string& y) noexcept\n\t\t{  return 0 == std::strcmp(x.sz_, y.sz_); }\n\n\t\tfriend bool operator!=(const move_only_string& x, const move_only_string& y) noexcept\n\t\t{ return !(x == y); }\n\n\t\tfriend bool operator<(const move_only_string& x, const move_only_string& y) noexcept\n\t\t{ return std::strcmp(x.sz_, y.sz_) < 0; }\n\n\t\tfriend bool operator<=(const move_only_string& x, const move_only_string& y) noexcept\n\t\t{ return !(y < x); }\n\n\t\tfriend bool operator>=(const move_only_string& x, const move_only_string& y) noexcept\n\t\t{ return !(x < y); }\n\n\t\tfriend bool operator>(const move_only_string& x, const move_only_string& y) noexcept\n\t\t{ return y < x; }\n\n\t\tfriend std::ostream& operator<<(std::ostream& sout, move_only_string const& str)\n\t\t{ return sout << '\"' << str.sz_ << '\"'; }\n\tprivate:\n\t\tchar const* sz_;\n\t\tstd::size_t length_;\n\n\t\ttemplate<class Self>\n\t\tstatic char subscript_impl(Self& self, const std::size_t n)\n\t\t{\n\t\t\tSTL2_EXPECT(n < self.length_);\n\t\t\treturn self.sz_[self.length_];\n\t\t}\n\t};\n} // namespace cmcstl2_test\n\n#endif // STL2_MOVE_ONLY_STRING_HPP\n"
  },
  {
    "path": "test/range_access.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//  Copyright Eric Niebler 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/iterator.hpp>\n#include <stl2/detail/algorithm/find.hpp>\n#include <stl2/view/subrange.hpp>\n#include <stl2/view/ref.hpp>\n#include <stl2/view/iota.hpp>\n#include <iostream>\n#include <vector>\n#include <utility>\n#include \"simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nvoid test_range_access_ambiguity() {\n\tstd::vector<ranges::reverse_iterator<int*>> vri{};\n\tusing namespace ranges;\n\t(void)begin(vri);\n\t(void)end(vri);\n\t(void)cbegin(vri);\n\t(void)cend(vri);\n\t(void)rbegin(vri);\n\t(void)rend(vri);\n\t(void)crbegin(vri);\n\t(void)crend(vri);\n}\n\nvoid test_initializer_list() {\n\tstd::initializer_list<int> il = {0,1,2};\n\t{\n\t\tint count = 0;\n\t\tfor (auto p = ranges::begin(il), e = ranges::end(il); p != e; ++p) {\n\t\t\tCHECK(*p == count++);\n\t\t}\n\t}\n\t{\n\t\tint count = 3;\n\t\tfor (auto p = ranges::rbegin(il), e = ranges::rend(il); p != e; ++p) {\n\t\t\tCHECK(*p == --count);\n\t\t}\n\t}\n\tCHECK(ranges::size(il) == std::size_t{3});\n\tCHECK(ranges::data(il) == &*il.begin());\n\tCHECK(ranges::empty(il) == false);\n}\n\ntemplate<class T, std::size_t... Is>\nvoid test_array(std::index_sequence<Is...>) {\n\tT a[sizeof...(Is)] = { Is... };\n\t{\n\t\tint count = 0;\n\t\tfor (auto p = ranges::begin(a), e = ranges::end(a); p != e; ++p) {\n\t\t\tCHECK(*p == count++);\n\t\t}\n\t}\n\t{\n\t\tint count = sizeof...(Is);\n\t\tfor (auto p = ranges::rbegin(a), e = ranges::rend(a); p != e; ++p) {\n\t\t\tCHECK(*p == --count);\n\t\t}\n\t}\n\tCHECK(ranges::size(a) == sizeof...(Is));\n\tCHECK(ranges::data(a) == a + 0);\n\tCHECK(ranges::empty(a) == false);\n}\n\nnamespace begin_testing {\n\ttemplate<class R>\n\tMETA_CONCEPT CanBegin =\n\t\trequires(R&& r) {\n\t\t\tranges::begin((R&&)r);\n\t\t};\n\n\ttemplate<class R>\n\tMETA_CONCEPT CanCBegin =\n\t\trequires(R&& r) {\n\t\t\tranges::cbegin((R&&)r);\n\t\t};\n\n\tstruct A {\n\t\tint* begin();\n\t\tint* end();\n\t\tconst int* begin() const;\n\t\tconst int* end() const;\n\t};\n\n\tstruct B : A {};\n\tvoid* begin(B&);\n\n\tstruct C : A {};\n\tvoid begin(C&);\n\n\tstruct D : A {};\n\tchar* begin(D&);\n\n\tvoid test() {\n\t\t// Valid\n\t\tstatic_assert(CanBegin<int(&)[2]>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<int(&)[2]>())), int*>);\n\t\tstatic_assert(CanBegin<const int(&)[2]>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<const int(&)[2]>())), const int*>);\n\n\t\tstatic_assert(CanCBegin<int(&)[2]>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::cbegin(std::declval<int(&)[2]>())), const int*>);\n\t\tstatic_assert(CanCBegin<const int(&)[2]>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::cbegin(std::declval<const int(&)[2]>())), const int*>);\n\n\t\t// Ill-formed: array rvalue\n\t\tstatic_assert(!CanBegin<int(&&)[2]>);\n\t\tstatic_assert(!CanBegin<const int(&&)[2]>);\n\n\t\tstatic_assert(!CanCBegin<int(&&)[2]>);\n\t\tstatic_assert(!CanCBegin<const int(&&)[2]>);\n\n\t\t// Valid: only member begin\n\t\tstatic_assert(CanBegin<A&>);\n\t\tstatic_assert(!CanBegin<A>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<A&>())), int*>);\n\t\tstatic_assert(CanBegin<const A&>);\n\t\tstatic_assert(!CanBegin<const A>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<const A&>())), const int*>);\n\n\t\t// Valid: Both member and non-member begin, but non-member returns non-input_or_output_iterator.\n\t\tstatic_assert(CanBegin<B&>);\n\t\tstatic_assert(!CanBegin<B>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<B&>())), int*>);\n\t\tstatic_assert(CanBegin<const B&>);\n\t\tstatic_assert(!CanBegin<const B>);\n\t\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<const B&>())), const int*>);\n\n\t\t// Valid: Both member and non-member begin, but non-member returns non-input_or_output_iterator.\n\t\tstatic_assert(CanBegin<C&>);\n\t\tstatic_assert(!CanBegin<C>);\n\t\tstatic_assert(CanBegin<const C&>);\n\t\tstatic_assert(!CanBegin<const C>);\n\n\t\t// Valid: Prefer member begin\n\t\tstatic_assert(CanBegin<D&>);\n\t\tstatic_assert(!CanBegin<D>);\n\t\tstatic_assert(ranges::same_as<int*, decltype(ranges::begin(std::declval<D&>()))>);\n\t\tstatic_assert(CanBegin<const D&>);\n\t\tstatic_assert(!CanBegin<const D>);\n\t\tstatic_assert(ranges::same_as<const int*, decltype(ranges::begin(std::declval<const D&>()))>);\n\n\t\t{\n\t\t\tusing T = std::initializer_list<int>;\n\t\t\t// Valid: begin accepts lvalue initializer_list\n\t\t\tstatic_assert(ranges::same_as<const int*, decltype(ranges::begin(std::declval<T&>()))>);\n\t\t\tstatic_assert(ranges::same_as<const int*, decltype(ranges::begin(std::declval<const T&>()))>);\n\t\t\tstatic_assert(!CanBegin<std::initializer_list<int>>);\n\t\t\tstatic_assert(!CanBegin<const std::initializer_list<int>>);\n\t\t}\n\n\t\tstatic_assert(CanBegin<ranges::subrange<int*, int*>&>);\n\t\tstatic_assert(CanBegin<const ranges::subrange<int*, int*>&>);\n\t\tstatic_assert(CanBegin<ranges::subrange<int*, int*>>);\n\t\tstatic_assert(CanBegin<const ranges::subrange<int*, int*>>);\n\n\t\tstatic_assert(CanCBegin<ranges::subrange<int*, int*>&>);\n\t\tstatic_assert(CanCBegin<const ranges::subrange<int*, int*>&>);\n\t\tstatic_assert(CanCBegin<ranges::subrange<int*, int*>>);\n\t\tstatic_assert(CanCBegin<const ranges::subrange<int*, int*>>);\n\n\t\tstatic_assert(CanBegin<ranges::ref_view<int[5]>&>);\n\t\tstatic_assert(CanBegin<const ranges::ref_view<int[5]>&>);\n\t\tstatic_assert(CanBegin<ranges::ref_view<int[5]>>);\n\t\tstatic_assert(CanBegin<const ranges::ref_view<int[5]>>);\n\n\t\tstatic_assert(CanCBegin<ranges::ref_view<int[5]>&>);\n\t\tstatic_assert(CanCBegin<const ranges::ref_view<int[5]>&>);\n\t\tstatic_assert(CanCBegin<ranges::ref_view<int[5]>>);\n\t\tstatic_assert(CanCBegin<const ranges::ref_view<int[5]>>);\n\n\t\tstatic_assert(CanBegin<ranges::iota_view<int, int>&>);\n\t\tstatic_assert(CanBegin<const ranges::iota_view<int, int>&>);\n\t\tstatic_assert(CanBegin<ranges::iota_view<int, int>>);\n\t\tstatic_assert(CanBegin<const ranges::iota_view<int, int>>);\n\n\t\tstatic_assert(CanCBegin<ranges::iota_view<int, int>&>);\n\t\tstatic_assert(CanCBegin<const ranges::iota_view<int, int>&>);\n\t\tstatic_assert(CanCBegin<ranges::iota_view<int, int>>);\n\t\tstatic_assert(CanCBegin<const ranges::iota_view<int, int>>);\n\t}\n} // namespace begin_testing\n\nnamespace X {\n\ttemplate<class T, std::size_t N>\n\t\trequires (N != 0)\n\tstruct array {\n\t\tT elements_[N];\n\n\t\tconstexpr bool empty() const noexcept { return N == 0; }\n\t\tconstexpr T* data() noexcept { return elements_; }\n\t\tconstexpr const T* data() const noexcept { return elements_; }\n\t};\n\n\ttemplate<class T, std::size_t N>\n\tconstexpr T* begin(array<T, N>& a) noexcept { return a.elements_; }\n\ttemplate<class T, std::size_t N>\n\tconstexpr T* end(array<T, N>& a) noexcept { return a.elements_ + N; }\n\ttemplate<class T, std::size_t N>\n\tconstexpr const T* begin(const array<T, N>& a) noexcept { return a.elements_; }\n\ttemplate<class T, std::size_t N>\n\tconstexpr const T* end(const array<T, N>& a) noexcept { return a.elements_ + N; }\n\n\ttemplate<class T, std::size_t N>\n\t\trequires (N != 0)\n\tstruct non_constexpr_array {\n\t\tT elements_[N];\n\n\t\tbool empty() const noexcept { return N == 0; }\n\t\tT* data() noexcept { return elements_; }\n\t\tconst T* data() const noexcept { return elements_; }\n\t};\n\n\ttemplate<class T, std::size_t N>\n\tT* begin(non_constexpr_array<T, N>& a) noexcept { return a.elements_; }\n\ttemplate<class T, std::size_t N>\n\tT* end(non_constexpr_array<T, N>& a) noexcept { return a.elements_ + N; }\n\ttemplate<class T, std::size_t N>\n\tconst T* begin(const non_constexpr_array<T, N>& a) noexcept { return a.elements_; }\n\ttemplate<class T, std::size_t N>\n\tconst T* end(const non_constexpr_array<T, N>& a) noexcept { return a.elements_ + N; }\n} // namespace X\n\nusing I = int*;\nusing CI = const int*;\nstatic_assert(ranges::input_or_output_iterator<I>);\nstatic_assert(ranges::input_or_output_iterator<CI>);\n\nvoid test_string_view_p0970() {\n\t// basic_string_views are non-dangling\n\tusing I = ranges::iterator_t<std::string_view>;\n\tstatic_assert(ranges::same_as<I, decltype(ranges::begin(std::declval<std::string_view>()))>);\n\tstatic_assert(ranges::same_as<I, decltype(ranges::end(std::declval<std::string_view>()))>);\n\tstatic_assert(ranges::same_as<I, decltype(ranges::begin(std::declval<const std::string_view>()))>);\n\tstatic_assert(ranges::same_as<I, decltype(ranges::end(std::declval<const std::string_view>()))>);\n\n\t{\n\t\tconst char hw[] = \"Hello, World!\";\n\t\tauto result = ranges::find(std::string_view{hw}, 'W');\n\t\tstatic_assert(ranges::same_as<I, decltype(result)>);\n\t\tCHECK(result == std::string_view{hw}.begin() + 7);\n\t}\n}\n\nint main() {\n\tusing namespace ranges;\n\n\tstatic constexpr X::array<int, 4> some_ints = {{0,1,2,3}};\n\n\tconstexpr auto first = begin(some_ints);\n\tconstexpr auto last = end(some_ints);\n\tstatic_assert(ranges::same_as<const CI, decltype(first)>);\n\tstatic_assert(ranges::same_as<const CI, decltype(last)>);\n\tstatic_assert(first == cbegin(some_ints));\n\tstatic_assert(last == cend(some_ints));\n\n\t{\n\t\tX::non_constexpr_array<int, 4> not_a_constant_expression{{0,1,2,3}};\n\t\tstatic_assert(noexcept(begin(not_a_constant_expression)));\n\t\tstatic_assert(noexcept(end(not_a_constant_expression)));\n\t\tstatic_assert(noexcept(cbegin(not_a_constant_expression)));\n\t\tstatic_assert(noexcept(cend(not_a_constant_expression)));\n\t\tstatic_assert(noexcept(empty(not_a_constant_expression)));\n\t\tstatic_assert(noexcept(data(not_a_constant_expression)));\n\t}\n\n\tconstexpr bool output = false;\n\tstatic_assert(!empty(some_ints));\n\tif (output) std::cout << '{';\n\tauto is_first = true;\n\tauto count = 0;\n\tfor (auto&& i : some_ints) {\n\t\tCHECK(i == count++);\n\t\tif (is_first) {\n\t\t\tis_first = false;\n\t\t} else {\n\t\t\tif (output) std::cout << \", \";\n\t\t}\n\t\tif (output) std::cout << i;\n\t}\n\tif (output) std::cout << \"}\\n\";\n\n\ttest_initializer_list();\n\ttest_array<int>(std::make_index_sequence<3>{});\n\ttest_array<const int>(std::make_index_sequence<3>{});\n\tbegin_testing::test();\n\n\ttest_string_view_p0970();\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/simple_test.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n\n#ifndef STL2_SIMPLE_TEST_HPP\n#define STL2_SIMPLE_TEST_HPP\n\n#include <cstdlib>\n#include <utility>\n#include <iostream>\n#include <typeinfo>\n#include <stl2/iterator.hpp>\n\nnamespace ranges = std::experimental::ranges;\n\nnamespace test_impl\n{\n\tinline int &test_failures()\n\t{\n\t\tstatic int test_failures = 0;\n\t\treturn test_failures;\n\t}\n\n\ttemplate<typename T>\n\tstruct streamable_base\n\t{};\n\n\ttemplate<typename T>\n\tstd::ostream &operator<<(std::ostream &sout, streamable_base<T> const &)\n\t{\n\t\treturn sout << \"<non-streamable type>\";\n\t}\n\n\ttemplate<typename T>\n\tstruct streamable : streamable_base<T>\n\t{\n\tprivate:\n\t\tT const &t_;\n\tpublic:\n\t\texplicit streamable(T const &t) : t_(t) {}\n\t\ttemplate<typename U = T>\n\t\tfriend auto operator<<(std::ostream &sout, streamable const &s) ->\n\t\t\tdecltype(sout << std::declval<U const &>())\n\t\t{\n\t\t\treturn sout << s.t_;\n\t\t}\n\t};\n\n\ttemplate<typename T>\n\tstreamable<T> stream(T const &t)\n\t{\n\t\treturn streamable<T>{t};\n\t}\n\n\ttemplate<typename T>\n\tstruct R\n\t{\n\tprivate:\n\t\tchar const *filename_;\n\t\tchar const *expr_;\n\t\tchar const *func_;\n\t\tT t_;\n\t\tint lineno_;\n\t\tbool dismissed_ = false;\n\n\t\ttemplate<typename U>\n\t\tvoid oops(U const &u) const\n\t\t{\n\t\t\tstd::cerr\n\t\t\t\t<< \"> ERROR: CHECK failed \\\"\" << expr_ << \"\\\"\\n\"\n\t\t\t\t<< \"> \\t\" << filename_ << '(' << lineno_ << ')' << '\\n'\n\t\t\t\t<< \"> \\t in function \\\"\" << func_ << \"\\\"\\n\";\n\t\t\tif(dismissed_)\n\t\t\t\tstd::cerr\n\t\t\t\t\t<< \"> \\tEXPECTED: \" << stream(u) << \"\\n> \\tACTUAL: \" << stream(t_) << '\\n';\n\t\t\t++test_failures();\n\t\t}\n\t\tvoid dismiss()\n\t\t{\n\t\t\tdismissed_ = true;\n\t\t}\n\t\ttemplate<typename V = T>\n\t\tauto eval_(int) -> decltype(!std::declval<V>())\n\t\t{\n\t\t\treturn !t_;\n\t\t}\n\t\tbool eval_(long)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\tpublic:\n\t\tR(char const *filename, int lineno, char const *expr, const char* func, T && t)\n\t\t  : filename_(filename), expr_(expr), func_(func)\n\t\t  , t_(std::forward<T>(t)), lineno_(lineno)\n\t\t{}\n\t\tR(R const&) = delete;\n\t\tR& operator=(R const&) = delete;\n\t\t~R()\n\t\t{\n\t\t\tif(!dismissed_ && eval_(42))\n\t\t\t\tthis->oops(42);\n\t\t}\n\t\ttemplate<typename U>\n\t\tvoid operator==(U const &u)\n\t\t{\n\t\t\tdismiss();\n\t\t\tif(!(t_ == u)) this->oops(u);\n\t\t}\n\t\ttemplate<typename U>\n\t\tvoid operator!=(U const &u)\n\t\t{\n\t\t\tdismiss();\n\t\t\tif(!(t_ != u)) this->oops(u);\n\t\t}\n\t\ttemplate<typename U>\n\t\tvoid operator<(U const &u)\n\t\t{\n\t\t\tdismiss();\n\t\t\tif(!(t_ < u)) this->oops(u);\n\t\t}\n\t\ttemplate<typename U>\n\t\tvoid operator<=(U const &u)\n\t\t{\n\t\t\tdismiss();\n\t\t\tif(!(t_ <= u)) this->oops(u);\n\t\t}\n\t\ttemplate<typename U>\n\t\tvoid operator>(U const &u)\n\t\t{\n\t\t\tdismiss();\n\t\t\tif(!(t_ > u)) this->oops(u);\n\t\t}\n\t\ttemplate<typename U>\n\t\tvoid operator>=(U const &u)\n\t\t{\n\t\t\tdismiss();\n\t\t\tif(!(t_ >= u)) this->oops(u);\n\t\t}\n\t};\n\n\tstruct S\n\t{\n\tprivate:\n\t\tchar const *filename_;\n\t\tchar const *expr_;\n\t\tchar const *func_;\n\t\tint lineno_;\n\tpublic:\n\t\tS(char const *filename, int lineno, char const *expr, char const *func)\n\t\t  : filename_(filename), expr_(expr), func_(func), lineno_(lineno)\n\t\t{}\n\t\ttemplate<typename T>\n\t\tR<T> operator->*(T && t)\n\t\t{\n\t\t\treturn {filename_, lineno_, expr_, func_, std::forward<T>(t)};\n\t\t}\n\t};\n}\n\ninline int test_result()\n{\n\treturn ::test_impl::test_failures() ? EXIT_FAILURE : EXIT_SUCCESS;\n}\n\n#if defined(_MSC_VER) && !defined(__clang__)\n#define STL2_PRETTY_FUNCTION __FUNCSIG__\n#else\n#define STL2_PRETTY_FUNCTION __PRETTY_FUNCTION__\n#endif\n\n#define CHECK(...)                                                                                  \\\n\t(void)(::test_impl::S{__FILE__, __LINE__, #__VA_ARGS__, STL2_PRETTY_FUNCTION} ->* __VA_ARGS__)  \\\n\t/**/\n\ntemplate<typename Rng, typename Rng2>\nconstexpr void check_equal_(const char* file, int line, const char* lhs, const char* rhs,\n\tconst char* fun, Rng && actual, Rng2&& expected)\n{\n\tauto begin0 = ranges::begin(actual);\n\tauto end0 = ranges::end(actual);\n\tauto begin1 = ranges::begin(expected);\n\tauto end1 = ranges::end(expected);\n\n\tfor(std::size_t i = 0; begin0 != end0 && begin1 != end1; ++begin0, (void)++i, ++begin1) {\n\t\tif (*begin0 != *begin1) {\n\t\t\tstd::cerr <<\n\t\t\t\t\"> ERROR: CHECK failed \\\"\" << lhs << '[' << i << \"] != \" << rhs << '[' << i << \"]\\\"\\n\"\n\t\t\t\t\"> \\t\" << file << '(' << line << ')' << \"\\n\"\n\t\t\t\t\"> \\t in function \\\"\" << fun << \"\\\"\\n\"\n\t\t\t\t\"> \\tEXPECTED: \" << test_impl::stream(*begin1) << \"\\n\"\n\t\t\t\t\"> \\tACTUAL: \" << test_impl::stream(*begin0) << '\\n';\n\t\t\t++test_impl::test_failures();\n\t\t}\n\t}\n\n\tif (!(begin0 == end0)) {\n\t\tstd::cerr <<\n\t\t\t\"> ERROR: CHECK failed \\\"begin0 != end0\\\"\\n\"\n\t\t\t\"> \\t\" << file << '(' << line << ')' << \"\\n\"\n\t\t\t\"> \\t in function \\\"\" << fun << \"\\\"\\n\"\n\t\t\t\"> \\tEXPECTED: \" << test_impl::stream(end0) << \"\\n\"\n\t\t\t\"> \\tACTUAL: \" << test_impl::stream(begin0) << '\\n';\n\t\t++test_impl::test_failures();\n\t}\n\n\tif (!(begin1 == end1)) {\n\t\tstd::cerr <<\n\t\t\t\"> ERROR: CHECK failed \\\"begin1 != end1\\\"\\n\"\n\t\t\t\"> \\t\" << file << '(' << line << ')' << \"\\n\"\n\t\t\t\"> \\t in function \\\"\" << fun << \"\\\"\\n\"\n\t\t\t\"> \\tEXPECTED: \" << test_impl::stream(end1) << \"\\n\"\n\t\t\t\"> \\tACTUAL: \" << test_impl::stream(begin1) << '\\n';\n\t\t++test_impl::test_failures();\n\t}\n}\n\ntemplate<typename Val, typename Rng>\nconstexpr void check_equal_(const char* file, int line, const char* lhs, const char* rhs,\n\tconst char* fun, Rng && actual, std::initializer_list<Val>&& expected)\n{\n\tcheck_equal_(file, line, lhs, rhs, fun, actual, expected);\n}\n\n#define CHECK_EQUAL(first, ...) \\\n\tcheck_equal_(__FILE__, __LINE__, #first, #__VA_ARGS__, STL2_PRETTY_FUNCTION, first, __VA_ARGS__) \\\n\t/**/\n\n#endif\n"
  },
  {
    "path": "test/test_iterators.hpp",
    "content": "//===----------------------------------------------------------------------===//\n//\n//                     The LLVM Compiler Infrastructure\n//\n// This file is dual licensed under the MIT and the University of Illinois Open\n// Source Licenses. See LICENSE.TXT for details.\n//\n//===----------------------------------------------------------------------===//\n\n#ifndef RANGES_TEST_ITERATORS_HPP\n#define RANGES_TEST_ITERATORS_HPP\n\n#include <stl2/iterator.hpp>\n\ntemplate<class It, bool Sized = false>\nclass sentinel;\n\ntemplate<class It>\nclass output_iterator;\n\ntemplate<class It>\nclass input_iterator;\n\ntemplate<class It>\nclass forward_iterator;\n\ntemplate<class It>\nclass bidirectional_iterator;\n\ntemplate<class It>\nclass random_access_iterator;\n\n\ntemplate<class Iter, bool Sized>\nconstexpr Iter base(sentinel<Iter, Sized> i) { return i.base(); }\n\ntemplate<class Iter>\nconstexpr Iter base(output_iterator<Iter> i) { return i.base(); }\n\ntemplate<class Iter>\nconstexpr Iter base(input_iterator<Iter> i) { return i.base(); }\n\ntemplate<class Iter>\nconstexpr Iter base(forward_iterator<Iter> i) { return i.base(); }\n\ntemplate<class Iter>\nconstexpr Iter base(bidirectional_iterator<Iter> i) { return i.base(); }\n\ntemplate<class Iter>\nconstexpr Iter base(random_access_iterator<Iter> i) { return i.base(); }\n\ntemplate<class Iter>    // everything else\nconstexpr Iter base(Iter i) { return i; }\n\n\ntemplate<class It, bool Sized>\nclass sentinel\n{\n\tIt it_;\npublic:\n\tconstexpr sentinel() : it_() {}\n\tconstexpr explicit sentinel(It it) : it_(it) {}\n\tconstexpr It base() const { return it_; }\n\ttemplate<typename I>\n\tconstexpr friend bool operator==(const I& x, const sentinel& y)\n\t{\n\t\tusing ::base;\n\t\treturn base(x) == y.it_;\n\t}\n\ttemplate<typename I>\n\tconstexpr friend bool operator!=(const I& x, const sentinel& y)\n\t{\n\t\treturn !(x == y);\n\t}\n\ttemplate<typename I>\n\tconstexpr friend bool operator==(const sentinel& x, const I& y)\n\t{\n\t\tusing ::base;\n\t\treturn x.it_ == base(y);\n\t}\n\ttemplate<typename I>\n\tconstexpr friend bool operator!=(const sentinel& x, const I& y)\n\t{\n\t\treturn !(x == y);\n\t}\n};\n\n// For making sized iterator ranges:\ntemplate<template<typename> class I, typename It>\nconstexpr\nstd::ptrdiff_t operator-(sentinel<It, true> end, I<It> begin)\n{\n\treturn base(end) - base(begin);\n}\n\ntemplate<typename It, template<typename> class I>\nconstexpr\nstd::ptrdiff_t operator-(I<It> end, sentinel<It, true> begin)\n{\n\treturn -(begin - end);\n}\n\ntemplate<class It>\nclass output_iterator\n{\n\tIt it_;\n\n\ttemplate<class U> friend class output_iterator;\npublic:\n\tusing difference_type = __stl2::iter_difference_t<It>;\n\tusing pointer = It;\n\tusing reference = __stl2::iter_reference_t<It>;\n\n\tconstexpr It base() const {return it_;}\n\n\tconstexpr output_iterator () {}\n\tconstexpr explicit output_iterator(It it) : it_(it) {}\n\ttemplate<class U>\n\t  requires __stl2::convertible_to<U, It>\n\tconstexpr\n\toutput_iterator(const output_iterator<U>& u) :it_(u.it_) {}\n\n\tconstexpr reference operator*() const {return *it_;}\n\n\tconstexpr output_iterator& operator++() {++it_; return *this;}\n\tconstexpr decltype(auto) operator++(int)\n\t{return it_++;}\n};\n\ntemplate<class It>\nclass input_iterator\n{\n\tIt it_;\n\n\ttemplate<class U> friend class input_iterator;\npublic:\n\ttypedef __stl2::input_iterator_tag iterator_category;\n\ttypedef __stl2::iter_value_t<It>      value_type;\n\ttypedef __stl2::iter_difference_t<It> difference_type;\n\ttypedef It                       pointer;\n\ttypedef __stl2::iter_reference_t<It>  reference;\n\n\tconstexpr It base() const {return it_;}\n\n\tconstexpr input_iterator() : it_() {}\n\tconstexpr explicit input_iterator(It it) : it_(it) {}\n\ttemplate<class U>\n\t  requires __stl2::convertible_to<U, It>\n\tconstexpr input_iterator(const input_iterator<U>& u) :it_(u.it_) {}\n\n\tconstexpr reference operator*() const {return *it_;}\n\tconstexpr pointer operator->() const {return it_;}\n\n\tconstexpr input_iterator& operator++() {++it_; return *this;}\n\tconstexpr input_iterator operator++(int)\n\t\t{input_iterator tmp(*this); ++(*this); return tmp;}\n\n\tconstexpr\n\tfriend bool operator==(const input_iterator& x, const input_iterator& y)\n\t\t{return x.it_ == y.it_;}\n\tconstexpr\n\tfriend bool operator!=(const input_iterator& x, const input_iterator& y)\n\t\t{return !(x == y);}\n};\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator==(const input_iterator<T>& x, const input_iterator<U>& y)\n{\n\treturn x.base() == y.base();\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator!=(const input_iterator<T>& x, const input_iterator<U>& y)\n{\n\treturn !(x == y);\n}\n\ntemplate<class It>\nclass forward_iterator\n{\n\tIt it_;\n\n\ttemplate<class U> friend class forward_iterator;\npublic:\n\ttypedef __stl2::forward_iterator_tag iterator_category;\n\ttypedef __stl2::iter_value_t<It>        value_type;\n\ttypedef __stl2::iter_difference_t<It>   difference_type;\n\ttypedef It                         pointer;\n\ttypedef __stl2::iter_reference_t<It>    reference;\n\n\tconstexpr It base() const {return it_;}\n\n\tconstexpr forward_iterator() : it_() {}\n\tconstexpr explicit forward_iterator(It it) : it_(it) {}\n\ttemplate<class U>\n\t  requires __stl2::convertible_to<U, It>\n\tconstexpr forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}\n\n\tconstexpr reference operator*() const {return *it_;}\n\tconstexpr pointer operator->() const {return it_;}\n\n\tconstexpr forward_iterator& operator++() {++it_; return *this;}\n\tconstexpr forward_iterator operator++(int)\n\t{forward_iterator tmp(*this); ++(*this); return tmp;}\n\n\tconstexpr\n\tfriend bool operator==(const forward_iterator& x, const forward_iterator& y)\n\t{return x.it_ == y.it_;}\n\tconstexpr\n\tfriend bool operator!=(const forward_iterator& x, const forward_iterator& y)\n\t{return !(x == y);}\n};\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator==(const forward_iterator<T>& x, const forward_iterator<U>& y)\n{\n\treturn x.base() == y.base();\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)\n{\n\treturn !(x == y);\n}\n\ntemplate<class It>\nclass bidirectional_iterator\n{\n\tIt it_;\n\n\ttemplate<class U> friend class bidirectional_iterator;\npublic:\n\ttypedef __stl2::bidirectional_iterator_tag iterator_category;\n\ttypedef __stl2::iter_value_t<It>              value_type;\n\ttypedef __stl2::iter_difference_t<It>         difference_type;\n\ttypedef It                               pointer;\n\ttypedef __stl2::iter_reference_t<It>          reference;\n\n\tconstexpr It base() const {return it_;}\n\n\tconstexpr bidirectional_iterator() : it_() {}\n\tconstexpr explicit bidirectional_iterator(It it) : it_(it) {}\n\ttemplate<class U>\n\t  requires __stl2::convertible_to<U, It>\n\tconstexpr bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}\n\n\tconstexpr reference operator*() const {return *it_;}\n\tconstexpr pointer operator->() const {return it_;}\n\n\tconstexpr bidirectional_iterator& operator++() {++it_; return *this;}\n\tconstexpr bidirectional_iterator operator++(int)\n\t{bidirectional_iterator tmp(*this); ++(*this); return tmp;}\n\n\tconstexpr bidirectional_iterator& operator--() {--it_; return *this;}\n\tconstexpr bidirectional_iterator operator--(int)\n\t{bidirectional_iterator tmp(*this); --(*this); return tmp;}\n};\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)\n{\n\treturn x.base() == y.base();\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)\n{\n\treturn !(x == y);\n}\n\ntemplate<class It>\nclass random_access_iterator\n{\n\tIt it_;\n\n\ttemplate<class U> friend class random_access_iterator;\npublic:\n\ttypedef __stl2::random_access_iterator_tag iterator_category;\n\ttypedef __stl2::iter_value_t<It>              value_type;\n\ttypedef __stl2::iter_difference_t<It>         difference_type;\n\ttypedef It                               pointer;\n\ttypedef __stl2::iter_reference_t<It>          reference;\n\n\tconstexpr It base() const {return it_;}\n\n\tconstexpr random_access_iterator() : it_() {}\n\tconstexpr explicit random_access_iterator(It it) : it_(it) {}\n\ttemplate<class U>\n\t  requires __stl2::convertible_to<U, It>\n\tconstexpr random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}\n\n\tconstexpr reference operator*() const {return *it_;}\n\tconstexpr pointer operator->() const {return it_;}\n\n\tconstexpr random_access_iterator& operator++() {++it_; return *this;}\n\tconstexpr random_access_iterator operator++(int)\n\t{random_access_iterator tmp(*this); ++(*this); return tmp;}\n\n\tconstexpr random_access_iterator& operator--() {--it_; return *this;}\n\tconstexpr random_access_iterator operator--(int)\n\t{random_access_iterator tmp(*this); --(*this); return tmp;}\n\n\tconstexpr\n\trandom_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}\n\tconstexpr\n\trandom_access_iterator operator+(difference_type n) const\n\t{random_access_iterator tmp(*this); tmp += n; return tmp;}\n\tconstexpr\n\tfriend random_access_iterator operator+(difference_type n, random_access_iterator x)\n\t{x += n; return x;}\n\tconstexpr\n\trandom_access_iterator& operator-=(difference_type n) {return *this += -n;}\n\tconstexpr\n\trandom_access_iterator operator-(difference_type n) const\n\t{random_access_iterator tmp(*this); tmp -= n; return tmp;}\n\n\tconstexpr\n\treference operator[](difference_type n) const {return it_[n];}\n};\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)\n{\n\treturn x.base() == y.base();\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)\n{\n\treturn !(x == y);\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)\n{\n\treturn x.base() < y.base();\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)\n{\n\treturn !(y < x);\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)\n{\n\treturn y < x;\n}\n\ntemplate<class T, class U>\nconstexpr\nbool\noperator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)\n{\n\treturn !(x < y);\n}\n\ntemplate<class T, class U>\nconstexpr\n__stl2::iter_difference_t<T>\noperator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)\n{\n\treturn x.base() - y.base();\n}\n\ntemplate<typename It, bool Sized = false>\nstruct sentinel_type\n{\n\tusing type = It;\n};\n\ntemplate<typename T, bool Sized>\nstruct sentinel_type<T*, Sized>\n{\n\tusing type = sentinel<T*, Sized>;\n};\n\ntemplate<template<typename> class I, typename It, bool Sized>\nstruct sentinel_type<I<It>, Sized>\n{\n\tusing type = sentinel<It, Sized>;\n};\n\n#endif  // ITERATORS_H\n"
  },
  {
    "path": "test/test_utils.hpp",
    "content": "// Range v3 library\n//\n//  Copyright Eric Niebler 2014\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n\n#ifndef RANGES_TEST_UTILS_HPP\n#define RANGES_TEST_UTILS_HPP\n\n#include <stl2/iterator.hpp>\n\n#include <algorithm>\n#include <initializer_list>\n#include \"./test_iterators.hpp\"\n#include \"./simple_test.hpp\"\n\ntemplate<typename T>\nT & as_lvalue(T && t)\n{\n\treturn t;\n}\n\ntemplate<typename T>\nstruct checker\n{\nprivate:\n\tstd::function<void(std::function<void(T)>)> algo_;\npublic:\n\texplicit checker(std::function<void(std::function<void(T)>)> algo)\n\t: algo_(std::move(algo)) {}\n\n\tvoid check(std::function<void(T)> const & check) const {\n\t\talgo_(check);\n\t}\n};\n\ntemplate<bool B, typename T>\ntypename std::conditional<B, T, T const &>::type rvalue_if(T const &t) {\n\treturn t;\n}\n\ntemplate<typename Algo, bool RvalueOK = false>\nstruct test_range_algo_1\n{\nprivate:\n\tAlgo algo_;\npublic:\n\texplicit test_range_algo_1(Algo algo)\n\t  : algo_(algo)\n\t{}\n\ttemplate<typename I, typename... Rest>\n\tauto operator()(I begin, I end, Rest &&... rest) const ->\n\t\tchecker<decltype(algo_(begin, end, rest...))>\n\t{\n\t\tusing R = decltype(algo_(begin, end, rest...));\n\t\treturn checker<R>{[=,this](std::function<void(R)> const & check)\n\t\t{\n\t\t\tusing S = typename sentinel_type<I>::type;\n\t\t\tcheck(algo_(begin, end, rest...));\n\t\t\tcheck(algo_(begin, S{base(end)}, rest...));\n\t\t\tcheck(algo_(::rvalue_if<RvalueOK>(__stl2::subrange(begin, end)), rest...));\n\t\t\tcheck(algo_(::rvalue_if<RvalueOK>(__stl2::subrange(begin, S{base(end)})), rest...));\n\t\t}};\n\t}\n};\n\ntemplate<bool RvalueOK = false, typename Algo>\ntest_range_algo_1<Algo, RvalueOK> make_testable_1(Algo algo)\n{\n\treturn test_range_algo_1<Algo, RvalueOK>{algo};\n}\n\ntemplate<typename Algo, bool RvalueOK1 = false, bool RvalueOK2 = false>\nstruct test_range_algo_2\n{\nprivate:\n\tAlgo algo_;\npublic:\n\texplicit test_range_algo_2(Algo algo)\n\t  : algo_(algo)\n\t{}\n\ttemplate<typename I1, typename I2, typename... Rest>\n\tauto operator()(I1 begin1, I1 end1, I2 begin2, I2 end2, Rest &&... rest) const ->\n\t\tchecker<decltype(algo_(begin1, end1, begin2, end2, rest...))>\n\t{\n\t\tusing R = decltype(algo_(begin1, end1, begin2, end2, rest...));\n\t\treturn checker<R>{[=,this](std::function<void(R)> const & check)\n\t\t{\n\t\t\tusing S1 = typename sentinel_type<I1>::type;\n\t\t\tusing S2 = typename sentinel_type<I2>::type;\n\t\t\tcheck(algo_(begin1, end1, begin2, end2, rest...));\n\t\t\tcheck(algo_(begin1, S1{base(end1)}, begin2, S2{base(end2)}, rest...));\n\t\t\tcheck(algo_(::rvalue_if<RvalueOK1>(__stl2::subrange(begin1, end1)),\n\t\t\t\t\t\t::rvalue_if<RvalueOK2>(__stl2::subrange(begin2, end2)),\n\t\t\t\t\t\trest...));\n\t\t\tcheck(algo_(::rvalue_if<RvalueOK1>(__stl2::subrange(begin1, S1{base(end1)})),\n\t\t\t\t\t\t::rvalue_if<RvalueOK2>(__stl2::subrange(begin2, S2{base(end2)})),\n\t\t\t\t\t\trest...));\n\t\t}};\n\t}\n};\n\ntemplate<bool RvalueOK1 = false, bool RvalueOK2 = false, typename Algo>\ntest_range_algo_2<Algo, RvalueOK1, RvalueOK2> make_testable_2(Algo algo)\n{\n\treturn test_range_algo_2<Algo, RvalueOK1, RvalueOK2>{algo};\n}\n\n#endif\n"
  },
  {
    "path": "test/view/CMakeLists.txt",
    "content": "# cmcstl2 - A concept-enabled C++ standard library\n#\n#  Copyright Casey Carter 2015 - 2018\n#\n#  Use, modification and distribution is subject to the\n#  Boost Software License, Version 1.0. (See accompanying\n#  file LICENSE_1_0.txt or copy at\n#  http://www.boost.org/LICENSE_1_0.txt)\n#\n# Project home: https://github.com/caseycarter/cmcstl2\n#\nadd_stl2_test(span span span.cpp)\nadd_stl2_test(view.common view.common common_view.cpp)\nadd_stl2_test(view.counted view.counted counted_view.cpp)\nadd_stl2_test(view.drop view.drop drop_view.cpp)\nadd_stl2_test(view.drop_while view.drop_while drop_while_view.cpp)\nadd_stl2_test(view.empty view.empty empty_view.cpp)\nadd_stl2_test(view.filter view.filter filter_view.cpp)\nadd_stl2_test(view.generate view.generate generate_view.cpp)\nadd_stl2_test(view.indirect view.indirect indirect_view.cpp)\nadd_stl2_test(view.istream view.istream istream_view.cpp)\nadd_stl2_test(view.join view.join join_view.cpp)\nadd_stl2_test(view.move view.move move_view.cpp)\nadd_stl2_test(view.ref view.ref ref_view.cpp)\nadd_stl2_test(view.repeat view.repeat repeat_view.cpp)\nadd_stl2_test(view.repeat_n view.repeat_n repeat_n_view.cpp)\nadd_stl2_test(view.reverse view.reverse reverse_view.cpp)\nadd_stl2_test(view.single view.single single_view.cpp)\nadd_stl2_test(view.split view.split split_view.cpp)\nadd_stl2_test(view.subrange view.subrange subrange.cpp)\nadd_stl2_test(view.take view.take take_view.cpp)\nadd_stl2_test(view.take_exactly view.take_exactly take_exactly_view.cpp)\nadd_stl2_test(view.take_while view.take_while take_while_view.cpp)\nadd_stl2_test(view.transform view.transform transform_view.cpp)\n"
  },
  {
    "path": "test/view/common_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/common.hpp>\n#include <stl2/view/counted.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\nnamespace views = ranges::views;\n\nint main() {\n\tusing ranges::same_as;\n\tusing ranges::view, ranges::sized_range, ranges::common_range;\n\tusing ranges::forward_range, ranges::bidirectional_range, ranges::random_access_range;\n\t{\n\t\tint rg[] = {0,1,2,3,4,5,6,7,8,9};\n\t\tauto x = rg | views::common;\n\t\tCHECK_EQUAL(x, {0,1,2,3,4,5,6,7,8,9});\n\t\tstatic_assert(view<decltype(x)>);\n\t\tstatic_assert(sized_range<decltype(x)>);\n\t\tstatic_assert(common_range<decltype(x)>);\n\t\tstatic_assert(random_access_range<decltype(x)>);\n\t}\n\t{\n\t\tint rg[] = {0,1,2,3,4,5,6,7,8,9};\n\t\tauto x = views::counted(bidirectional_iterator(rg), 5) | views::common;\n\t\tCHECK_EQUAL(x, {0,1,2,3,4});\n\t\tstatic_assert(view<decltype(x)>);\n\t\tstatic_assert(sized_range<decltype(x)>);\n\t\tstatic_assert(common_range<decltype(x)>);\n\t\tstatic_assert(forward_range<decltype(x)>);\n\t\tstatic_assert(!bidirectional_range<decltype(x)>);\n\t\tstatic_assert(same_as<decltype(x), decltype(views::common(x))>);\n\t}\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/counted_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/counted.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\nnamespace views = ranges::views;\n\nint main() {\n\tusing ranges::view, ranges::sized_range, ranges::common_range;\n\tusing ranges::forward_range, ranges::bidirectional_range, ranges::random_access_range;\n\t{\n\t\tint rg[] = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};\n\t\tauto x = views::counted(rg, 10);\n\t\tCHECK_EQUAL(x, {0,1,2,3,4,5,6,7,8,9});\n\t\tstatic_assert(view<decltype(x)>);\n\t\tstatic_assert(sized_range<decltype(x)>);\n\t\tstatic_assert(common_range<decltype(x)>);\n\t\tstatic_assert(random_access_range<decltype(x)>);\n\t}\n\t{\n\t\tint rg[] = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};\n\t\tauto x = views::counted(forward_iterator(rg), 10);\n\t\tCHECK_EQUAL(x, {0,1,2,3,4,5,6,7,8,9});\n\t\tstatic_assert(view<decltype(x)>);\n\t\tstatic_assert(sized_range<decltype(x)>);\n\t\tstatic_assert(!common_range<decltype(x)>);\n\t\tstatic_assert(forward_range<decltype(x)>);\n\t\tstatic_assert(!bidirectional_range<decltype(x)>);\n\t}\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/drop_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/drop.hpp>\n\n#include <stl2/view/iota.hpp>\n#include <stl2/view/join.hpp>\n#include <stl2/view/reverse.hpp>\n#include <stl2/view/subrange.hpp>\n#include <stl2/view/take.hpp>\n#include <list>\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\nnamespace views = ranges::views;\n\nint main()\n{\n\t{\n\t\tint rgi[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\n\t\tauto rng0 = rgi | views::drop(6);\n\t\tstatic_assert(ranges::view<decltype(rng0)>);\n\t\tstatic_assert(ranges::sized_range<decltype(rng0)>);\n\t\tstatic_assert(ranges::random_access_iterator<decltype(ranges::begin(rng0))>);\n\t\tCHECK_EQUAL(rng0, {6, 7, 8, 9, 10});\n\t\tCHECK(ranges::size(rng0) == 5u);\n\n\t\tauto rng1 = rng0 | views::reverse;\n\t\tstatic_assert(ranges::view<decltype(rng1)>);\n\t\tstatic_assert(ranges::sized_range<decltype(rng1)>);\n\t\tstatic_assert(ranges::random_access_iterator<decltype(ranges::begin(rng1))>);\n\t\tCHECK_EQUAL(rng1, {10, 9, 8, 7, 6});\n\t}\n\n\t{\n\t\tstd::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\t\tauto rng = v | views::drop(6) | views::reverse;\n\t\tstatic_assert(ranges::view<decltype(rng)>);\n\t\tstatic_assert(ranges::sized_range<decltype(rng)>);\n\t\tstatic_assert(ranges::random_access_iterator<decltype(ranges::begin(rng))>);\n\t\tCHECK_EQUAL(rng, {10, 9, 8, 7, 6});\n\t}\n\n\t{\n\t\tstd::list<int> l{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\t\tauto rng = l | views::drop(6);\n\t\tstatic_assert(ranges::view<decltype(rng)>);\n\t\tstatic_assert(ranges::sized_range<decltype(rng)>);\n\t\tstatic_assert(ranges::bidirectional_iterator<decltype(ranges::begin(rng))>);\n\t\tCHECK_EQUAL(rng, {6, 7, 8, 9, 10});\n\t}\n\n\t{\n\t\tauto rng = views::iota(10) | views::drop(10);\n\t\tstatic_assert(ranges::view<decltype(rng)>);\n\t\tstatic_assert(!ranges::sized_range<decltype(rng)>);\n\t\t// static_assert(ranges::is_infinite<decltype(rng4)>::value, \"\");\n\t\tauto b = ranges::begin(rng);\n\t\tCHECK(*b == 20);\n\t\tCHECK(*(b+1) == 21);\n\t}\n\n#if 0 // Test DISABLED while views::take(n) | views::reverse isn't possible.\n\t{\n\t\tauto rng = views::iota(10) | views::drop(10) | views::take(10) | views::reverse;\n\t\tstatic_assert(ranges::view<decltype(rng)>);\n\t\tstatic_assert(ranges::sized_range<decltype(rng)>);\n\t\tstatic_assert(!ranges::is_infinite<decltype(rng5)>::value, \"\");\n\t\tCHECK_EQUAL(rng, {29, 28, 27, 26, 25, 24, 23, 22, 21, 20});\n\t\tCHECK(ranges::size(rng) == 10u);\n\t}\n#endif\n\t{\n\t\t// consolation for the above not being possible\n\t\tauto rng = views::iota(10) | views::drop(10) | views::take(10);\n\t\tstatic_assert(ranges::view<decltype(rng)>);\n\t\tstatic_assert(!ranges::sized_range<decltype(rng)>);\n\t\t// static_assert(!ranges::is_infinite<decltype(rng5)>::value, \"\");\n\t\tCHECK_EQUAL(rng, {20, 21, 22, 23, 24, 25, 26, 27, 28, 29});\n\t}\n\n\t{\n\t\tint some_ints[] = {0,1,2};\n\t\tauto rng = ranges::subrange(some_ints + 0, some_ints + 1);\n\t\tauto rng2 = views::drop(rng, 2);\n\t\tCHECK(ranges::begin(rng2) == some_ints + 1);\n\t\tCHECK(ranges::size(rng2) == 0u);\n\t}\n\n#if 0 // Test DISABLED pending view implementations.\n\t{\n\t\t// Regression test for https://github.com/ericniebler/range-v3/issues/413\n\t\tauto skips = [](std::vector<int> xs) -> std::vector<std::vector<int>> {\n\t\t\treturn views::iota(0, (int)xs.size())\n\t\t\t\t  | views::transform([&](int n) {\n\t\t\t\t\t\t return xs | views::chunk(n + 1)\n\t\t\t\t\t\t\t\t\t  | views::transform(views::drop(n))\n\t\t\t\t\t\t\t\t\t  | views::join;\n\t\t\t\t\t });\n\t\t};\n\t\tauto skipped = skips({1,2,3,4,5,6,7,8});\n\t\tCHECK(skipped.size() == 8u);\n\t\tif(skipped.size() >= 8u)\n\t\t{\n\t\t\tCHECK_EQUAL(skipped[0], {1,2,3,4,5,6,7,8});\n\t\t\tCHECK_EQUAL(skipped[1], {2,4,6,8});\n\t\t\tCHECK_EQUAL(skipped[2], {3,6});\n\t\t\tCHECK_EQUAL(skipped[3], {4,8});\n\t\t\tCHECK_EQUAL(skipped[4], {5});\n\t\t\tCHECK_EQUAL(skipped[5], {6});\n\t\t\tCHECK_EQUAL(skipped[6], {7});\n\t\t\tCHECK_EQUAL(skipped[7], {8});\n\t\t}\n\t}\n\n\t{\n\t\tstatic int const some_ints[] = {0,1,2,3};\n\t\tauto rng = debug_input_view<int const>{some_ints} | views::drop(2);\n\t\tusing R = decltype(rng);\n\t\tstatic_assert(InputView<R>());\n\t\tstatic_assert(!forward_range<R>());\n\t\tstatic_assert(same_as<int const&, ranges::iter_reference_t<R>>());\n\t\tCHECK_EQUAL(rng, {2,3});\n\t}\n\n\t{\n\t\t// regression test for ericniebler/range-v3#728\n\t\tauto rng1 = views::iota(1) | views::chunk(6) | views::take(3);\n\t\tint i = 2;\n\t\tfor (auto o1 : rng1) {\n\t\t\tauto rng2 = o1 | views::drop(1);\n\t\t\tCHECK_EQUAL(rng2, {i, i+1, i+2, i+3, i+4});\n\t\t\ti += 6;\n\t\t}\n\t}\n#endif\n\n\t{\n\t\t// regression test for ericniebler/range-v3#813\n\t\tstatic int const some_ints[] = {0,1,2,3};\n\t\tauto rng = some_ints | views::drop(10);\n\t\tCHECK(ranges::empty(rng));\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/drop_while_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/drop_while.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/take.hpp>\n#include <list>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\nnamespace views = ranges::views;\n\nint main()\n{\n\t{\n\t\tauto rng0 = views::iota(10) | views::drop_while([](int i) { return i < 25; });\n\t\t//  static_assert(range_cardinality<decltype(rng0)>::value == unknown);\n\t\tstatic_assert(ranges::random_access_range<decltype(rng0)>);\n\t\tstatic_assert(!ranges::common_range<decltype(rng0)>);\n\t\tauto b = rng0.begin();\n\t\tCHECK(*b == 25);\n\t\tCHECK(*(b+1) == 26);\n\t\tCHECK_EQUAL(rng0 | views::take(10), {25, 26, 27, 28, 29, 30, 31, 32, 33, 34});\n\t}\n\n\tstd::list<int> vi{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};\n\tauto rng1 = vi | views::drop_while([](int i) { return i != 50; });\n\t//  static_assert(range_cardinality<decltype(rng1)>::value == ranges::finite);\n\tstatic_assert(ranges::bidirectional_range<decltype(rng1)>);\n\tstatic_assert(ranges::common_range<decltype(rng1)>);\n\tCHECK(rng1.begin() == rng1.end());\n\n\n\t// Check with a mutable predicate\n\t{\n\t\tauto rng0 = views::iota(10) | views::drop_while([b = true](int i) mutable { b = !b; return i < 25; });\n\t\t//  static_assert(range_cardinality<decltype(rng0)>::value == unknown);\n\t\tstatic_assert(ranges::random_access_range<decltype(rng0)>);\n\t\tstatic_assert(!ranges::common_range<decltype(rng0)>);\n\t\tauto b = rng0.begin();\n\t\tCHECK(*b == 25);\n\t\tCHECK(*(b+1) == 26);\n\t\tCHECK_EQUAL(rng0 | views::take(10), {25, 26, 27, 28, 29, 30, 31, 32, 33, 34});\n\t}\n\n\t//  {\n\t//      // Check with move-only subview\n\t//      auto rng = debug_input_view<const int>{rgi} | views::drop_while([](int i){ return i < 4; });\n\t//      using R = decltype(rng);\n\t//      static_assert(InputView<R>());\n\t//      static_assert(!forward_range<R>());\n\t//      static_assert(!BoundedRange<R>());\n\t//      static_assert(same_as<int const&, range_reference_t<R>>());\n\t//      CHECK_EQUAL(rng, {4,5,6,7,8,9});\n\t//  }\n\n    return ::test_result();\n}\n"
  },
  {
    "path": "test/view/empty_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/empty.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main() {\n\tusing namespace ranges;\n\n\t{\n\t\tauto rng = views::empty<double>;\n\n\t\tCHECK(ranges::begin(rng) == nullptr);\n\t\tCHECK(rng.begin() == nullptr);\n\t\tCHECK(ranges::end(rng) == nullptr);\n\t\tCHECK(rng.end() == nullptr);\n\t\tCHECK(ranges::data(rng) == nullptr);\n\t\tCHECK(rng.data() == nullptr);\n\t\tCHECK(ranges::size(rng) == 0);\n\t\tCHECK(rng.size() == 0);\n\t}\n\n\t{\n\t\tCHECK(ranges::begin(views::empty<int>) == nullptr);\n\t\tCHECK(ranges::end(views::empty<int>) == nullptr);\n\t\tCHECK(ranges::data(views::empty<int>) == nullptr);\n\t\tCHECK(ranges::size(views::empty<int>) == 0);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/filter_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/filter.hpp>\n\n#include <stl2/detail/algorithm/count.hpp>\n#include <stl2/detail/algorithm/transform.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <stl2/view/all.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/reverse.hpp>\n#include <stl2/view/take_exactly.hpp>\n\n#include <list>\n#include <memory>\n#include <vector>\n\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tstruct is_odd {\n\t\tbool operator()(int i) const {\n\t\t\treturn (i % 2) == 1;\n\t\t}\n\t};\n\n\tstruct is_even {\n\t\tbool operator()(int i) const {\n\t\t\treturn (i % 2) == 0;\n\t\t}\n\t};\n}\n\nint main() {\n\tusing namespace ranges;\n\n\tint rgi[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\tstatic_assert(size(views::all(rgi))==10);\n\n\tauto rng = rgi | views::filter(is_odd());\n\tstatic_assert(same_as<int &, decltype(*begin(rgi))>);\n\tstatic_assert(same_as<int &, decltype(*begin(rng))>);\n\tstatic_assert(view<decltype(rng)>);\n\tstatic_assert(input_range<decltype(rng)>);\n\tstatic_assert(common_range<decltype(rng)>);\n\tstatic_assert(!sized_range<decltype(rng)>);\n\tstatic_assert(bidirectional_range<decltype(rng)>);\n\tstatic_assert(!random_access_range<decltype(rng)>);\n\tCHECK_EQUAL(rng, {1,3,5,7,9});\n\n\tCHECK_EQUAL(rng | views::reverse, {9,7,5,3,1});\n\tauto tmp = rng | views::reverse;\n\tCHECK(&*begin(tmp) == &rgi[8]);\n\n\t// auto rng2 = views::counted(rgi, 10) | views::remove_if(not_fn(is_odd()));\n\t// static_assert(same_as<int &, decltype(*begin(rng2))>);\n\t// static_assert(BidirectionalView<__f<decltype(rng2)>>);\n\t// static_assert(!RandomAccessView<__f<decltype(rng2)>>);\n\t// static_assert(CommonView<__f<decltype(rng2)>>);\n\t// static_assert(!SizedView<__f<decltype(rng2)>>);\n\t// CHECK_EQUAL(rng2, {1,3,5,7,9});\n\t// CHECK(&*begin(rng2) == &rgi[0]);\n\n\t// auto rng3 = views::counted(bidirectional_iterator<int*>{rgi}, 10) | views::remove_if(is_even());\n\t// static_assert(same_as<int &, decltype(*begin(rng3))>);\n\t// static_assert(BidirectionalView<__f<decltype(rng3)>>);\n\t// static_assert(!RandomAccessView<__f<decltype(rng3)>>);\n\t// static_assert(!CommonView<__f<decltype(rng3)>>);\n\t// static_assert(!SizedView<__f<decltype(rng3)>>);\n\t// CHECK_EQUAL(rng3, {1,3,5,7,9});\n\t// CHECK(&*begin(rng3) == &rgi[0]);\n\t// CHECK(&*prev(next(begin(rng3))) == &rgi[0]);\n\n\t// Test remove_if with a mutable lambda\n\tbool flag = false;\n\tauto f = [flag](int) mutable { return flag = !flag;};\n\tdetail::semiregular_box<decltype(f)> b{f};\n\tauto b2 = b;\n\tb = b2;\n\tauto mutable_rng = views::filter(rgi, [flag](int) mutable { return flag = !flag;});\n\tCHECK_EQUAL(mutable_rng, {1,3,5,7,9});\n\tstatic_assert(range<decltype(mutable_rng)>);\n\tstatic_assert(copyable<decltype(mutable_rng)>);\n\tstatic_assert(!view<decltype(mutable_rng) const>);\n\n\t// {\n\t//\t const std::array<int, 3> a{{0, 1, 2}};\n\t//\t const std::vector<int> b{3, 4, 5, 6};\n\n\t//\t auto r = views::concat(a, b);\n\t//\t auto f = [](int i) { return i != 1 && i != 5; };\n\t//\t auto r2 = r | views::remove_if(f);\n\t//\t CHECK_EQUAL(r2, {1,5});\n\t// }\n\n\t// {\n\t//\t auto rng = debug_input_view<int const>{rgi} | views::remove_if(is_even{});\n\t//\t CHECK_EQUAL(rng, {1,3,5,7,9});\n\t// }\n\n\t{\n\t\t// Test operator-> with pointer\n\t\tstd::pair<int, int> pairs[] = {{1, 99}, {2, 1}, {3, 99}, {4, 3}};\n\t\tauto rng = views::filter(pairs, [](auto&& p) { return p.first % 2 == 0; });\n\t\tauto i = ranges::begin(rng);\n\t\tauto const e = ranges::end(rng);\n\t\tint sum = 0;\n\t\tfor (; i != e; ++i) {\n\t\t\tsum += i->second;\n\t\t}\n\t\tCHECK(sum == 4);\n\t}\n\n\t{\n\t\t// Test operator-> with non-pointer\n\t\tstd::list<std::pair<int, int>> pairs = {{1, 99}, {2, 1}, {3, 99}, {4, 3}};\n\t\tauto rng = views::filter(pairs, [](auto&& p) { return p.first % 2 == 0; });\n\t\tauto i = ranges::begin(rng);\n\t\tauto const e = ranges::end(rng);\n\t\tint sum = 0;\n\t\tfor (; i != e; ++i) {\n\t\t\tsum += i->second;\n\t\t}\n\t\tCHECK(sum == 4);\n\t}\n\n\t{\n\t\tauto yes = [](int) { return true; };\n\t\t(void) (views::iota(0) | views::filter(yes));\n\t}\n\n\t{\n\t\tauto yes = [](int) { return true; };\n\t\tauto const rng = views::iota(0) | views::filter(yes);\n\t\tviews::all(rng);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/generate_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/generate.hpp>\n\n#include \"../move_only_string.hpp\"\n#include \"../simple_test.hpp\"\n#include <stl2/view/take_exactly.hpp>\n\nnamespace ranges = __stl2;\n\nnamespace views {\n\tusing namespace ranges::views;\n\tusing namespace ext;\n} // namespace views\n\nint main()\n{\n\t// Test for constant generator functions\n\t{\n\t\tint i = 0, j = 1;\n\t\tauto fib = views::generate([&]{ int tmp = i; i += j; std::swap(i, j); return tmp; });\n\t\tstatic_assert(ranges::input_range<decltype(fib)>);\n\t\tstatic_assert(ranges::view<decltype(fib)>);\n\t\tCHECK_EQUAL(fib | views::take_exactly(10), {0,1,1,2,3,5,8,13,21,34});\n\t}\n\n\t// Test for mutable-only generator functions\n\t{\n\t\tint i = 0, j = 1;\n\t\tauto fib = views::generate([=]()mutable->int{int tmp = i; i += j; std::swap(i, j); return tmp;});\n\t\tstatic_assert(ranges::input_range<decltype(fib)>);\n\t\tstatic_assert(ranges::view<decltype(fib)>);\n\t\tCHECK_EQUAL(fib | views::take_exactly(10), {0,1,1,2,3,5,8,13,21,34});\n\t\t// The generator cannot be called when it's const-qualified, so \"fib const\"\n\t\t// does not model view.\n\t\tstatic_assert(!ranges::view<decltype(fib) const>);\n\t}\n\n#if 0 // unlike range-v3, cmcstl2 doesn't support move-only input views\n\t// Test for move-only generator functions\n\t{\n\t\tstruct MoveOnlyFunction {\n\t\t\tmove_only_string str_;\n\t\t\tint i_;\n\n\t\t\tchar operator()()\n\t\t\t{ return str_.sz_[i_++]; }\n\t\t};\n\t\tauto r = views::generate(MoveOnlyFunction{\"Hello, world!\", 0}) | views::take_exactly(5);\n\t\tstatic_assert(ranges::input_range<decltype(r)>);\n\t\tstatic_assert(ranges::view<decltype(r)>);\n\t\tCHECK_EQUAL(r, {'H', 'e', 'l', 'l', 'o'});\n\t}\n#endif // 0\n\n\t// Test for generator functions that return move-only types\n\t// https://github.com/ericniebler/range-v3/issues/905\n\t{\n\t\tusing cmcstl2_test::move_only_string;\n\n\t\tchar str[] = \"gi\";\n\t\tauto r = views::generate([&]{str[0]++; return move_only_string{str};}) | views::take_exactly(2);\n\t\tauto i = r.begin();\n\t\tCHECK(bool(*i == move_only_string{\"hi\"}));\n\t\tCHECK(bool(*i == move_only_string{\"hi\"}));\n\t\tCHECK(bool(*r.begin() == move_only_string{\"hi\"}));\n\t\tCHECK(bool(*r.begin() == move_only_string{\"hi\"}));\n\t\tstatic_assert(ranges::input_range<decltype(r)>);\n\t\tstatic_assert(ranges::view<decltype(r)>);\n\t\tCHECK_EQUAL(r, {move_only_string{\"hi\"}, move_only_string{\"ii\"}});\n\t\tstatic_assert(std::is_same<ranges::range_reference_t<decltype(r)>, move_only_string&&>::value, \"\");\n\t}\n\n\t// Test for generator functions that return internal references\n\t// https://github.com/ericniebler/range-v3/issues/807\n\t{\n\t\tint i = 42;\n\t\tauto r = views::generate([i]{return &i;});\n\t\tauto rng2 = std::move(r);\n\t\tauto it = rng2.begin();\n\t\tauto p = *it;\n\t\tauto p2 = *++it;\n\t\tCHECK(p == p2);\n\t}\n\n\t// Test that we only call the function once for each dereferenceable position\n\t// https://github.com/ericniebler/range-v3/issues/819\n\t{\n\t\tint i = 0;\n\t\tauto r = views::generate([&i]{return ++i;});\n\t\tauto rng2 = std::move(r);\n\t\tauto it = rng2.begin();\n\t\tCHECK(i == 0);\n\t\tCHECK(*it == 1);\n\t\tCHECK(i == 1);\n\t\t++it;\n\t\tCHECK(i == 1);\n\t\tCHECK(*it == 2);\n\t\tCHECK(i == 2);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/indirect_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/indirect.hpp>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n\nnamespace views = __stl2::views::ext;\n\nint main()\n{\n\tstd::vector<std::shared_ptr<int>> vp;\n\tfor(int i = 0; i < 10; ++i)\n\t\tvp.push_back(std::make_shared<int>(i));\n\tauto && rng = vp | views::indirect;\n\tCHECK(&*begin(rng) == vp[0].get());\n\tCHECK_EQUAL(rng, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9});\n\n#if 0\n\t{\n\t\tint const some_ints[] = {0,1,2,3};\n\t\tint const *some_int_pointers[] = {\n\t\t\tsome_ints + 0, some_ints + 1, some_ints + 2, some_ints + 3\n\t\t};\n\t\tauto make_range = [&]{\n\t\t\treturn debug_input_view<int const *>{some_int_pointers} | views::indirect;\n\t\t};\n\t\tauto rng = make_range();\n\t\tCHECK_EQUAL(rng, some_ints);\n\t\trng = make_range();\n\t\tCHECK(&*begin(rng) == some_ints + 0);\n\t}\n#endif\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/istream_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler\n//  Copyright Casey Carter\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/istream.hpp>\n\n#include <sstream>\n#include <string_view>\n\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n\nstruct moveonly {\n\tchar c;\n\n\tmoveonly() = default;\n\tmoveonly(moveonly&&) = default;\n\tmoveonly& operator=(moveonly&&) & = default;\n\n\toperator char() const { return c; }\n\n\tfriend std::istream& operator>>(std::istream& is, moveonly& m) {\n\t\tis.get(m.c);\n\t\treturn is;\n\t}\n};\n\nnamespace ranges = __stl2;\n\nint main() {\n\tconstexpr std::string_view test = \"abcd3210\";\n\tstd::istringstream ss{test.data()};\n\tCHECK_EQUAL(ranges::views::istream<moveonly>(ss), test);\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/join_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/join.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/transform.hpp>\n#include <stl2/view/filter.hpp>\n#include <stl2/detail/algorithm/count.hpp>\n#include <stl2/detail/algorithm/transform.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <memory>\n#include <vector>\n#include <string>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main()\n{\n\tusing namespace ranges;\n\n\t{\n\t\tstd::vector<std::string> vs{\"this\",\"is\",\"his\",\"face\"};\n\t\tjoin_view jv{vs};\n\t\tCHECK_EQUAL(jv, {'t','h','i','s','i','s','h','i','s','f','a','c','e'});\n\t\tstatic_assert(bidirectional_range<decltype(jv)>);\n\t\tstatic_assert(bidirectional_range<const decltype(jv)>);\n\t\tstatic_assert(common_range<decltype(jv)>);\n\t\tstatic_assert(common_range<const decltype(jv)>);\n\t}\n\n\t{\n\t\tauto rng = views::iota(0,4)\n\t\t\t| views::transform([](int i) {return views::iota(0,i);})\n\t\t\t| views::join;\n\t\tCHECK_EQUAL(rng, {0,0,1,0,1,2});\n\t\tstatic_assert(input_range<decltype(rng)>);\n\t\tstatic_assert(!range<const decltype(rng)>);\n\t\tstatic_assert(!forward_range<decltype(rng)>);\n\t\tstatic_assert(!common_range<decltype(rng)>);\n\t}\n\n\t{\n\t\tauto rng = views::iota(0,4)\n\t\t\t| views::transform([](int i) {return views::iota(0,i);})\n\t\t\t| views::filter([](auto){ return true; })\n\t\t\t| views::join;\n\t\tCHECK_EQUAL(rng, {0,0,1,0,1,2});\n\t\tstatic_assert(input_range<decltype(rng)>);\n\t\tstatic_assert(!range<const decltype(rng)>);\n\t\tstatic_assert(!forward_range<decltype(rng)>);\n\t\tstatic_assert(!common_range<decltype(rng)>);\n\t}\n\n\t{\n\t\t// https://github.com/ericniebler/stl2/issues/604\n\t\tauto rng0 = views::iota(0, 4)\n\t\t\t| views::transform([](int i) { return views::iota(0, i); });\n\t\tauto rng1 = ref_view{rng0};\n\t\tstatic_assert(random_access_range<decltype(rng1)>);\n\t\tstatic_assert(range<const decltype(rng1)>);\n\t\tstatic_assert(common_range<decltype(rng1)>);\n\t\tstatic_assert(random_access_range<range_reference_t<decltype(rng1)>>);\n\t\tstatic_assert(ext::simple_view<decltype(rng1)>);\n\t\tstatic_assert(!std::is_reference_v<range_reference_t<decltype(rng1)>>);\n\t\tauto rng2 = rng1 | views::join;\n\t\tCHECK_EQUAL(rng2, {0,0,1,0,1,2});\n\t\tstatic_assert(input_range<decltype(rng2)>);\n\t\tstatic_assert(!range<const decltype(rng2)>);\n\t\tstatic_assert(!forward_range<decltype(rng2)>);\n\t\tstatic_assert(!common_range<decltype(rng2)>);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/move_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/move.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/ref.hpp>\n#include <stl2/view/take_exactly.hpp>\n#include <stl2/detail/algorithm/count.hpp>\n#include <stl2/detail/algorithm/transform.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <memory>\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\ttemplate<ranges::integral I>\n\tauto make_interval(I from, I to) {\n\t\treturn ranges::views::iota(from, to);\n\t}\n\n\ttemplate<ranges::range R>\n\tvoid test(R&& base) {\n\t\tauto rng = base | ranges::views::move;\n\t\tCHECK(static_cast<std::size_t>(ranges::size(rng)) == ranges::size(base));\n\t\tCHECK(!ranges::empty(rng));\n\t\tint count = 0;\n\t\tfor (auto i : rng) {\n\t\t\tCHECK(count++ == *i);\n\t\t}\n\t\tCHECK(ranges::count(base, std::unique_ptr<int>{}) == ranges::distance(base));\n\t}\n}\n\nint main() {\n\tauto rng = make_interval(0, 4);\n\tauto as_unique_ptr = [](auto&& i) {\n\t\tusing I = decltype(i);\n\t\treturn std::make_unique<std::decay_t<I>>(std::forward<I>(i));\n\t};\n\t{\n\t\tstd::unique_ptr<int> some_ints[] = {\n\t\t\tstd::make_unique<int>(0), std::make_unique<int>(1),\n\t\t\tstd::make_unique<int>(2), std::make_unique<int>(3),\n\t\t};\n\t\tranges::transform(rng, ranges::begin(some_ints), as_unique_ptr);\n\t\ttest(some_ints);\n\t}\n\n\t{\n\t\tstd::vector<std::unique_ptr<int>> some_ints;\n\t\tranges::transform(rng, ranges::back_inserter(some_ints), as_unique_ptr);\n\t\ttest(some_ints);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/ref_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Christopher Di Bella\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/ref.hpp>\n#include <vector>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n#include <stl2/detail/algorithm/transform.hpp>\n\nnamespace ranges = __stl2;\n\nstatic_assert(ranges::constructible_from<ranges::ref_view<const int[42]>, const int(&)[42]>);\nstatic_assert(ranges::constructible_from<ranges::ref_view<const int[42]>, int(&)[42]>);\nstatic_assert(!ranges::constructible_from<ranges::ref_view<const int[42]>, int(&&)[42]>);\nstatic_assert(!ranges::constructible_from<ranges::ref_view<const int[42]>, const int(&&)[42]>);\n\nint main() {\n\t{\n\t\tauto rng = std::vector<int>(10, 0);\n\t\tauto iota = 0;\n\t\tfor (auto&& i : ranges::ref_view{rng}) {\n\t\t\ti += iota;\n\t\t\t++iota;\n\t\t}\n\t\tCHECK_EQUAL(rng, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9});\n\t}\n\t{\n\t\tint some_ints[42]{};\n\t\tauto first = ranges::begin(ranges::ref_view{some_ints});\n\t\tauto last = ranges::end(ranges::ref_view{some_ints});\n\t\tauto count = ranges::size(ranges::ref_view{some_ints});\n\t\tCHECK((first + count) == last);\n\t\tCHECK(first == ranges::data(ranges::ref_view{some_ints}));\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/repeat_n_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/repeat_n.hpp>\n#include <stl2/iterator.hpp>\n#include <stl2/algorithm.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main() {\n\tstatic constexpr int N = 13;\n\tstatic constexpr int value = 42;\n\tauto v = ranges::views::ext::repeat_n(value, N);\n\tusing V = decltype(v);\n\tstatic_assert(ranges::view<V>);\n\tstatic_assert(ranges::sized_range<V>);\n\n\tCHECK(ranges::size(v) == N);\n\tCHECK(ranges::count(v, value) == N);\n\tCHECK(ranges::equal(v, std::vector<int>(N, value)));\n\n\tstatic_assert(sizeof(v) == 2 * sizeof(std::ptrdiff_t));\n\n\t{\n\t\tstruct empty {\n\t\t\tbool operator==(empty const&) const noexcept { return true; }\n\t\t\tbool operator!=(empty const&) const noexcept { return false; }\n\t\t};\n\t\tauto e = empty{};\n\t\tauto v2 = ranges::views::ext::repeat_n(e, 3);\n\t\tCHECK_EQUAL(v2, {e, e, e});\n\n\t\tauto v3 = ranges::views::ext::repeat_n(std::move(e), 3);\n\t\tCHECK_EQUAL(v2, v3);\n\t}\n\t{\n\t\tauto v = ranges::views::ext::repeat_n(9, 10);\n\t\tstatic_assert(ranges::view<decltype(v)>);\n\t\tstatic_assert(ranges::random_access_iterator<decltype(v.begin())>);\n\t\tstatic_assert(ranges::sized_range<decltype(v)>);\n\t\tCHECK_EQUAL(v, {9, 9, 9, 9, 9, 9, 9, 9, 9, 9});\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/repeat_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2015\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/repeat.hpp>\n#include <stl2/view/take.hpp>\n#include <array>\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nint main() {\n\t{\n\t\tauto v = ranges::ext::repeat_view{42};\n\t\tusing R = decltype(v);\n\t\tstatic_assert(ranges::view<R>);\n\t\tstatic_assert(ranges::random_access_range<R>);\n\t\tstatic_assert(!ranges::contiguous_range<R>);\n\t\tstatic_assert(!ranges::common_range<R>);\n\t\tstatic_assert(sizeof(v) == sizeof(int));\n\t\tCHECK(v.value() == 42);\n\n\t\tauto first = v.begin();\n\t\tstatic_assert(ranges::same_as<decltype(*first), int&>);\n\t\tstatic_assert(ranges::same_as<decltype(first.operator->()), int*>);\n\t\tCHECK(*first == 42);\n\t\tCHECK(std::addressof(*first) == std::addressof(v.value()));\n\t\tCHECK(ranges::next(first) == first);\n\n\t\tauto const& cv = v;\n\t\tstatic_assert(ranges::random_access_range<const R>);\n\t\tstatic_assert(!ranges::contiguous_range<const R>);\n\t\tstatic_assert(!ranges::common_range<const R>);\n\t\tCHECK(cv.value() == 42);\n\t\tCHECK(std::addressof(v.value()) == std::addressof(cv.value()));\n\n\t\tauto cfirst = cv.begin();\n\t\tstatic_assert(ranges::same_as<decltype(*cfirst), const int&>);\n\t\tstatic_assert(ranges::same_as<decltype(cfirst.operator->()), const int*>);\n\t\tCHECK(*cfirst == 42);\n\t\tCHECK(std::addressof(*cfirst) == std::addressof(cv.value()));\n\t\tCHECK(ranges::next(cfirst) == cfirst);\n\n\t\tCHECK(first == cfirst);\n\t\tcfirst = first;\n\t\tCHECK(first == cfirst + 1729);\n\n\t\tCHECK(first == first + 42);\n\n\t\tfirst[999999999] = 13;\n\t\tCHECK(*cfirst == 13);\n\t}\n\t{\n\t\tauto v = ranges::views::ext::repeat(9) | ranges::views::take(10);\n\t\tstatic_assert(ranges::view<decltype(v)>);\n\t\tstatic_assert(ranges::random_access_iterator<decltype(v.begin())>);\n\t\tCHECK_EQUAL(v, {9, 9, 9, 9, 9, 9, 9, 9, 9, 9});\n\t}\n\t{\n\t\tstruct empty {\n\t\t\tbool operator==(empty const&) const noexcept { return true; }\n\t\t\tbool operator!=(empty const&) const noexcept { return false; }\n\t\t};\n\n\t\tauto e = empty{};\n\t\tauto v2 = ranges::views::ext::repeat(e) | ranges::views::take(3);\n\t\tCHECK_EQUAL(v2, {e, e, e});\n\n\t\tauto v3 = ranges::views::ext::repeat(std::move(e)) | ranges::views::take(3);\n\t\tCHECK_EQUAL(v2, v3);\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/reverse_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/reverse.hpp>\n#include <stl2/view/counted.hpp>\n#include <stl2/view/filter.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\nnamespace ranges = __stl2;\nnamespace views = ranges::views;\n\nint main() {\n\tusing ranges::view, ranges::range, ranges::sized_range, ranges::common_range;\n\tusing ranges::bidirectional_range, ranges::random_access_range;\n\t{\n\t\tint rg[] = {0,1,2,3,4,5,6,7,8,9};\n\t\tauto x = rg | views::reverse;\n\t\tCHECK_EQUAL(x, {9,8,7,6,5,4,3,2,1,0});\n\t\tstatic_assert(view<decltype(x)>);\n\t\tstatic_assert(range<const decltype(x)>);\n\t\tstatic_assert(sized_range<decltype(x)>);\n\t\tstatic_assert(common_range<decltype(x)>);\n\t\tstatic_assert(random_access_range<decltype(x)>);\n\t}\n\t{\n\t\tint rg[] = {0,1,2,3,4,5,6,7,8,9};\n\t\tauto x = views::counted(bidirectional_iterator(rg), 5) | views::reverse;\n\t\tCHECK_EQUAL(x, {4,3,2,1,0});\n\t\tstatic_assert(view<decltype(x)>);\n\t\tstatic_assert(!range<const decltype(x)>);\n\t\tstatic_assert(sized_range<decltype(x)>);\n\t\tstatic_assert(common_range<decltype(x)>);\n\t\tstatic_assert(bidirectional_range<decltype(x)>);\n\t\tstatic_assert(!random_access_range<decltype(x)>);\n\t}\n\t{\n\t\t// Regression test for CaseyCarter/cmcstl2#223\n\t\tint a[] = {1, 7, 3, 6, 5, 2, 4, 8};\n\t\tauto r0 = views::reverse(a);\n\t\tauto is_even = [](int i) { return i % 2 == 0; };\n\t\tauto r1 = views::filter(r0, is_even);\n\t\tint sum = 0;\n\t\tfor (auto i : r1) {\n\t\t\tsum += i;\n\t\t}\n\t\tCHECK(20 == sum);\n\t}\n\n\t{\n\t\tint rg[] = {0,1,2,3,4,5,6,7,8,9};\n#if 0\n\t\tauto x = rg | views::reverse | views::reverse;\n\t\tstatic_assert(same_as<decltype(x), ref_view<decltype(rg)>>);\n\t\tCHECK(&x.base() == &rg);\n#else\n\t\tusing ranges::_RangeImpl, ranges::viewable_range;\n\t\tauto x = views::reverse(rg);\n\t\tusing R = decltype(x);\n\t\tstatic_assert(range<R>);\n\t\tstatic_assert(!_RangeImpl<R>);\n\t\tstatic_assert(view<R>);\n\t\tstatic_assert(viewable_range<R>);\n#endif\n\t}\n \treturn test_result();\n}\n"
  },
  {
    "path": "test/view/single_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2018\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/single.hpp>\n#include <stl2/detail/concepts/core.hpp>\n#include <stl2/detail/iterator/concepts.hpp>\n#include <stl2/detail/range/concepts.hpp>\n#include <type_traits>\n#include <utility>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\ntemplate<class T>\nusing remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;\n\ntemplate<class V, class T>\nvoid test_one(V& v, const T& t) {\n    static_assert(ranges::contiguous_range<V>);\n    static_assert(ranges::sized_range<V>);\n    static_assert(ranges::common_range<V>);\n    using I = ranges::iterator_t<V>;\n    static_assert(std::is_pointer_v<I>);\n    static_assert(ranges::same_as<T, ranges::iter_value_t<I>>);\n    static_assert(V::size() == 1u);\n    CHECK(v.size() == 1u);\n    CHECK(v.data() != nullptr);\n    CHECK(&*v.begin() == v.data());\n    CHECK(v.end() == v.begin() + 1);\n    CHECK(v.front() == t);\n}\n\ntemplate<class T>\nvoid test(T&& t) {\n    using D = remove_cvref_t<T>;\n    auto v = ranges::views::single(std::forward<T>(t));\n    static_assert(ranges::same_as<ranges::single_view<D>, decltype(v)>);\n    test_one(v, t);\n    test_one(std::as_const(v), t);\n}\n\nint main() {\n\tusing namespace ranges;\n\n    test(42);\n    {\n        int i = 42;\n        test(i);\n    }\n\n    {\n        const int i = 42;\n        test(i);\n    }\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/span.cpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n//\n// Copyright (c) 2015 Microsoft Corporation. All rights reserved.\n//\n// This code is licensed under the MIT License (MIT).\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n///////////////////////////////////////////////////////////////////////////////\n\n#include <stl2/detail/span.hpp>\n#include <stl2/detail/algorithm/find.hpp>\n\n#include <array>\n#include <iostream>\n#include <list>\n#include <map>\n#include <memory>\n#include <regex>\n#include <string>\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\nusing ranges::ext::span;\nusing ranges::ext::__span::narrow_cast;\nusing ranges::ext::make_span;\nusing ranges::ext::as_bytes;\nusing ranges::ext::as_writeable_bytes;\n\nnamespace {\n\tstruct BaseClass {};\n\tstruct DerivedClass : BaseClass {};\n}\n\nvoid test_case_default_constructor()\n{\n\t{\n\t\tspan<int> s;\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\n\t\tspan<const int> cs;\n\t\tCHECK((cs.size() == 0 && cs.data() == nullptr));\n\t}\n\n\t{\n\t\tspan<int, 0> s;\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\n\t\tspan<const int, 0> cs;\n\t\tCHECK((cs.size() == 0 && cs.data() == nullptr));\n\t}\n\n\t{\n\t\tspan<int, 1> s;\n\t\tCHECK((s.size() == 1 && s.data() == nullptr));\n\t}\n\n\t{\n\t\tspan<int> s{};\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\n\t\tspan<const int> cs{};\n\t\tCHECK((cs.size() == 0 && cs.data() == nullptr));\n\t}\n}\n\nvoid test_case_size_optimization()\n{\n\t{\n\t\tspan<int> s;\n\t\tCHECK(sizeof(s) == sizeof(int*) + sizeof(std::ptrdiff_t));\n\t}\n\n\t{\n\t\tspan<int, 0> s;\n\t\tCHECK(sizeof(s) == sizeof(int*));\n\t}\n}\n\nvoid test_case_from_nullptr_constructor()\n{\n\t// This implementation doesn't support the silly nullptr_t constructor.\n\tstatic_assert(!std::is_constructible<span<int>, std::nullptr_t>::value);\n\tstatic_assert(!std::is_constructible<span<const int>, std::nullptr_t>::value);\n\n\tstatic_assert(!std::is_constructible<span<int, 0>, std::nullptr_t>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 0>, std::nullptr_t>::value);\n\n\tstatic_assert(!std::is_constructible<span<int, 1>, std::nullptr_t>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 1>, std::nullptr_t>::value);\n}\n\nvoid test_case_from_nullptr_size_constructor()\n{\n\t{\n\t\tspan<int> s{nullptr, static_cast<span<int>::index_type>(0)};\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\n\t\tspan<const int> cs{nullptr, static_cast<span<int>::index_type>(0)};\n\t\tCHECK((cs.size() == 0 && cs.data() == nullptr));\n\t}\n\n\t{\n\t\tspan<int, 0> s{nullptr, static_cast<span<int>::index_type>(0)};\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\n\t\tspan<const int, 0> cs{nullptr, static_cast<span<int>::index_type>(0)};\n\t\tCHECK((cs.size() == 0 && cs.data() == nullptr));\n\t}\n\n\t{\n\t\tspan<int*> s{nullptr, static_cast<span<int>::index_type>(0)};\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\n\t\tspan<const int*> cs{nullptr, static_cast<span<int>::index_type>(0)};\n\t\tCHECK((cs.size() == 0 && cs.data() == nullptr));\n\t}\n}\n\nvoid test_case_from_pointer_size_constructor()\n{\n\tint arr[4] = {1, 2, 3, 4};\n\n\t{\n\t\tspan<int> s{&arr[0], 2};\n\t\tCHECK((s.size() == 2 && s.data() == &arr[0]));\n\t\tCHECK((s[0] == 1 && s[1] == 2));\n\t}\n\n\t{\n\t\tspan<int, 2> s{&arr[0], 2};\n\t\tCHECK((s.size() == 2 && s.data() == &arr[0]));\n\t\tCHECK((s[0] == 1 && s[1] == 2));\n\t}\n\n\t{\n\t\tint* p = nullptr;\n\t\tspan<int> s{p, static_cast<span<int>::index_type>(0)};\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\t}\n\n\t{\n\t\tauto s = make_span(&arr[0], 2);\n\t\tCHECK((s.size() == 2 && s.data() == &arr[0]));\n\t\tCHECK((s[0] == 1 && s[1] == 2));\n\t}\n\n\t{\n\t\tint* p = nullptr;\n\t\tauto s = make_span(p, static_cast<span<int>::index_type>(0));\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\t}\n}\n\nvoid test_case_from_pointer_pointer_constructor()\n{\n\tint arr[4] = {1, 2, 3, 4};\n\n\t{\n\t\tspan<int> s{&arr[0], &arr[2]};\n\t\tCHECK((s.size() == 2 && s.data() == &arr[0]));\n\t\tCHECK((s[0] == 1 && s[1] == 2));\n\t}\n\n\t{\n\t\tspan<int, 2> s{&arr[0], &arr[2]};\n\t\tCHECK((s.size() == 2 && s.data() == &arr[0]));\n\t\tCHECK((s[0] == 1 && s[1] == 2));\n\t}\n\n\t{\n\t\tspan<int> s{&arr[0], &arr[0]};\n\t\tCHECK((s.size() == 0 && s.data() == &arr[0]));\n\t}\n\n\t{\n\t\tspan<int, 0> s{&arr[0], &arr[0]};\n\t\tCHECK((s.size() == 0 && s.data() == &arr[0]));\n\t}\n\n\t// this will fail the std::distance() precondition, which asserts on MSVC debug builds\n\t//{\n\t//    auto workaround_macro = [&]() { span<int> s{&arr[1], &arr[0]}; };\n\t//    CHECK_THROWS_AS(workaround_macro(), fail_fast);\n\t//}\n\n\t// this will fail the std::distance() precondition, which asserts on MSVC debug builds\n\t//{\n\t//    int* p = nullptr;\n\t//    auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };\n\t//    CHECK_THROWS_AS(workaround_macro(), fail_fast);\n\t//}\n\n\t{\n\t\tint* p = nullptr;\n\t\tspan<int> s{p, p};\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\t}\n\n\t{\n\t\tint* p = nullptr;\n\t\tspan<int, 0> s{p, p};\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\t}\n\n\t// this will fail the std::distance() precondition, which asserts on MSVC debug builds\n\t//{\n\t//    int* p = nullptr;\n\t//    auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };\n\t//    CHECK_THROWS_AS(workaround_macro(), fail_fast);\n\t//}\n\n\t{\n\t\tauto s = make_span(&arr[0], &arr[2]);\n\t\tCHECK((s.size() == 2 && s.data() == &arr[0]));\n\t\tCHECK((s[0] == 1 && s[1] == 2));\n\t}\n\n\t{\n\t\tauto s = make_span(&arr[0], &arr[0]);\n\t\tCHECK((s.size() == 0 && s.data() == &arr[0]));\n\t}\n\n\t{\n\t\tint* p = nullptr;\n\t\tauto s = make_span(p, p);\n\t\tCHECK((s.size() == 0 && s.data() == nullptr));\n\t}\n}\n\nvoid test_case_from_array_constructor()\n{\n\tint arr[5] = {1, 2, 3, 4, 5};\n\n\t{\n\t\tspan<int> s{arr};\n\t\tCHECK((s.size() == 5 && s.data() == &arr[0]));\n\t}\n\n\t{\n\t\tspan<int, 5> s{arr};\n\t\tCHECK((s.size() == 5 && s.data() == &arr[0]));\n\t}\n\n\tint arr2d[2][3] = {1, 2, 3, 4, 5, 6};\n\n\tstatic_assert(!std::is_constructible<span<int, 6>, int(&)[5]>::value);\n\tstatic_assert(!std::is_constructible<span<int, 0>, int(&)[5]>::value);\n\tstatic_assert(!std::is_constructible<span<int>, decltype((arr2d))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 0>, decltype((arr2d))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 6>, decltype((arr2d))>::value);\n\n\t{\n\t\tspan<int[3]> s{&(arr2d[0]), 1};\n\t\tCHECK((s.size() == 1 && s.data() == &arr2d[0]));\n\t}\n\n\tint arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};\n\n\tstatic_assert(!std::is_constructible<span<int>, decltype((arr3d))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 0>, decltype((arr3d))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 11>, decltype((arr3d))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 12>, decltype((arr3d))>::value);\n\n\t{\n\t\tspan<int[3][2]> s{&arr3d[0], 1};\n\t\tCHECK((s.size() == 1 && s.data() == &arr3d[0]));\n\t}\n\n\t{\n\t\tauto s = make_span(arr);\n\t\tCHECK((s.size() == 5 && s.data() == &arr[0]));\n\t}\n\n\t{\n\t\tauto s = make_span(&(arr2d[0]), 1);\n\t\tCHECK((s.size() == 1 && s.data() == &arr2d[0]));\n\t}\n\n\t{\n\t\tauto s = make_span(&arr3d[0], 1);\n\t\tCHECK((s.size() == 1 && s.data() == &arr3d[0]));\n\t}\n}\n\nvoid test_case_from_std_array_constructor()\n{\n\tstd::array<int, 4> arr = {1, 2, 3, 4};\n\n\t{\n\t\tspan<int> s{arr};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\n\t\tspan<const int> cs{arr};\n\t\tCHECK((cs.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && cs.data() == arr.data()));\n\t}\n\n\t{\n\t\tspan<int, 4> s{arr};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\n\t\tspan<const int, 4> cs{arr};\n\t\tCHECK((cs.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && cs.data() == arr.data()));\n\t}\n\n\tstatic_assert(!std::is_constructible<span<int, 2>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 2>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 0>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 0>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 5>, decltype((arr))>::value);\n\n\t{\n\t\tauto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };\n\t\tauto take_a_span = [](span<int>) {};\n\t\ttake_a_span(get_an_array());\n\t}\n\n\t{\n\t\tauto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };\n\t\tauto take_a_span = [](span<const int>) {};\n\t\ttake_a_span(get_an_array());\n\t}\n\n\t{\n\t\tauto s = make_span(arr);\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\t}\n}\n\nvoid test_case_from_const_std_array_constructor()\n{\n\tconst std::array<int, 4> arr = {1, 2, 3, 4};\n\n\t{\n\t\tspan<const int> s{arr};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\t}\n\n\t{\n\t\tspan<const int, 4> s{arr};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\t}\n\n\tstatic_assert(!std::is_constructible<span<const int, 2>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 0>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 5>, decltype((arr))>::value);\n\n\t{\n\t\tauto get_an_array = []() -> const std::array<int, 4> { return {1, 2, 3, 4}; };\n\t\tauto take_a_span = [](span<const int>) {};\n\t\ttake_a_span(get_an_array());\n\t}\n\n\t{\n\t\tauto s = make_span(arr);\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\t}\n}\n\nvoid test_case_from_std_array_const_constructor()\n{\n\tstd::array<const int, 4> arr = {1, 2, 3, 4};\n\n\t{\n\t\tspan<const int> s{arr};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\t}\n\n\t{\n\t\tspan<const int, 4> s{arr};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\t}\n\n\tstatic_assert(!std::is_constructible<span<const int, 2>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 0>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<const int, 5>, decltype((arr))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 4>, decltype((arr))>::value);\n\n\t{\n\t\tauto s = make_span(arr);\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(arr.size()) && s.data() == arr.data()));\n\t}\n}\n\nvoid test_case_from_container_constructor()\n{\n\tstd::vector<int> v = {1, 2, 3};\n\tconst std::vector<int> cv = v;\n\n\t{\n\t\tspan<int> s{v};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data()));\n\n\t\tspan<const int> cs{v};\n\t\tCHECK((cs.size() == narrow_cast<std::ptrdiff_t>(v.size()) && cs.data() == v.data()));\n\t}\n\n\tstd::string str = \"hello\";\n\tconst std::string cstr = \"hello\";\n\n\t{\n\t\tspan<char> s{str};\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(str.size()) && s.data() == str.data()));\n\t}\n\n\t{\n\t\tauto get_temp_string = []() -> std::string { return {}; };\n\t\tauto use_span = [](span<char>) {};\n\t\tuse_span(get_temp_string());\n\t}\n\n\t{\n\t\tspan<const char> cs{str};\n\t\tCHECK((cs.size() == narrow_cast<std::ptrdiff_t>(str.size()) && cs.data() == str.data()));\n\t}\n\n\t{\n\t\tauto get_temp_string = []() -> std::string { return {}; };\n\t\tauto use_span = [](span<const char>) {};\n\t\tuse_span(get_temp_string());\n\t}\n\n\t{\n\t\tstatic_assert(!std::is_constructible<span<char>, decltype((cstr))>::value);\n\t\tspan<const char> cs{cstr};\n\t\tCHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size()) &&\n\t\t\t  cs.data() == cstr.data()));\n\t}\n\n\t{\n\t\tauto get_temp_vector = []() -> std::vector<int> { return {}; };\n\t\tauto use_span = [](span<int>) {};\n\t\tuse_span(get_temp_vector());\n\t}\n\n\t{\n\t\tauto get_temp_vector = []() -> std::vector<int> { return {}; };\n\t\tauto use_span = [](span<const int>) {};\n\t\tuse_span(get_temp_vector());\n\t}\n\n\tstatic_assert(!std::is_convertible<const std::vector<int>, span<const char>>::value);\n\n\t{\n\t\tauto get_temp_string = []() -> const std::string { return {}; };\n\t\tauto use_span = [](span<const char> s) { static_cast<void>(s); };\n\t\tuse_span(get_temp_string());\n\t\tuse_span(span<const char>(get_temp_string()));\n\t}\n\n\tstatic_assert(!std::is_constructible<span<int>, std::map<int, int>&>::value);\n\n\t{\n\t\tauto s = make_span(v);\n\t\tCHECK((s.size() == narrow_cast<std::ptrdiff_t>(v.size()) && s.data() == v.data()));\n\n\t\tauto cs = make_span(cv);\n\t\tCHECK((cs.size() == narrow_cast<std::ptrdiff_t>(cv.size()) && cs.data() == cv.data()));\n\t}\n}\n\nvoid test_case_from_convertible_span_constructor()\n{\n\t{\n\t\tspan<DerivedClass> avd;\n\t\tspan<const DerivedClass> avcd = avd;\n\t\tstatic_cast<void>(avcd);\n\t}\n\n\tstatic_assert(!std::is_constructible<span<BaseClass>, span<DerivedClass>>::value);\n\tstatic_assert(!std::is_constructible<span<DerivedClass>, span<BaseClass>>::value);\n\tstatic_assert(!std::is_constructible<span<unsigned int>, span<int>>::value);\n\tstatic_assert(!std::is_constructible<span<const unsigned int>, span<int>>::value);\n\tstatic_assert(!std::is_constructible<span<short>, span<int>>::value);\n}\n\nvoid test_case_copy_move_and_assignment()\n{\n\tspan<int> s1;\n\tCHECK(s1.empty());\n\n\tint arr[] = {3, 4, 5};\n\n\tspan<const int> s2 = arr;\n\tCHECK((s2.size() == 3 && s2.data() == &arr[0]));\n\n\ts2 = s1;\n\tCHECK(s2.empty());\n\n\tauto get_temp_span = [&]() -> span<int> { return {&arr[1], 2}; };\n\tauto use_span = [&](span<const int> s) { CHECK((s.size() == 2 && s.data() == &arr[1])); };\n\tuse_span(get_temp_span());\n\n\ts1 = get_temp_span();\n\tCHECK((s1.size() == 2 && s1.data() == &arr[1]));\n}\n\nvoid test_case_class_template_argument_deduction()\n{\n#ifdef __cpp_deduction_guides\n\t{\n\t\tint arr[] = {1, 2, 3, 4, 5};\n\t\t{\n\t\t\tspan s{arr};\n\t\t\tstatic_assert(ranges::same_as<span<int, 5>, decltype(s)>);\n\t\t}\n\t\t{\n\t\t\tspan s{ranges::begin(arr), ranges::size(arr)};\n\t\t\tstatic_assert(ranges::same_as<span<int>, decltype(s)>);\n\t\t}\n\t\t{\n\t\t\tspan s{ranges::begin(arr), ranges::end(arr)};\n\t\t\tstatic_assert(ranges::same_as<span<int>, decltype(s)>);\n\t\t}\n\t}\n\t{\n\t\tstd::array<int, 5> arr = {1, 2, 3, 4, 5};\n\t\t{\n\t\t\tspan s{arr};\n\t\t\tstatic_assert(ranges::same_as<span<int, 5>, decltype(s)>);\n\t\t}\n#if 0 // TODO: reactivate these cases on the span_updates branch\n\t\t{\n\t\t\tspan s{ranges::begin(arr), ranges::size(arr)};\n\t\t\tstatic_assert(ranges::same_as<span<int>, decltype(s)>);\n\t\t}\n\t\t{\n\t\t\tspan s{ranges::begin(arr), ranges::end(arr)};\n\t\t\tstatic_assert(ranges::same_as<span<int>, decltype(s)>);\n\t\t}\n#endif\n\t}\n\t{\n\t\tstd::vector<int> vec = {1, 2, 3, 4, 5};\n\t\t{\n\t\t\tspan s{vec};\n\t\t\tstatic_assert(ranges::same_as<span<int>, decltype(s)>);\n\t\t}\n\t}\n#endif\n}\n\nvoid test_case_first()\n{\n\tint arr[5] = {1, 2, 3, 4, 5};\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK(av.first<2>().size() == 2);\n\t\tCHECK(av.first(2).size() == 2);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK(av.first<0>().size() == 0);\n\t\tCHECK(av.first(0).size() == 0);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK(av.first<5>().size() == 5);\n\t\tCHECK(av.first(5).size() == 5);\n\t}\n\n\t{\n\t\tspan<int> av;\n\t\tCHECK(av.first<0>().size() == 0);\n\t\tCHECK(av.first(0).size() == 0);\n\t}\n}\n\nvoid test_case_last()\n{\n\tint arr[5] = {1, 2, 3, 4, 5};\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK(av.last<2>().size() == 2);\n\t\tCHECK(av.last(2).size() == 2);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK(av.last<0>().size() == 0);\n\t\tCHECK(av.last(0).size() == 0);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK(av.last<5>().size() == 5);\n\t\tCHECK(av.last(5).size() == 5);\n\t}\n\n\t{\n\t\tspan<int> av;\n\t\tCHECK(av.last<0>().size() == 0);\n\t\tCHECK(av.last(0).size() == 0);\n\t}\n}\n\nvoid test_case_subspan()\n{\n\tint arr[5] = {1, 2, 3, 4, 5};\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK((av.subspan<2, 2>().size() == 2));\n\t\tCHECK(av.subspan(2, 2).size() == 2);\n\t\tCHECK(av.subspan(2, 3).size() == 3);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK((av.subspan<0, 0>().size() == 0));\n\t\tCHECK(av.subspan(0, 0).size() == 0);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK((av.subspan<0, 5>().size() == 5));\n\t\tCHECK(av.subspan(0, 5).size() == 5);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK((av.subspan<4, 0>().size() == 0));\n\t\tCHECK(av.subspan(4, 0).size() == 0);\n\t\tCHECK(av.subspan(5, 0).size() == 0);\n\t}\n\n\t{\n\t\tspan<int> av;\n\t\tCHECK((av.subspan<0, 0>().size() == 0));\n\t\tCHECK(av.subspan(0, 0).size() == 0);\n\t}\n\n\t{\n\t\tspan<int> av;\n\t\tCHECK(av.subspan(0).size() == 0);\n\t}\n\n\t{\n\t\tspan<int> av = arr;\n\t\tCHECK(av.subspan(0).size() == 5);\n\t\tCHECK(av.subspan(1).size() == 4);\n\t\tCHECK(av.subspan(4).size() == 1);\n\t\tCHECK(av.subspan(5).size() == 0);\n\t\tconst auto av2 = av.subspan(1);\n\t\tfor (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2);\n\t}\n\n\t{\n\t\tspan<int, 5> av = arr;\n\t\tCHECK(av.subspan(0).size() == 5);\n\t\tCHECK(av.subspan(1).size() == 4);\n\t\tCHECK(av.subspan(4).size() == 1);\n\t\tCHECK(av.subspan(5).size() == 0);\n\t\tconst auto av2 = av.subspan(1);\n\t\tfor (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2);\n\t}\n}\n\nvoid test_case_iterator_value_init()\n{\n\tspan<int>::iterator it1{};\n\tspan<int>::iterator it2{};\n\tCHECK(it1 == it2);\n}\n\nvoid test_case_iterator_comparisons()\n{\n\tint a[] = {1, 2, 3, 4};\n\t{\n\t\tspan<int> s = a;\n\t\tspan<int>::iterator it = s.begin();\n\t\tauto it2 = it + 1;\n\n\t\tCHECK(it == it);\n\t\tCHECK(it == s.begin());\n\t\tCHECK(s.begin() == it);\n\n\t\tCHECK(it != it2);\n\t\tCHECK(it2 != it);\n\t\tCHECK(it != s.end());\n\t\tCHECK(it2 != s.end());\n\t\tCHECK(s.end() != it);\n\n\t\tCHECK(it < it2);\n\t\tCHECK(it <= it2);\n\t\tCHECK(it2 <= s.end());\n\t\tCHECK(it < s.end());\n\n\t\tCHECK(it2 > it);\n\t\tCHECK(it2 >= it);\n\t\tCHECK(s.end() > it2);\n\t\tCHECK(s.end() >= it2);\n\t}\n}\n\nvoid test_case_begin_end()\n{\n\t{\n\t\tint a[] = {1, 2, 3, 4};\n\t\tspan<int> s = a;\n\n\t\tspan<int>::iterator it = s.begin();\n\t\tspan<int>::iterator it2 = std::begin(s);\n\t\tCHECK(it == it2);\n\n\t\tit = s.end();\n\t\tit2 = std::end(s);\n\t\tCHECK(it == it2);\n\t}\n\n\t{\n\t\tint a[] = {1, 2, 3, 4};\n\t\tspan<int> s = a;\n\n\t\tauto it = s.begin();\n\t\tauto first = it;\n\t\tCHECK(it == first);\n\t\tCHECK(*it == 1);\n\n\t\tauto beyond = s.end();\n\t\tCHECK(it != beyond);\n\n\t\tCHECK((beyond - first) == 4);\n\t\tCHECK((first - first) == 0);\n\t\tCHECK((beyond - beyond) == 0);\n\n\t\t++it;\n\t\tCHECK((it - first) == 1);\n\t\tCHECK(*it == 2);\n\t\t*it = 22;\n\t\tCHECK(*it == 22);\n\t\tCHECK((beyond - it) == 3);\n\n\t\tit = first;\n\t\tCHECK(it == first);\n\t\twhile (it != s.end()) {\n\t\t\t*it = 5;\n\t\t\t++it;\n\t\t}\n\n\t\tCHECK(it == beyond);\n\t\tCHECK((it - beyond) == 0);\n\n\t\tfor (const auto& n : s) {\n\t\t\tCHECK(n == 5);\n\t\t}\n\t}\n}\n\nvoid test_case_rbegin_rend()\n{\n\t{\n\t\tint a[] = {1, 2, 3, 4};\n\t\tspan<int> s = a;\n\n\t\tauto it = s.rbegin();\n\t\tauto first = it;\n\t\tCHECK(it == first);\n\t\tCHECK(*it == 4);\n\n\t\tauto beyond = s.rend();\n\t\tCHECK(it != beyond);\n\n\t\tCHECK((beyond - first) == 4);\n\t\tCHECK((first - first) == 0);\n\t\tCHECK((beyond - beyond) == 0);\n\n\t\t++it;\n\t\tCHECK((it - first) == 1);\n\t\tCHECK(*it == 3);\n\t\t*it = 22;\n\t\tCHECK(*it == 22);\n\t\tCHECK((beyond - it) == 3);\n\n\t\tit = first;\n\t\tCHECK(it == first);\n\t\twhile (it != s.rend()) {\n\t\t\t*it = 5;\n\t\t\t++it;\n\t\t}\n\n\t\tCHECK(it == beyond);\n\t\tCHECK((it - beyond) == 0);\n\n\t\tfor (const auto& n : s) {\n\t\t\tCHECK(n == 5);\n\t\t}\n\t}\n}\n\nvoid test_case_comparison_operators()\n{\n\t{\n\t\tspan<int> s1;\n\t\tspan<int> s2;\n\t\tCHECK(s1 == s2);\n\t\tCHECK(!(s1 != s2));\n\t\tCHECK(!(s1 < s2));\n\t\tCHECK(s1 <= s2);\n\t\tCHECK(!(s1 > s2));\n\t\tCHECK(s1 >= s2);\n\t\tCHECK(s2 == s1);\n\t\tCHECK(!(s2 != s1));\n\t\tCHECK(!(s2 < s1));\n\t\tCHECK(s2 <= s1);\n\t\tCHECK(!(s2 > s1));\n\t\tCHECK(s2 >= s1);\n\t}\n\n\t{\n\t\tint arr[] = {2, 1};\n\t\tspan<int> s1 = arr;\n\t\tspan<int> s2 = arr;\n\n\t\tCHECK(s1 == s2);\n\t\tCHECK(!(s1 != s2));\n\t\tCHECK(!(s1 < s2));\n\t\tCHECK(s1 <= s2);\n\t\tCHECK(!(s1 > s2));\n\t\tCHECK(s1 >= s2);\n\t\tCHECK(s2 == s1);\n\t\tCHECK(!(s2 != s1));\n\t\tCHECK(!(s2 < s1));\n\t\tCHECK(s2 <= s1);\n\t\tCHECK(!(s2 > s1));\n\t\tCHECK(s2 >= s1);\n\t}\n\n\t{\n\t\tint arr[] = {2, 1}; // bigger\n\n\t\tspan<int> s1;\n\t\tspan<int> s2 = arr;\n\n\t\tCHECK(s1 != s2);\n\t\tCHECK(s2 != s1);\n\t\tCHECK(!(s1 == s2));\n\t\tCHECK(!(s2 == s1));\n\t\tCHECK(s1 < s2);\n\t\tCHECK(!(s2 < s1));\n\t\tCHECK(s1 <= s2);\n\t\tCHECK(!(s2 <= s1));\n\t\tCHECK(s2 > s1);\n\t\tCHECK(!(s1 > s2));\n\t\tCHECK(s2 >= s1);\n\t\tCHECK(!(s1 >= s2));\n\t}\n\n\t{\n\t\tint arr1[] = {1, 2};\n\t\tint arr2[] = {1, 2};\n\t\tspan<int> s1 = arr1;\n\t\tspan<int> s2 = arr2;\n\n\t\tCHECK(s1 == s2);\n\t\tCHECK(!(s1 != s2));\n\t\tCHECK(!(s1 < s2));\n\t\tCHECK(s1 <= s2);\n\t\tCHECK(!(s1 > s2));\n\t\tCHECK(s1 >= s2);\n\t\tCHECK(s2 == s1);\n\t\tCHECK(!(s2 != s1));\n\t\tCHECK(!(s2 < s1));\n\t\tCHECK(s2 <= s1);\n\t\tCHECK(!(s2 > s1));\n\t\tCHECK(s2 >= s1);\n\t}\n\n\t{\n\t\tint arr[] = {1, 2, 3};\n\n\t\tspan<int> s1 = {&arr[0], 2}; // shorter\n\t\tspan<int> s2 = arr;          // longer\n\n\t\tCHECK(s1 != s2);\n\t\tCHECK(s2 != s1);\n\t\tCHECK(!(s1 == s2));\n\t\tCHECK(!(s2 == s1));\n\t\tCHECK(s1 < s2);\n\t\tCHECK(!(s2 < s1));\n\t\tCHECK(s1 <= s2);\n\t\tCHECK(!(s2 <= s1));\n\t\tCHECK(s2 > s1);\n\t\tCHECK(!(s1 > s2));\n\t\tCHECK(s2 >= s1);\n\t\tCHECK(!(s1 >= s2));\n\t}\n\n\t{\n\t\tint arr1[] = {1, 2}; // smaller\n\t\tint arr2[] = {2, 1}; // bigger\n\n\t\tspan<int> s1 = arr1;\n\t\tspan<int> s2 = arr2;\n\n\t\tCHECK(s1 != s2);\n\t\tCHECK(s2 != s1);\n\t\tCHECK(!(s1 == s2));\n\t\tCHECK(!(s2 == s1));\n\t\tCHECK(s1 < s2);\n\t\tCHECK(!(s2 < s1));\n\t\tCHECK(s1 <= s2);\n\t\tCHECK(!(s2 <= s1));\n\t\tCHECK(s2 > s1);\n\t\tCHECK(!(s1 > s2));\n\t\tCHECK(s2 >= s1);\n\t\tCHECK(!(s1 >= s2));\n\t}\n}\n\nvoid test_case_as_bytes()\n{\n\tint a[] = {1, 2, 3, 4};\n\n\t{\n\t\tconst span<const int> s = a;\n\t\tCHECK(s.size() == 4);\n\t\tconst auto bs = as_bytes(s);\n\t\tCHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));\n\t\tCHECK(bs.size() == s.size_bytes());\n\t}\n\n\t{\n\t\tspan<int> s;\n\t\tconst auto bs = as_bytes(s);\n\t\tCHECK(bs.size() == s.size());\n\t\tCHECK(bs.size() == 0);\n\t\tCHECK(bs.size_bytes() == 0);\n\t\tCHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));\n\t\tCHECK(bs.data() == nullptr);\n\t}\n\n\t{\n\t\tspan<int> s = a;\n\t\tconst auto bs = as_bytes(s);\n\t\tCHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));\n\t\tCHECK(bs.size() == s.size_bytes());\n\t}\n}\n\nvoid test_case_as_writeable_bytes()\n{\n\tint a[] = {1, 2, 3, 4};\n\n\t{\n\t\tspan<int> s;\n\t\tconst auto bs = as_writeable_bytes(s);\n\t\tCHECK(bs.size() == s.size());\n\t\tCHECK(bs.size() == 0);\n\t\tCHECK(bs.size_bytes() == 0);\n\t\tCHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));\n\t\tCHECK(bs.data() == nullptr);\n\t}\n\n\t{\n\t\tspan<int> s = a;\n\t\tconst auto bs = as_writeable_bytes(s);\n\t\tCHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));\n\t\tCHECK(bs.size() == s.size_bytes());\n\t}\n}\n\nvoid test_case_fixed_size_conversions()\n{\n\tint arr[] = {1, 2, 3, 4};\n\n\t// converting to an span from an equal size array is ok\n\tspan<int, 4> s4 = arr;\n\tCHECK(s4.size() == 4);\n\n\t// converting to dynamic_range is always ok\n\t{\n\t\tspan<int> s = s4;\n\t\tCHECK(s.size() == s4.size());\n\t\tstatic_cast<void>(s);\n\t}\n\n\t// initialization or assignment to static span that REDUCES size is NOT ok\n\tstatic_assert(!std::is_convertible<decltype((arr)), span<int, 2>>::value);\n\tstatic_assert(!std::is_convertible<span<int, 4>, span<int, 2>>::value);\n\n\t// you can convert statically\n\t{\n\t\tconst span<int, 2> s2 = {arr, 2};\n\t\tstatic_cast<void>(s2);\n\t}\n\t{\n\t\tconst span<int, 1> s1 = s4.first<1>();\n\t\tstatic_cast<void>(s1);\n\t}\n\n\t// ...or dynamically\n\t{\n\t\t// NB: implicit conversion to span<int,1> from span<int>\n\t\tspan<int, 1> s1 = s4.first(1);\n\t\tstatic_cast<void>(s1);\n\t}\n\n\t// initialization or assignment to static span that requires size INCREASE is not ok.\n\tint arr2[2] = {1, 2};\n\t(void)arr2;\n\n\tstatic_assert(!std::is_constructible<span<int, 4>, decltype((arr2))>::value);\n\tstatic_assert(!std::is_constructible<span<int, 4>, span<int, 2>>::value);\n}\n\nvoid test_case_interop_with_std_regex()\n{\n\tchar lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'};\n\tspan<char> s = lat;\n\tconst auto f_it = s.begin() + 7;\n\n\tstd::match_results<span<char>::iterator> match;\n\n\tstd::regex_match(s.begin(), s.end(), match, std::regex(\".*\"));\n\tCHECK(match.ready());\n\tCHECK(!match.empty());\n\tCHECK(match[0].matched);\n\tCHECK(match[0].first == s.begin());\n\tCHECK(match[0].second == s.end());\n\n\tstd::regex_search(s.begin(), s.end(), match, std::regex(\"F\"));\n\tCHECK(match.ready());\n\tCHECK(!match.empty());\n\tCHECK(match[0].matched);\n\tCHECK(match[0].first == f_it);\n\tCHECK(match[0].second == (f_it + 1));\n}\n\nvoid test_case_default_initializable()\n{\n\tCHECK((std::is_default_constructible<span<int>>::value));\n\tCHECK((std::is_default_constructible<span<int, 0>>::value));\n\tCHECK((std::is_default_constructible<span<int, 42>>::value));\n}\n\nint main() {\n\ttest_case_default_constructor();\n\ttest_case_size_optimization();\n\ttest_case_from_nullptr_constructor();\n\ttest_case_from_nullptr_size_constructor();\n\ttest_case_from_pointer_size_constructor();\n\ttest_case_from_pointer_pointer_constructor();\n\ttest_case_from_array_constructor();\n\ttest_case_from_std_array_constructor();\n\ttest_case_from_const_std_array_constructor();\n\ttest_case_from_std_array_const_constructor();\n\ttest_case_from_container_constructor();\n\ttest_case_from_convertible_span_constructor();\n\ttest_case_copy_move_and_assignment();\n\ttest_case_class_template_argument_deduction();\n\ttest_case_first();\n\ttest_case_last();\n\ttest_case_subspan();\n\ttest_case_iterator_value_init();\n\ttest_case_iterator_comparisons();\n\ttest_case_begin_end();\n\ttest_case_rbegin_rend();\n\ttest_case_comparison_operators();\n\ttest_case_as_bytes();\n\ttest_case_as_writeable_bytes();\n\ttest_case_fixed_size_conversions();\n\ttest_case_interop_with_std_regex();\n\ttest_case_default_initializable();\n\n\tstatic_assert(ranges::contiguous_range<span<int>> && ranges::view<span<int>>);\n\tstatic_assert(ranges::contiguous_range<span<int, 42>> && ranges::view<span<int, 42>>);\n\n\t// spans are non-dangling\n\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<span<int>>())), ranges::iterator_t<span<int>>>);\n\tstatic_assert(ranges::same_as<decltype(ranges::end(std::declval<span<int>>())), ranges::iterator_t<span<int>>>);\n\tstatic_assert(ranges::same_as<decltype(ranges::begin(std::declval<const span<int>>())), ranges::iterator_t<span<int>>>);\n\tstatic_assert(ranges::same_as<decltype(ranges::end(std::declval<const span<int>>())), ranges::iterator_t<span<int>>>);\n\t{\n\t\tint some_ints[]{42};\n\t\tCHECK(ranges::data(span{some_ints, 42}) == +some_ints);\n\t}\n\n\t{\n\t\tint some_ints[] = {0,1,2,3,4};\n\t\tauto result = ranges::find(span{some_ints}, 3);\n\t\tCHECK(*result == 3);\n\t}\n}\n"
  },
  {
    "path": "test/view/split_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/split.hpp>\n#include <stl2/view/empty.hpp>\n#include <stl2/detail/iterator/istreambuf_iterator.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_iterators.hpp\"\n\n#include <list>\n#include <sstream>\n\nnamespace ranges = __stl2;\n\nint main() {\n\tusing namespace ranges;\n\tstd::string greeting = \"now is the time\";\n\tstd::string pattern = \" \";\n\n\t{\n\t\tsplit_view sv{greeting, pattern};\n\t\tauto i = sv.begin();\n\t\tCHECK_EQUAL(*i, {'n','o','w'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'i','s'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'t','h','e'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'t','i','m','e'});\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tsplit_view sv{greeting, ' '};\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'n','o','w'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'i','s'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'t','h','e'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'t','i','m','e'});\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tstd::stringstream sin{greeting};\n\t\tauto rng = subrange{\n\t\t\tistreambuf_iterator<char>{sin},\n\t\t\tdefault_sentinel};\n\n\t\tsplit_view sv{rng, ' '};\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'n','o','w'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'i','s'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'t','h','e'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'t','i','m','e'});\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tstd::string list{\"eggs,milk,,butter\"};\n\t\tsplit_view sv{list, ','};\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'e','g','g','s'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'m','i','l','k'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, views::empty<char>);\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'b','u','t','t','e','r'});\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tstd::string list{\"eggs,milk,,butter\"};\n\t\tstd::stringstream sin{list};\n\t\tauto rng = subrange{\n\t\t\tistreambuf_iterator<char>{sin},\n\t\t\tdefault_sentinel};\n\t\tauto sv = rng | views::split(',');\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'e','g','g','s'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'m','i','l','k'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, views::empty<char>);\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, {'b','u','t','t','e','r'});\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tstd::string hello(\"hello\");\n\t\tsplit_view sv{hello, views::empty<char>};\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'h'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'e'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'o'});\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tstd::string hello{\"hello\"};\n\t\tstd::stringstream sin{hello};\n\t\tauto rng = subrange{\n\t\t\tistreambuf_iterator<char>{sin},\n\t\t\tdefault_sentinel};\n\t\tauto sv = views::split(rng, views::empty<char>);\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'h'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'e'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'o'});\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tstd::string hello{\"hello\"};\n\t\tauto sv = views::split(hello, views::empty<char>);\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\t{\n\t\tstd::string hello{\"hello\"};\n\t\tstd::stringstream sin{hello};\n\t\tauto rng = subrange{\n\t\t\tistreambuf_iterator<char>{sin},\n\t\t\tdefault_sentinel};\n\t\tauto sv = views::split(rng, views::empty<char>);\n\t\tauto i = sv.begin();\n\t\tCHECK(i != sv.end());\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\tCHECK_EQUAL(*i, single_view{'l'});\n\t\t++i;\n\t\tCHECK(i != sv.end());\n\t\t++i;\n\t\tCHECK(i == sv.end());\n\t}\n\n\treturn test_result();\n}\n"
  },
  {
    "path": "test/view/subrange.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Eric Niebler 2014\n//  Copyright Casey Carter 2017\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <list>\n#include <vector>\n#include <stl2/view/all.hpp>\n#include <stl2/view/subrange.hpp>\n#include \"../simple_test.hpp\"\n#include \"../test_utils.hpp\"\n\nnamespace ranges = __stl2;\n\nusing namespace ranges;\n\ntemplate<range Rng>\nsafe_subrange_t<Rng> algorithm(Rng &&rng);\n\nstruct Base {};\nstruct Derived : Base {};\n\nint main() {\n\tstd::vector<int> vi{1,2,3,4};\n\n\t////////////////////////////////////////////////////////////////////////////\n\t// safe_subrange_t tests:\n\n\t// lvalues are ReferenceableRanges and do not dangle:\n\tstatic_assert(same_as<subrange<int*>,\n\t\tdecltype(::algorithm(std::declval<int(&)[42]>()))>);\n\tstatic_assert(same_as<subrange<std::vector<int>::iterator>,\n\t\tdecltype(::algorithm(vi))>);\n\n\t// subrange and ref_view are ReferenceableRanges and do not dangle:\n\tstatic_assert(same_as<subrange<int*>,\n\t\tdecltype(::algorithm(std::declval<subrange<int*>>()))>);\n\tstatic_assert(same_as<subrange<int*>,\n\t\tdecltype(::algorithm(std::declval<ref_view<int[42]>>()))>);\n\n\t// non-ReferenceableRange rvalue ranges dangle:\n\tstatic_assert(same_as<dangling,\n\t\tdecltype(::algorithm(std::declval<std::vector<int>>()))>);\n\tstatic_assert(same_as<dangling,\n\t\tdecltype(::algorithm(std::move(vi)))>);\n\n\t// Test that slicing conversions are not allowed.\n\tstatic_assert(constructible_from<subrange<Base*, Base*>, Base*, Base*>);\n\tstatic_assert(!constructible_from<subrange<Base*, Base*>, Derived*, Derived*>);\n\tstatic_assert(constructible_from<subrange<const Base*, const Base*>, Base*, Base*>);\n\tstatic_assert(!constructible_from<subrange<const Base*, const Base*>, Derived*, Derived*>);\n\tstatic_assert(!constructible_from<subrange<Base*, Base*>, subrange<Derived*, Derived*>>);\n\n\tstatic_assert(constructible_from<subrange<Base*, unreachable_sentinel_t>, Base*, unreachable_sentinel_t>);\n\tstatic_assert(!constructible_from<subrange<Base*, unreachable_sentinel_t>, Derived*, unreachable_sentinel_t>);\n\tstatic_assert(constructible_from<subrange<const Base*, unreachable_sentinel_t>, Base*, unreachable_sentinel_t>);\n\tstatic_assert(!constructible_from<subrange<const Base*, unreachable_sentinel_t>, Derived*, unreachable_sentinel_t>);\n\tstatic_assert(!constructible_from<subrange<Base*, unreachable_sentinel_t>, subrange<Derived*, unreachable_sentinel_t>>);\n\n\tstatic_assert(constructible_from<subrange<Base*, unreachable_sentinel_t, subrange_kind::sized>, Base*, unreachable_sentinel_t, std::ptrdiff_t>);\n\tstatic_assert(!constructible_from<subrange<Base*, unreachable_sentinel_t, subrange_kind::sized>, Derived*, unreachable_sentinel_t, std::ptrdiff_t>);\n\tstatic_assert(constructible_from<subrange<const Base*, unreachable_sentinel_t, subrange_kind::sized>, Base*, unreachable_sentinel_t, std::ptrdiff_t>);\n\tstatic_assert(!constructible_from<subrange<const Base*, unreachable_sentinel_t, subrange_kind::sized>, Derived*, unreachable_sentinel_t, std::ptrdiff_t>);\n\tstatic_assert(!constructible_from<subrange<Base*, unreachable_sentinel_t, subrange_kind::sized>, subrange<Derived*, unreachable_sentinel_t>, std::ptrdiff_t>);\n\n\tstatic_assert(convertible_to<subrange<Base*, Base*>, std::pair<const Base*, const Base*>>);\n\tstatic_assert(!convertible_to<subrange<Derived*, Derived*>, std::pair<Base*, Base*>>);\n\n\tsubrange<std::vector<int>::iterator> r0 {vi.begin(), vi.end()};\n\tstatic_assert(std::tuple_size<decltype(r0)>::value == 2);\n\tstatic_assert(same_as<std::vector<int>::iterator,\n\t\tstd::tuple_element<0, decltype(r0)>::type>);\n\tstatic_assert(same_as<std::vector<int>::iterator,\n\t\tstd::tuple_element<1, decltype(r0)>::type>);\n\tstatic_assert(sized_range<decltype(r0)>);\n\tCHECK(r0.size() == 4);\n\tCHECK(r0.begin() == vi.begin());\n\tCHECK(get<0>(r0) == vi.begin());\n\tCHECK(r0.end() == vi.end());\n\tCHECK(get<1>(r0) == vi.end());\n\tr0 = r0.next();\n\tCHECK(r0.size() == 3);\n\n\t{\n\t\tsubrange<std::vector<int>::iterator> rng {vi.begin(), vi.end(), ranges::distance(vi)};\n\t\tCHECK(rng.size() == 4);\n\t\tCHECK(rng.begin() == vi.begin());\n\t\tCHECK(rng.end() == vi.end());\n\t}\n\n\tstd::pair<std::vector<int>::iterator, std::vector<int>::iterator> p0 = r0;\n\tCHECK(p0.first == vi.begin()+1);\n\tCHECK(p0.second == vi.end());\n\n\tsubrange<std::vector<int>::iterator, unreachable_sentinel_t> r1 { r0.begin(), {} };\n\tstatic_assert(std::tuple_size<decltype(r1)>::value == 2);\n\tstatic_assert(same_as<std::vector<int>::iterator,\n\t\tstd::tuple_element<0, decltype(r1)>::type>);\n\tstatic_assert(same_as<unreachable_sentinel_t,\n\t\tstd::tuple_element<1, decltype(r1)>::type>);\n\tstatic_assert(view<decltype(r1)>);\n\tstatic_assert(!sized_range<decltype(r1)>);\n\tCHECK(r1.begin() == vi.begin()+1);\n\tr1.end() = unreachable_sentinel;\n\n\tr0 = r0.next();\n\t++r0.begin();\n\tCHECK(r0.begin() == vi.begin()+2);\n\tCHECK(r0.size() == 2);\n\tr0 = {r0.begin(), --r0.end()}; // --r0.end();\n\tCHECK(r0.end() == vi.end()-1);\n\tCHECK(r0.size() == 1);\n\tCHECK(r0.front() == 3);\n\tCHECK(r0.back() == 3);\n\n\tstd::pair<std::vector<int>::iterator, unreachable_sentinel_t> p1 = r1;\n\tCHECK(p1.first == vi.begin()+1);\n\n\tstd::list<int> li{1,2,3,4};\n\text::sized_subrange<std::list<int>::iterator> l0 {li.begin(), li.end(),\n\t\tstatic_cast<std::ptrdiff_t>(li.size())};\n\tstatic_assert(view<decltype(l0)> && sized_range<decltype(l0)>);\n\tCHECK(l0.begin() == li.begin());\n\tCHECK(l0.end() == li.end());\n\tCHECK(l0.size() == static_cast<std::ptrdiff_t>(li.size()));\n\tl0 = l0.next();\n\tCHECK(l0.begin() == next(li.begin()));\n\tCHECK(l0.end() == li.end());\n\tCHECK(l0.size() == static_cast<std::ptrdiff_t>(li.size()) - 1);\n\n\tl0 = views::all(li);\n\n\tsubrange<std::list<int>::iterator> l1 = l0;\n\tstatic_assert(!sized_range<decltype(l1)>);\n\tCHECK(l1.begin() == li.begin());\n\tCHECK(l1.end() == li.end());\n\n\t{\n\t\tsubrange s0{vi.begin(), vi.end()};\n\t\tsubrange s1{li.begin(), li.end()};\n\t\tstatic_assert(same_as<decltype(r0), decltype(s0)>);\n\t\tstatic_assert(same_as<decltype(l1), decltype(s1)>);\n\t}\n\t{\n\t\tsubrange s0{vi.begin(), vi.end(), ranges::distance(vi)};\n\t\tsubrange s1{li.begin(), li.end(), ranges::distance(li)};\n\t\tstatic_assert(same_as<decltype(r0), decltype(s0)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s1)>);\n\t}\n\t{\n\t\tsubrange s0{vi};\n\t\tsubrange s1{li};\n\t\tsubrange s2{views::all(vi)};\n\t\tsubrange s3{views::all(li)};\n\t\tstatic_assert(same_as<decltype(r0), decltype(s0)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s1)>);\n\t\tstatic_assert(same_as<decltype(r0), decltype(s2)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s3)>);\n\t}\n\t{\n\t\tsubrange s0{r0};\n\t\tsubrange s1{l0};\n\t\tsubrange s2{l1};\n\t\tstatic_assert(same_as<decltype(r0), decltype(s0)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s1)>);\n\t\tstatic_assert(same_as<decltype(l1), decltype(s2)>);\n\t}\n\t{\n\t\tsubrange s0{vi, ranges::distance(vi)};\n\t\tsubrange s1{li, ranges::distance(li)};\n\t\tsubrange s2{views::all(vi), ranges::distance(vi)};\n\t\tsubrange s3{views::all(li), ranges::distance(li)};\n\t\tstatic_assert(same_as<decltype(r0), decltype(s0)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s1)>);\n\t\tstatic_assert(same_as<decltype(r0), decltype(s2)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s3)>);\n\t}\n\t{\n\t\tsubrange s0{r0, size(r0)};\n\t\tsubrange s1{l0, size(l0)};\n\t\tsubrange s2{l1, size(l0)};\n\t\tstatic_assert(same_as<decltype(r0), decltype(s0)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s1)>);\n\t\tstatic_assert(same_as<decltype(l0), decltype(s2)>);\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/take_exactly_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/take_exactly.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/filter.hpp>\n#include <stl2/view/subrange.hpp>\n#include <stl2/detail/iterator/istream_iterator.hpp>\n#include <memory>\n#include <vector>\n#include <sstream>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\ttemplate<class I, class S>\n\tstruct my_subrange : ranges::subrange<I, S> {\n\t\tmy_subrange() = default;\n\t\tmy_subrange(I i, S s)\n\t\t: ranges::subrange<I, S>{i, s} {}\n\t\tI begin() { return this->my_subrange::subrange::begin(); }\n\t\tS end() { return this->my_subrange::subrange::end(); }\n\t};\n}\n\nint main()\n{\n\tusing namespace ranges;\n\n\t{\n\t\tauto rng = views::iota(0) | views::ext::take_exactly(10);\n\t\tstatic_assert(view<decltype(rng)>);\n\t\tstatic_assert(!sized_range<iota_view<int>>);\n\t\tstatic_assert(range<const decltype(rng)>);\n\t\tCHECK_EQUAL(rng, {0,1,2,3,4,5,6,7,8,9});\n\t}\n\n\t{\n\t\tauto rng = views::iota(0, 100) | views::ext::take_exactly(10);\n\t\tstatic_assert(view<decltype(rng)>);\n\t\tstatic_assert(range<const decltype(rng)>);\n\t\tCHECK_EQUAL(rng, {0,1,2,3,4,5,6,7,8,9});\n\t}\n\n\t{\n\t\tauto rng = views::iota(0, 9) | views::ext::take_exactly(10);\n\t\tstatic_assert(view<decltype(rng)>);\n\t\tstatic_assert(range<const decltype(rng)>);\n\t\tCHECK_EQUAL(rng, {0,1,2,3,4,5,6,7,8,9});\n\t}\n\n\t{\n\t\tauto evens = [](int i){return i%2 == 0;};\n\t\tstd::stringstream sin{\"0 1 2 3 4 5 6 7 8 9\"};\n\t\tmy_subrange is{istream_iterator<int>{sin}, istream_iterator<int>{}};\n\t\tstatic_assert(input_range<decltype(is)>);\n\t\tauto rng = is | views::filter(evens) | views::ext::take_exactly(3);\n\t\tstatic_assert(view<decltype(rng)>);\n\t\tstatic_assert(!range<const decltype(rng)>);\n\t\tCHECK_EQUAL(rng, {0,2,4});\n\t}\n\n\t{\n\t\tauto odds = [](int i){return i%2 == 1;};\n\t\tstd::stringstream sin{\"0 1 2 3 4 5 6 7 8 9\"};\n\t\tmy_subrange is{istream_iterator<int>{sin}, istream_iterator<int>{}};\n\t\tauto pipe = views::filter(odds) | views::ext::take_exactly(3);\n\t\tauto rng = is | pipe;\n\t\tstatic_assert(view<decltype(rng)>);\n\t\tstatic_assert(!range<const decltype(rng)>);\n\t\tCHECK_EQUAL(rng, {1,3,5});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/take_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/take.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/filter.hpp>\n#include <stl2/view/subrange.hpp>\n#include <stl2/detail/iterator/istream_iterator.hpp>\n#include <list>\n#include <memory>\n#include <vector>\n#include <sstream>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\ttemplate<class I, class S>\n\tstruct my_subrange : ranges::subrange<I, S> {\n\t\tmy_subrange() = default;\n\t\tmy_subrange(I i, S s)\n\t\t: ranges::subrange<I, S>{i, s} {}\n\t\tI begin() { return this->my_subrange::subrange::begin(); }\n\t\tS end() { return this->my_subrange::subrange::end(); }\n\t};\n}\n\nint main()\n{\n\tusing namespace ranges;\n\n\t{\n\t\tauto rng = views::iota(0) | views::take(10);\n\t\tusing R = decltype(rng);\n\t\tstatic_assert(view<R>);\n\t\tstatic_assert(!sized_range<R>);\n\t\tstatic_assert(!common_range<R>);\n\t\tstatic_assert(random_access_range<R>);\n\t\tstatic_assert(!contiguous_range<R>);\n\t\tstatic_assert(range<const R>);\n\t\tCHECK_EQUAL(rng, {0,1,2,3,4,5,6,7,8,9});\n\t}\n\n\t{\n\t\tauto rng = views::iota(0, 100) | views::take(10);\n\t\tusing R = decltype(rng);\n\t\tstatic_assert(view<R>);\n\t\tstatic_assert(sized_range<R>);\n\t\tstatic_assert(common_range<R>);\n\t\tstatic_assert(random_access_range<R>);\n\t\tstatic_assert(!contiguous_range<R>);\n\t\tstatic_assert(range<const R>);\n\t\tCHECK_EQUAL(rng, {0,1,2,3,4,5,6,7,8,9});\n\t}\n\n\t{\n\t\tauto evens = [](int i) { return i % 2 == 0; };\n\t\tstd::stringstream sin{\"0 1 2 3 4 5 6 7 8 9\"};\n\t\tmy_subrange is{istream_iterator<int>{sin}, istream_iterator<int>{}};\n\t\tstatic_assert(input_range<decltype(is)>);\n\t\tauto rng = is | views::filter(evens) | views::take(3);\n\t\tusing R = decltype(rng);\n\t\tstatic_assert(view<R>);\n\t\tstatic_assert(!sized_range<decltype(rng.base())>);\n\t\tstatic_assert(!sized_range<R>);\n\t\tstatic_assert(!common_range<R>);\n\t\tstatic_assert(input_range<R>);\n\t\tstatic_assert(!forward_range<R>);\n\t\tstatic_assert(!range<const R>);\n\t\tCHECK_EQUAL(rng, {0,2,4});\n\t}\n\n\t{\n\t\tauto odds = [](int i) { return i % 2 == 1; };\n\t\tstd::stringstream sin{\"0 1 2 3 4 5 6 7 8 9\"};\n\t\tmy_subrange is{istream_iterator<int>{sin}, istream_iterator<int>{}};\n\t\tauto pipe = views::filter(odds) | views::take(3);\n\t\tauto rng = is | pipe;\n\t\tusing R = decltype(rng);\n\t\tstatic_assert(view<R>);\n\t\tstatic_assert(!sized_range<decltype(rng.base())>);\n\t\tstatic_assert(!sized_range<R>);\n\t\tstatic_assert(!common_range<R>);\n\t\tstatic_assert(input_range<R>);\n\t\tstatic_assert(!forward_range<R>);\n\t\tstatic_assert(!range<const R>);\n\t\tCHECK_EQUAL(rng, {1,3,5});\n\t}\n\n\t{\n\t\tint some_ints[] = {1,2,3};\n\t\ttake_view{some_ints, 2};\n\t}\n\n\t{\n\t\tstd::list<int> l{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\t\tauto rng = l | views::take(6);\n\t\tstatic_assert(ranges::view<decltype(rng)>);\n\t\tstatic_assert(ranges::sized_range<decltype(rng)>);\n\t\tstatic_assert(ranges::bidirectional_iterator<decltype(ranges::begin(rng))>);\n\t\tCHECK_EQUAL(rng, {0, 1, 2, 3, 4, 5});\n\t}\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/take_while_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter\n//  Copyright Eric Niebler\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/take_while.hpp>\n#include <stl2/view/iota.hpp>\n#include <list>\n#include <vector>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\nnamespace views = ranges::views;\n\nint main()\n{\n\tauto rng0 = views::iota(10) | views::take_while([](int i) { return i != 25; });\n\tCHECK_EQUAL(rng0, {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24});\n\tstatic_assert(ranges::view<decltype(rng0)>);\n\tstatic_assert(!ranges::common_range<decltype(rng0)>);\n\tstatic_assert(ranges::random_access_iterator<decltype(rng0.begin())>);\n\n\tstd::vector<int> vi{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};\n\tauto rng1 = vi | views::take_while([](int i) { return i != 50; });\n\tstatic_assert(ranges::random_access_range<decltype(rng1)>);\n\tCHECK_EQUAL(rng1, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9});\n\n#if 0 // DISABLED until generate is migrated to cmcstl2.\n\t{\n\t\tauto ns = views::generate([]() mutable {\n\t\t\tstatic int N;\n\t\t\treturn ++N;\n\t\t});\n\t\tauto rng = ns | views::take_while([](int i) { return i < 5; });\n\t\tCHECK_EQUAL(rng, {1,2,3,4});\n\t}\n#endif\n\n\treturn ::test_result();\n}\n"
  },
  {
    "path": "test/view/transform_view.cpp",
    "content": "// cmcstl2 - A concept-enabled C++ standard library\n//\n//  Copyright Casey Carter 2016\n//\n//  Use, modification and distribution is subject to the\n//  Boost Software License, Version 1.0. (See accompanying\n//  file LICENSE_1_0.txt or copy at\n//  http://www.boost.org/LICENSE_1_0.txt)\n//\n// Project home: https://github.com/caseycarter/cmcstl2\n//\n#include <stl2/view/transform.hpp>\n\n#include <memory>\n#include <vector>\n\n#include <stl2/detail/algorithm/count.hpp>\n#include <stl2/detail/algorithm/transform.hpp>\n#include <stl2/detail/iterator/insert_iterators.hpp>\n#include <stl2/view/filter.hpp>\n#include <stl2/view/iota.hpp>\n#include <stl2/view/reverse.hpp>\n#include \"../simple_test.hpp\"\n\nnamespace ranges = __stl2;\n\nnamespace {\n\tstruct is_odd {\n\t\tbool operator()(int i) const {\n\t\t\treturn (i % 2) == 1;\n\t\t}\n\t};\n}\n\nint main() {\n\tusing namespace ranges;\n\n\tint rgi[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};\n\n\tauto rng = rgi | views::transform(is_odd());\n\tstatic_assert(same_as<int &, decltype(*begin(rgi))>);\n\tstatic_assert(same_as<bool, decltype(*begin(rng))>);\n\tstatic_assert(view<decltype(rng)>);\n\tstatic_assert(sized_range<decltype(rng)>);\n\tstatic_assert(random_access_range<decltype(rng)>);\n\tCHECK_EQUAL(rng, {true, false, true, false, true, false, true, false, true, false});\n\n\tstd::pair<int, int> rgp[] = {{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}, {8,8}, {9,9}, {10,10}};\n\tauto rng2 = rgp | views::transform(&std::pair<int,int>::first);\n\tstatic_assert(same_as<int &, decltype(*begin(rng2))>);\n\tstatic_assert(same_as<iter_value_t<iterator_t<decltype(rng2)>>, int>);\n\tstatic_assert(same_as<decltype(iter_move(begin(rng2))), int &&>);\n\tstatic_assert(view<decltype(rng2)>);\n\tstatic_assert(common_range<decltype(rng2)>);\n\tstatic_assert(sized_range<decltype(rng2)>);\n\tstatic_assert(random_access_range<decltype(rng2)>);\n\tCHECK(&*begin(rng2) == &rgp[0].first);\n\tCHECK(rng2.size() == 10u);\n\tCHECK_EQUAL(rng2, {1,2,3,4,5,6,7,8,9,10});\n\tCHECK_EQUAL(rng2 | views::reverse, {10,9,8,7,6,5,4,3,2,1});\n\n\t// https://github.com/CaseyCarter/cmcstl2/issues/262\n\t{\n\t\tauto id = [](int x){ return x; };\n\t\tviews::iota(0) | views::filter(id) | views::transform(id);\n\t}\n\n\treturn ::test_result();\n}\n"
  }
]