pax_global_header00006660000000000000000000000064135712372360014523gustar00rootroot0000000000000052 comment=299aa51954aa9602f4ff66392953f93979487035 xtl-0.6.9/000077500000000000000000000000001357123723600123465ustar00rootroot00000000000000xtl-0.6.9/.appveyor.yml000066400000000000000000000017631357123723600150230ustar00rootroot00000000000000build: false os: Visual Studio 2015 platform: - x64 environment: matrix: - MINICONDA: C:\xtl-conda init: - "ECHO %MINICONDA%" - C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\VC\vcvarsall.bat %PLATFORM% - ps: if($env:Platform -eq "x64"){Start-FileDownload 'http://repo.continuum.io/miniconda/Miniconda3-latest-Windows-x86_64.exe' C:\Miniconda.exe; echo "Done"} - ps: if($env:Platform -eq "x86"){Start-FileDownload 'http://repo.continuum.io/miniconda/Miniconda3-latest-Windows-x86.exe' C:\Miniconda.exe; echo "Done"} - cmd: C:\Miniconda.exe /S /D=C:\xtl-conda - "set PATH=%MINICONDA%;%MINICONDA%\\Scripts;%MINICONDA%\\Library\\bin;%PATH%" install: - conda config --set always_yes yes --set changeps1 no - conda update -q conda - conda info -a - conda install gtest cmake nlohmann_json -c QuantStack -c conda-forge - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\LIBRARY -DBUILD_TESTS=ON . - nmake test_xtl - cd test build_script: - .\test_xtl xtl-0.6.9/.gitignore000066400000000000000000000010301357123723600143300ustar00rootroot00000000000000# Prerequisites *.d # Compiled Object files *.slo *.lo *.o *.obj # Precompiled Headers *.gch *.pch # Compiled Dynamic libraries *.so *.dylib *.dll # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app # Vim tmp files *.swp # Build directory build/ # Test build artefacts test/test_xtl test/CMakeCache.txt test/Makefile test/CMakeFiles/ test/cmake_install.cmake # Documentation build artefacts docs/CMakeCache.txt docs/xml/ docs/build/ # Jupyter artefacts .ipynb_checkpoints/ # Generated files *.pc xtl-0.6.9/.releash.py000066400000000000000000000013051357123723600144200ustar00rootroot00000000000000from releash import * gitpush = ReleaseTargetGitPush('upstream', 'master') xtl = add_package(path=".", name="xtl") version_xtl = VersionSourceAndTargetHpp(xtl, '{path}/include/xtl/xtl_config.hpp', prefix='XTL_VERSION_') gittag_xtl = ReleaseTargetGitTagVersion(version_source=version_xtl, prefix='', annotate=True) xtl.version_source = version_xtl xtl.version_targets.append(version_xtl) xtl.release_targets.append(gittag_xtl) xtl.release_targets.append(gitpush) source_tarball_filename = 'https://github.com/QuantStack/xtl/archive/{version}.tar.gz'.format(version=version_xtl) xtl.release_targets.append(ReleaseTargetCondaForge(xtl, '../xtl-feedstock', source_tarball_filename=source_tarball_filename)) xtl-0.6.9/.travis.yml000066400000000000000000000057601357123723600144670ustar00rootroot00000000000000language: cpp dist: trusty matrix: include: - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-4.9 env: COMPILER=gcc GCC=4.9 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-5 env: COMPILER=gcc GCC=5 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-6 env: COMPILER=gcc GCC=6 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-4.9 - clang-3.6 env: COMPILER=clang CLANG=3.6 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-3.9 packages: - g++-4.9 - clang-3.9 env: COMPILER=clang CLANG=3.9 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-4.0 packages: - g++-4.9 - clang-4.0 env: COMPILER=clang CLANG=4.0 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-5.0 packages: - g++-4.9 - clang-5.0 env: COMPILER=clang CLANG=5.0 - os: linux addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-6.0 packages: - clang-6.0 env: COMPILER=clang CLANG=6.0 - os: osx osx_image: xcode8 compiler: clang env: global: - MINCONDA_VERSION="latest" - MINCONDA_LINUX="Linux-x86_64" - MINCONDA_OSX="MacOSX-x86_64" before_install: - | # Configure build variables if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then if [[ "$COMPILER" == "gcc" ]]; then export CXX=g++-$GCC CC=gcc-$GCC; fi if [[ "$COMPILER" == "clang" ]]; then export CXX=clang++-$CLANG CC=clang-$CLANG; fi elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CXX=clang++ CC=clang; fi install: # Define the version of miniconda to download - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then MINCONDA_OS=$MINCONDA_LINUX; elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then MINCONDA_OS=$MINCONDA_OSX; fi - wget "http://repo.continuum.io/miniconda/Miniconda3-$MINCONDA_VERSION-$MINCONDA_OS.sh" -O miniconda.sh; - bash miniconda.sh -b -p $HOME/miniconda - export PATH="$HOME/miniconda/bin:$PATH" - hash -r - conda config --set always_yes yes --set changeps1 no - conda update -q conda - conda install cmake nlohmann_json -c QuantStack -c conda-forge # Testing - mkdir build - cd build - cmake -DDOWNLOAD_GTEST=ON ..; - make -j2 test_xtl - cd test script: - ./test_xtl xtl-0.6.9/CMakeLists.txt000066400000000000000000000115501357123723600151100ustar00rootroot00000000000000############################################################################ # Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht # # Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # # The full license is in the file LICENSE, distributed with this software. # ############################################################################ cmake_minimum_required(VERSION 3.1) project(xtl) enable_testing() set(XTL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) # Versioning # =========== file(STRINGS "${XTL_INCLUDE_DIR}/xtl/xtl_config.hpp" xtl_version_defines REGEX "#define XTL_VERSION_(MAJOR|MINOR|PATCH)") foreach(ver ${xtl_version_defines}) if(ver MATCHES "#define XTL_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$") set(XTL_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "") endif() endforeach() set(${PROJECT_NAME}_VERSION ${XTL_VERSION_MAJOR}.${XTL_VERSION_MINOR}.${XTL_VERSION_PATCH}) message(STATUS "xtl v${${PROJECT_NAME}_VERSION}") # Dependencies # ============ find_package(nlohmann_json QUIET) # Build # ===== set(XTL_HEADERS ${XTL_INCLUDE_DIR}/xtl/xany.hpp ${XTL_INCLUDE_DIR}/xtl/xbasic_fixed_string.hpp ${XTL_INCLUDE_DIR}/xtl/xbase64.hpp ${XTL_INCLUDE_DIR}/xtl/xclosure.hpp ${XTL_INCLUDE_DIR}/xtl/xcomplex.hpp ${XTL_INCLUDE_DIR}/xtl/xcomplex_sequence.hpp ${XTL_INCLUDE_DIR}/xtl/xspan.hpp ${XTL_INCLUDE_DIR}/xtl/xspan_impl.hpp ${XTL_INCLUDE_DIR}/xtl/xdynamic_bitset.hpp ${XTL_INCLUDE_DIR}/xtl/xfunctional.hpp ${XTL_INCLUDE_DIR}/xtl/xhash.hpp ${XTL_INCLUDE_DIR}/xtl/xhierarchy_generator.hpp ${XTL_INCLUDE_DIR}/xtl/xiterator_base.hpp ${XTL_INCLUDE_DIR}/xtl/xjson.hpp ${XTL_INCLUDE_DIR}/xtl/xmasked_value_meta.hpp ${XTL_INCLUDE_DIR}/xtl/xmasked_value.hpp ${XTL_INCLUDE_DIR}/xtl/xmeta_utils.hpp ${XTL_INCLUDE_DIR}/xtl/xoptional_meta.hpp ${XTL_INCLUDE_DIR}/xtl/xoptional.hpp ${XTL_INCLUDE_DIR}/xtl/xoptional_sequence.hpp ${XTL_INCLUDE_DIR}/xtl/xproxy_wrapper.hpp ${XTL_INCLUDE_DIR}/xtl/xsequence.hpp ${XTL_INCLUDE_DIR}/xtl/xtl_config.hpp ${XTL_INCLUDE_DIR}/xtl/xtype_traits.hpp ${XTL_INCLUDE_DIR}/xtl/xvariant.hpp ${XTL_INCLUDE_DIR}/xtl/xvariant_impl.hpp ) add_library(xtl INTERFACE) target_include_directories(xtl INTERFACE $ $) # xtl requires C++14 support! target_compile_features(xtl INTERFACE cxx_std_14) option(BUILD_TESTS "xtl test suite" OFF) option(DOWNLOAD_GTEST "build gtest from downloaded sources" OFF) option(XTL_DISABLE_EXCEPTIONS "Disable C++ exceptions" OFF) if(DOWNLOAD_GTEST OR GTEST_SRC_DIR) set(BUILD_TESTS ON) endif() if(BUILD_TESTS) add_subdirectory(test) endif() # Installation # ============ include(GNUInstallDirs) include(CMakePackageConfigHelpers) install(TARGETS xtl EXPORT ${PROJECT_NAME}-targets) # Makes the project importable from the build directory export(EXPORT ${PROJECT_NAME}-targets FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") install(FILES ${XTL_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/xtl) set(XTL_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE STRING "install path for xtlConfig.cmake") configure_package_config_file(${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" INSTALL_DESTINATION ${XTL_CMAKECONFIG_INSTALL_DIR}) # xtl is header-only and does not depend on the architecture. # Remove CMAKE_SIZEOF_VOID_P from xtlConfigVersion.cmake so that an xtlConfig.cmake # generated for a 64 bit target can be used for 32 bit targets and vice versa. set(_XTL_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) unset(CMAKE_SIZEOF_VOID_P) write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${${PROJECT_NAME}_VERSION} COMPATIBILITY AnyNewerVersion) set(CMAKE_SIZEOF_VOID_P ${_XTL_CMAKE_SIZEOF_VOID_P}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake DESTINATION ${XTL_CMAKECONFIG_INSTALL_DIR}) install(EXPORT ${PROJECT_NAME}-targets FILE ${PROJECT_NAME}Targets.cmake DESTINATION ${XTL_CMAKECONFIG_INSTALL_DIR}) configure_file(${PROJECT_NAME}.pc.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/") xtl-0.6.9/LICENSE000066400000000000000000000030541357123723600133550ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2017, Sylvain Corlay, Johan Mabille and Wolf Vollprecht Copyright (c) 2017, QuantStack All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. xtl-0.6.9/README.md000066400000000000000000000046101357123723600136260ustar00rootroot00000000000000# ![xtl](docs/source/xtl.svg) [![Travis](https://travis-ci.org/xtensor-stack/xtl.svg?branch=master)](https://travis-ci.org/xtensor-stack/xtl) [![Appveyor](https://ci.appveyor.com/api/projects/status/wikc50xlb5rbrjy7?svg=true)](https://ci.appveyor.com/project/xtensor-stack/xtl) [![Azure](https://dev.azure.com/xtensor-stack/xtensor-stack/_apis/build/status/xtensor-stack.xtl?branchName=master)](https://dev.azure.com/xtensor-stack/xtensor-stack/_build/latest?definitionId=2&branchName=master) [![Documentation Status](http://readthedocs.org/projects/xtl/badge/?version=latest)](https://xtl.readthedocs.io/en/latest/?badge=latest) [![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantStack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Basic tools (containers, algorithms) used by other quantstack packages ## Installation ### Package managers We provide a package for the conda package manager: ```bash conda install -c conda-forge xtl ``` If you are using Conan to manage your dependencies, merely add `xtl/x.y.z@omaralvarez/public-conan` to your requires, where x.y.z is the release version you want to use. Please file issues in [conan-xtl](https://github.com/omaralvarez/conan-xtl) if you experience problems with the packages. Sample `conanfile.txt`: ``` [requires] xtl/0.6.5@omaralvarez/public-conan [generators] cmake ``` ### Install from sources `xtl` is a header-only library. You can directly install it from the sources: ```bash cmake -D CMAKE_INSTALL_PREFIX=your_install_prefix make install ``` ## Documentation To get started with using `xtl`, check out the full documentation http://xtl.readthedocs.io/ ## Building the HTML documentation xtl's documentation is built with three tools - [doxygen](http://www.doxygen.org) - [sphinx](http://www.sphinx-doc.org) - [breathe](https://breathe.readthedocs.io) While doxygen must be installed separately, you can install breathe by typing ```bash pip install breathe ``` Breathe can also be installed with `conda` ```bash conda install -c conda-forge breathe ``` Finally, build the documentation with ```bash make html ``` from the `docs` subdirectory. ## License We use a shared copyright model that enables all contributors to maintain the copyright on their contributions. This software is licensed under the BSD-3-Clause license. See the [LICENSE](LICENSE) file for details. xtl-0.6.9/azure-pipelines.yml000066400000000000000000000056541357123723600162170ustar00rootroot00000000000000trigger: - master jobs: # Configure, build, install, and test job - job: 'build' pool: vmImage: 'vs2015-win2012r2' timeoutInMinutes: 360 steps: # Install Chocolatey (https://chocolatey.org/install#install-with-powershellexe) - powershell: | Set-ExecutionPolicy Bypass -Scope Process -Force iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) Write-Host "##vso[task.setvariable variable=PATH]$env:PATH" choco --version displayName: "Install Chocolatey" # Install Miniconda - script: | choco install miniconda3 --yes set PATH=C:\tools\miniconda3\Scripts;C:\tools\miniconda3;C:\tools\miniconda3\Library\bin;%PATH% echo '##vso[task.setvariable variable=PATH]%PATH%' set LIB=C:\tools\miniconda3\Library\lib;%LIB% echo '##vso[task.setvariable variable=LIB]%LIB%' conda --version displayName: "Install Miniconda" # Configure Miniconda - script: | conda config --set always_yes yes conda config --append channels conda-forge conda info displayName: "Configure Miniconda" # Create conda enviroment # Note: conda activate doesn't work here, because it creates a new shell! - script: | conda install cmake ^ gtest ^ ninja ^ nlohmann_json ^ python=3.6 conda list displayName: "Install conda packages" # Install LLVM # Note: LLVM distributed by conda is too old - script: | choco install llvm --yes set PATH=C:\Program Files\LLVM\bin;%PATH% echo '##vso[task.setvariable variable=PATH]%PATH%' clang-cl --version displayName: "Install LLVM" # Configure - script: | setlocal EnableDelayedExpansion call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 mkdir build & cd build cmake -G Ninja ^ -DCMAKE_BUILD_TYPE=Release ^ -DCMAKE_C_COMPILER=clang-cl ^ -DCMAKE_CXX_COMPILER=clang-cl ^ -DBUILD_TESTS=ON ^ $(Build.SourcesDirectory) displayName: "Configure xtl" workingDirectory: $(Build.BinariesDirectory) # Build - script: | call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 cmake --build . ^ --config Release ^ --target test_xtl ^ -- -v displayName: "Build xtl" workingDirectory: $(Build.BinariesDirectory)/build # Test - script: | setlocal EnableDelayedExpansion cd test .\test_xtl displayName: "Test xtl" workingDirectory: $(Build.BinariesDirectory)/build/test xtl-0.6.9/docs/000077500000000000000000000000001357123723600132765ustar00rootroot00000000000000xtl-0.6.9/docs/Doxyfile000066400000000000000000000004761357123723600150130ustar00rootroot00000000000000PROJECT_NAME = "xtl" XML_OUTPUT = xml INPUT = ../include GENERATE_LATEX = NO GENERATE_MAN = NO GENERATE_RTF = NO CASE_SENSE_NAMES = NO GENERATE_HTML = NO GENERATE_XML = YES RECURSIVE = YES QUIET = YES JAVADOC_AUTOBRIEF = YES WARN_IF_UNDOCUMENTED = NO xtl-0.6.9/docs/Makefile000066400000000000000000000152501357123723600147410ustar00rootroot00000000000000# You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build INKSCAPE = inkscape SED = sed PAPER = BUILDDIR = build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext api default: html help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* rm -rf xml html: doxygen $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: doxygen $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: doxygen $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: doxygen $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: doxygen $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: doxygen $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." epub: doxygen $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." tex-generation: doxygen $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex ${SED} -i.old -e 's/{\([^}]*\)}.svg/\1-svg.pdf/' $(BUILDDIR)/latex/xtl.tex (cd $(BUILDDIR)/latex/;\ for i in *.svg; do\ name=`basename $$i .svg`;\ ${INKSCAPE} -D -z --file=$$i --export-pdf=$$name-svg.pdf --export-latex; \ done) latex: tex-generation @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: tex-generation @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: tex-generation @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: doxygen $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: doxygen $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: doxygen $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: doxygen $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: doxygen $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: doxygen $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: doxygen $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: doxygen $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." coverage: doxygen $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." xml: doxygen $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: doxygen $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." xtl-0.6.9/docs/environment.yml000066400000000000000000000001051357123723600163610ustar00rootroot00000000000000name: xtl-docs channels: - conda-forge dependencies: - breathe xtl-0.6.9/docs/make.bat000066400000000000000000000161651357123723600147140ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source set I18NSPHINXOPTS=%SPHINXOPTS% source if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled echo. coverage to run coverage check of the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) REM Check if sphinx-build is available and fallback to Python version if any %SPHINXBUILD% 1>NUL 2>NUL if errorlevel 9009 goto sphinx_python goto sphinx_ok :sphinx_python set SPHINXBUILD=python -m sphinx.__init__ %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) :sphinx_ok if "%1" == "html" ( doxygen %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\packagename.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\packagename.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "coverage" ( %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage if errorlevel 1 exit /b 1 echo. echo.Testing of coverage in the sources finished, look at the ^ results in %BUILDDIR%/coverage/python.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end xtl-0.6.9/docs/source/000077500000000000000000000000001357123723600145765ustar00rootroot00000000000000xtl-0.6.9/docs/source/_static/000077500000000000000000000000001357123723600162245ustar00rootroot00000000000000xtl-0.6.9/docs/source/_static/main_stylesheet.css000066400000000000000000000000741357123723600221340ustar00rootroot00000000000000.wy-nav-content{ max-width: 1000px; margin: auto; } xtl-0.6.9/docs/source/build-options.rst000066400000000000000000000021461357123723600201230ustar00rootroot00000000000000.. Copyright (c) 2017, Johan Mabille and Sylvain Corlay Distributed under the terms of the BSD 3-Clause License. The full license is in the file LICENSE, distributed with this software. Build and configuration ======================= Build ----- ``xtl`` build supports the following options: - ``BUILD_TESTS``: enables the ``xtest`` target (see below). - ``DOWNLOAD_GTEST``: downloads ``gtest`` and builds it locally instead of using a binary installation. - ``GTEST_SRC_DIR``: indicates where to find the ``gtest`` sources instead of downloading them. - ``XTL_DISABLE_EXCEPTIONS``: indicates that tests should be run with exceptions disabled. All these options are disabled by default. Enabling ``DOWNLOAD_GTEST`` or setting ``GTEST_SRC_DIR`` enables ``BUILD_TESTS``. If the ``BUILD_TESTS`` option is enabled, the following target is available: - xtest: builds an run the test suite. For instance, building the test suite of ``xtl`` where the sources of ``gtest`` are located in e.g. ``/usr/share/gtest``: .. code:: mkdir build cd build cmake -DGTEST_SRC_DIR=/usr/share/gtest ../ make xtest xtl-0.6.9/docs/source/changelog.rst000066400000000000000000000131341357123723600172610ustar00rootroot00000000000000.. Copyright (c) 2017, Johan Mabille and Sylvain Corlay Distributed under the terms of the BSD 3-Clause License. The full license is in the file LICENSE, distributed with this software. Changelog ========= 0.6.9 ----- - Implemented stepping iterators 0.6.8 ----- - Fixed murmur implementation for x86 platform 0.6.7 ----- - Specialized ``promote_type`` for ``std::complex`` 0.6.6 ----- - Fixed ``promote_type`` for ``std::chrono::time_point`` - Update README for Conan installation instructions 0.6.5 ----- - Add supports for clang-cl compiler - Fix cmake command - Fix compiler error with clang-cl compiler 0.6.4 ----- - Fixed forward type 0.6.3 ----- - Fix constness issue in xtl's implementation of std::any. 0.6.2 ----- - Allows xtl to build with -fno-exceptions - Added ``constify`` and ``constify_t`` - Added ``size_t`` overloads for random access iterators 0.6.1 ----- - Latex does not know how to include svg - Added ``XTL_REQUIRES_IMPL`` macro - Removed warnings 0.6.0 ----- - Standalone build of xtl tests - Moved ``xmasked_value`` from `xtensor` - Moved ``promote_type`` from `xtensor` - Disabled ``xoptional`` methods for ``xmasked_value`` - Implemented ``select`` - ``make_sequence`` from ``initializer_list`` 0.5.4 ----- - Implementation of mpl::unique - Prevent installation of gtest artifact 0.5.3 ----- - upgraded to mpark/variant 1.4.0 - implemented concepts - implemented split of type lists 0.5.2 ----- - fixed C++11 compatibility in xjson.hpp 0.5.1 ----- - reverse order of initialization of optional - fixup mime type rendering of fixed string - closure wrapper assignment fixed 0.5.0 ----- - Serialization and deserialization of fixed strings - Inequality comparisons removed from bidirectional iterator base - Simplified forward sequence - Fixed forward sequence - Removed warnings - const reference getter for variant holding non const references - xget on rvalue fixed - Added storage option to fixed string - Added missing entries of header files in CMakeLists.txt - Refactored xdynamic_bitset - Fixed forwrad sequence for non resizable types - Removed meta pop-back 0.4.16 ------ - meta find_if implementation - Enable CTest and CMake cleanup - Make nlohmann_json optional in the tests, exported C++14 requirements 0.4.15 ------ - Value types in const closures are not const qualified anymore, to allow move - Added third template parameter to forward_sequence that allows for true forwarding of sequences 0.4.14 ------ - Fixed typo in 'xtl.pc.in' - Removed -march=native from systems that do not support in CMakeLists - Added hash.verification result for big-endian systemss - Fixed common_optional_impl - Implemented xeus-cling mime_bundle_repr for xoptional, xcomplex and xfixed_string 0.4.13 ------ - CMake call to find_package with nlohmann_json is QUIET - Fix typo in xoptional swap - Added pkgconfig support 0.4.12 ------ - operator overload fixes for xcomplex 0.4.11 ------ - add missing `` header in xcomplex - fix xcomplex isnan test 0.4.10 ------ - `xcomplex` implementation - `xcomplex_sequence` implementation 0.4.9 ----- - return type of `static_if` fixed 0.4.8 ----- - support for JSON serialization of xoptionals 0.4.7 ----- - support for uninitialized `make_sequence` 0.4.6 ----- - remove an unused file. - support for overloaded lambdas 0.4.5 ----- - xget for variant on xclosure_wrapper 0.4.4 ----- - bug fix in any - hierarchy generators 0.4.3 ----- - missing near integers functions for `xoptional` - `xoptional` compilation issue fixed 0.4.2 ----- - added missing operators for xoptional - removed compiler warning if cpp_exceptions already defined 0.4.1 ----- - Bug fix in move semantics for xoptional free functions (`value` and `has_value`) - Use `static_if` instead of regular `if` to remove gcc-6 warning. - Document installation with the Spack package manager. - Fix complex operators with closure wrappers. - Integrate upstream fix for the variant implementation. 0.4.0 ----- - Migration to modern target-based cmake 0.3.9 ----- - Bug fix in the computing of hashes for 32 bit platforms - Fixing warnings 0.3.8 ----- - Improvements and fixes in base iterators (common iterator tag) 0.3.7 ----- - Fixes in `xoptional`. 0.3.6 ----- - Addition of base iterators for linear containers, and associative containers. 0.3.5 ----- - Addition of `value` and `has_value` free functions. - Bug fix in comparison operator for `xclosure_wrapper`. 0.3.4 ----- - Better semantics for assignment operators in `xoptional`. - Addition of `static_if` in `xtl::mpl`. - Addition of `xtl::identity` functor in xfunctional. 0.3.3 ----- - Work around Visual Studio compiler bug in `xoptional_proxy`. 0.3.2 ----- - Improvement of xoptional value semantics (explicit constructors when underlying value type not implicitely constructable) 0.3.1 ----- - Fixes in closure wrapper semantics 0.3.0 ----- - Improve optional sequence - Use dynamic bitset in optional vector - Added base64encode and base64decode 0.2.11 ------ - Added dynamic bitset 0.2.10 ------ - Added meta programming tools 0.2.9 ----- - Added variant implementation 0.2.8 ----- - Added proxy wrapper for pointer semantics. 0.2.7 ----- - Added implementation for closure pointer 0.2.6 ----- - Added base class for random access iterators 0.2.5 ----- - Added closure wrappers 0.2.4 ----- - Added implementation of std::any 0.2.3 ----- - Fixed bug in fixed-size string hashing 0.2.2 ----- - Added the hashing of fixed-size strings 0.2.1 ----- - Fixed-size strings - Fixup issue with ambiguous overload of operator<< 0.2.0 ----- - Moving features from xtensor (xcomplex, xoptional, xsequence, xtypetraits) xtl-0.6.9/docs/source/cmake.svg000066400000000000000000000425311357123723600164040ustar00rootroot00000000000000 image/svg+xml xtl-0.6.9/docs/source/conda.svg000066400000000000000000000034151357123723600164060ustar00rootroot00000000000000xtl-0.6.9/docs/source/conf.py000066400000000000000000000014751357123723600161040ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import subprocess on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if on_rtd: subprocess.call('cd ..; doxygen', shell=True) import sphinx_rtd_theme html_theme = "sphinx_rtd_theme" html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] def setup(app): app.add_stylesheet("main_stylesheet.css") extensions = ['breathe'] breathe_projects = { 'xtl': '../xml' } templates_path = ['_templates'] html_static_path = ['_static'] source_suffix = '.rst' master_doc = 'index' project = 'xtl' copyright = '2017, Johan Mabille and Sylvain Corlay' author = 'Johan Mabille and Sylvain Corlay' html_logo = 'quantstack-white.svg' exclude_patterns = [] highlight_language = 'c++' pygments_style = 'sphinx' todo_include_todos = False htmlhelp_basename = 'xtldoc' xtl-0.6.9/docs/source/debian.svg000066400000000000000000000153171357123723600165500ustar00rootroot00000000000000 ]> xtl-0.6.9/docs/source/index.rst000066400000000000000000000012551357123723600164420ustar00rootroot00000000000000.. Copyright (c) 2017, Johan Mabille and Sylvain Corlay Distributed under the terms of the BSD 3-Clause License. The full license is in the file LICENSE, distributed with this software. .. image:: xtl.svg :alt: xtl Basic tools (containers, algorithms) used by other quantstack packages Licensing --------- We use a shared copyright model that enables all contributors to maintain the copyright on their contributions. This software is licensed under the BSD-3-Clause license. See the LICENSE file for details. .. toctree:: :caption: INSTALLATION :maxdepth: 2 installation changelog .. toctree:: :caption: DEVELOPER ZONE build-options releasing xtl-0.6.9/docs/source/installation.rst000066400000000000000000000032521357123723600200330ustar00rootroot00000000000000.. Copyright (c) 2017, Johan Mabille and Sylvain Corlay Distributed under the terms of the BSD 3-Clause License. The full license is in the file LICENSE, distributed with this software. .. raw:: html Installation ============ Although ``xtl`` is a header-only library, we provide standardized means to install it, with package managers or with cmake. Besides the xtl headers, all these methods place the ``cmake`` project configuration file in the right location so that third-party projects can use cmake's ``find_package`` to locate xtl headers. .. image:: conda.svg Using the conda package ----------------------- A package for xtl is available on the conda package manager. .. code:: conda install -c conda-forge xtl .. image:: spack.svg Using the Spack package ----------------------- A package for xtl is available on the Spack package manager. .. code:: spack install xtl spack load xtl .. image:: cmake.svg From source with cmake ---------------------- You can also install ``xtl`` from source with cmake. On Unix platforms, from the source directory: .. code:: mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX=/path/to/prefix .. make install On Windows platforms, from the source directory: .. code:: mkdir build cd build cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=/path/to/prefix .. nmake nmake install See the section of the documentation on :doc:`build-options`, for more details on how to cmake options. xtl-0.6.9/docs/source/quantstack-white.svg000066400000000000000000000116361357123723600206220ustar00rootroot00000000000000 image/svg+xmlxtl-0.6.9/docs/source/releasing.rst000066400000000000000000000024761357123723600173120ustar00rootroot00000000000000.. Copyright (c) 2017, Johan Mabille and Sylvain Corlay Distributed under the terms of the BSD 3-Clause License. The full license is in the file LICENSE, distributed with this software. Releasing xtl ============= Releasing a new version ----------------------- From the relevant branch of xtl - Make sure that you are in sync with the master branch of the upstream remote. - In file ``xtl_config.hpp``, set the macros for ``XTL_VERSION_MAJOR``, ``XTL_VERSION_MINOR`` and ``XTL_VERSION_PATCH`` to the desired values. - In file ``README.md``, modify the binder link to point to the new release. - Stage the changes (``git add``), commit the changes (``git commit``) and add a tag of the form ``Major.minor.patch``. It is important to not add any other content to the tag name. - Push the new commit and tag to the main repository. (``git push``, and ``git push --tags``) Updating the conda-forge recipe ------------------------------- xtl has been packaged for the conda package manager. Once the new tag has been pushed on GitHub, edit the conda-forge recipe for xtl in the following fashion: - Update the version number to the new ``Major.minor.patch``. - Set the build number to ``0``. - Update the hash of the source tarball. - Check for the versions of the dependencies. - Optionally, rerender the conda-forge feedstock. xtl-0.6.9/docs/source/spack.svg000066400000000000000000000046711357123723600164300ustar00rootroot00000000000000 xtl-0.6.9/docs/source/xtl.svg000066400000000000000000000106311357123723600161270ustar00rootroot00000000000000 image/svg+xml xtl-0.6.9/include/000077500000000000000000000000001357123723600137715ustar00rootroot00000000000000xtl-0.6.9/include/xtl/000077500000000000000000000000001357123723600146005ustar00rootroot00000000000000xtl-0.6.9/include/xtl/xany.hpp000066400000000000000000000412671357123723600163020ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Sylvain Corlay and Johan Mabille and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_ANY_HPP #define XTL_ANY_HPP #include #include #include #include "xtl/xmeta_utils.hpp" namespace xtl { /************************************** * Implementation of C++17's std::any * **************************************/ // Copyright (c) 2016 Denilson das Mercês Amorim // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) class bad_any_cast : public std::bad_cast { public: const char* what() const noexcept override { return "bad any cast"; } }; namespace detail { inline static void check_any_cast(const void* p) { if (p == nullptr) { #if defined(XTL_NO_EXCEPTIONS) std::fprintf(stderr, "bad_any_cast\n"); std::terminate(); #else throw bad_any_cast(); #endif } } } // namespace detail class any final { public: /// Constructs an object of type any with an empty state. any() : vtable(nullptr) { } /// Constructs an object of type any with an equivalent state as other. any(const any& rhs) : vtable(rhs.vtable) { if (!rhs.empty()) { rhs.vtable->copy(rhs.storage, this->storage); } } /// Constructs an object of type any with a state equivalent to the original state of other. /// rhs is left in a valid but otherwise unspecified state. any(any&& rhs) noexcept : vtable(rhs.vtable) { if (!rhs.empty()) { rhs.vtable->move(rhs.storage, this->storage); rhs.vtable = nullptr; } } /// Same effect as this->clear(). ~any() { this->clear(); } /// Constructs an object of type any that contains an object of type T direct-initialized with std::forward(value). /// /// T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed. /// This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed. template ::type, any>::value>::type> any(ValueType&& value) { static_assert(std::is_copy_constructible::type>::value, "T shall satisfy the CopyConstructible requirements."); this->construct(std::forward(value)); } /// Has the same effect as any(rhs).swap(*this). No effects if an exception is thrown. any& operator=(const any& rhs) { any(rhs).swap(*this); return *this; } /// Has the same effect as any(std::move(rhs)).swap(*this). /// /// The state of *this is equivalent to the original state of rhs and rhs is left in a valid /// but otherwise unspecified state. any& operator=(any&& rhs) noexcept { any(std::move(rhs)).swap(*this); return *this; } /// Has the same effect as any(std::forward(value)).swap(*this). No effect if a exception is thrown. /// /// T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed. /// This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed. template ::type, any>::value>::type> any& operator=(ValueType&& value) { static_assert(std::is_copy_constructible::type>::value, "T shall satisfy the CopyConstructible requirements."); any(std::forward(value)).swap(*this); return *this; } /// If not empty, destroys the contained object. void clear() noexcept { if (!empty()) { this->vtable->destroy(storage); this->vtable = nullptr; } } /// Returns true if *this has no contained object, otherwise false. bool empty() const noexcept { return this->vtable == nullptr; } /// If *this has a contained object of type T, typeid(T); otherwise typeid(void). const std::type_info& type() const noexcept { return empty() ? typeid(void) : this->vtable->type(); } /// Exchange the states of *this and rhs. void swap(any& rhs) noexcept { if (this->vtable != rhs.vtable) { any tmp(std::move(rhs)); // move from *this to rhs. rhs.vtable = this->vtable; if (this->vtable != nullptr) { this->vtable->move(this->storage, rhs.storage); //this->vtable = nullptr; -- uneeded, see below } // move from tmp (previously rhs) to *this. this->vtable = tmp.vtable; if (tmp.vtable != nullptr) { tmp.vtable->move(tmp.storage, this->storage); tmp.vtable = nullptr; } } else // same types { if (this->vtable != nullptr) this->vtable->swap(this->storage, rhs.storage); } } private: // Storage and Virtual Method Table union storage_union { using stack_storage_t = typename std::aligned_storage<2 * sizeof(void*), std::alignment_of::value>::type; void* dynamic; stack_storage_t stack; // 2 words for e.g. shared_ptr }; /// Base VTable specification. struct vtable_type { // Note: The caller is responssible for doing .vtable = nullptr after destructful operations // such as destroy() and/or move(). /// The type of the object this vtable is for. const std::type_info& (*type)() noexcept; /// Destroys the object in the union. /// The state of the union after this call is unspecified, caller must ensure not to use src anymore. void (*destroy)(storage_union&) noexcept; /// Copies the **inner** content of the src union into the yet unitialized dest union. /// As such, both inner objects will have the same state, but on separate memory locations. void (*copy)(const storage_union& src, storage_union& dest); /// Moves the storage from src to the yet unitialized dest union. /// The state of src after this call is unspecified, caller must ensure not to use src anymore. void (*move)(storage_union& src, storage_union& dest) noexcept; /// Exchanges the storage between lhs and rhs. void (*swap)(storage_union& lhs, storage_union& rhs) noexcept; }; /// VTable for dynamically allocated storage. template struct vtable_dynamic { static const std::type_info& type() noexcept { return typeid(T); } static void destroy(storage_union& storage) noexcept { //assert(reinterpret_cast(storage.dynamic)); delete reinterpret_cast(storage.dynamic); } static void copy(const storage_union& src, storage_union& dest) { dest.dynamic = new T(*reinterpret_cast(src.dynamic)); } static void move(storage_union& src, storage_union& dest) noexcept { dest.dynamic = src.dynamic; src.dynamic = nullptr; } static void swap(storage_union& lhs, storage_union& rhs) noexcept { // just exchage the storage pointers. std::swap(lhs.dynamic, rhs.dynamic); } }; /// VTable for stack allocated storage. template struct vtable_stack { static const std::type_info& type() noexcept { return typeid(T); } static void destroy(storage_union& storage) noexcept { reinterpret_cast(&storage.stack)->~T(); } static void copy(const storage_union& src, storage_union& dest) { new (&dest.stack) T(reinterpret_cast(src.stack)); } static void move(storage_union& src, storage_union& dest) noexcept { // one of the conditions for using vtable_stack is a nothrow move constructor, // so this move constructor will never throw a exception. new (&dest.stack) T(std::move(reinterpret_cast(src.stack))); destroy(src); } static void swap(storage_union& lhs, storage_union& rhs) noexcept { storage_union tmp_storage; move(rhs, tmp_storage); move(lhs, rhs); move(tmp_storage, lhs); } }; /// Whether the type T must be dynamically allocated or can be stored on the stack. template struct requires_allocation : std::integral_constant::value // N4562 �6.3/3 [any.class] && sizeof(T) <= sizeof(storage_union::stack) && std::alignment_of::value <= std::alignment_of::value)> { }; /// Returns the pointer to the vtable of the type T. template static vtable_type* vtable_for_type() { using VTableType = typename std::conditional::value, vtable_dynamic, vtable_stack>::type; static vtable_type table = { VTableType::type, VTableType::destroy, VTableType::copy, VTableType::move, VTableType::swap, }; return &table; } protected: template friend const T* any_cast(const any* operand) noexcept; template friend T* any_cast(any* operand) noexcept; /// Same effect as is_same(this->type(), t); bool is_typed(const std::type_info& t) const { return is_same(this->type(), t); } /// Checks if two type infos are the same. /// /// If ANY_IMPL_FAST_TYPE_INFO_COMPARE is defined, checks only the address of the /// type infos, otherwise does an actual comparision. Checking addresses is /// only a valid approach when there's no interaction with outside sources /// (other shared libraries and such). static bool is_same(const std::type_info& a, const std::type_info& b) { #ifdef ANY_IMPL_FAST_TYPE_INFO_COMPARE return &a == &b; #else return a == b; #endif } /// Casts (with no type_info checks) the storage pointer as const T*. template const T* cast() const noexcept { return requires_allocation::type>::value ? reinterpret_cast(storage.dynamic) : reinterpret_cast(&storage.stack); } /// Casts (with no type_info checks) the storage pointer as T*. template T* cast() noexcept { return requires_allocation::type>::value ? reinterpret_cast(storage.dynamic) : reinterpret_cast(&storage.stack); } private: storage_union storage; // on offset(0) so no padding for align vtable_type* vtable; /// Chooses between stack and dynamic allocation for the type decay_t, /// assigns the correct vtable, and constructs the object on our storage. template void construct(ValueType&& value) { using T = typename std::decay::type; this->vtable = vtable_for_type(); return xtl::mpl::static_if::value>([&](auto self) { self(*this).storage.dynamic = new T(std::forward(value)); }, /*else*/ [&](auto self) { new (&self(*this).storage.stack) T(std::forward(value)); }); } }; namespace detail { template inline ValueType any_cast_move_if_true(typename std::remove_reference::type* p, std::true_type) { return std::move(*p); } template inline ValueType any_cast_move_if_true(typename std::remove_reference::type* p, std::false_type) { return *p; } } /// Performs *any_cast>>(&operand), or throws bad_any_cast on failure. template inline ValueType any_cast(const any& operand) { auto p = any_cast::type>::type>(&operand); detail::check_any_cast(p); return *p; } /// Performs *any_cast>(&operand), or throws bad_any_cast on failure. template inline ValueType any_cast(any& operand) { auto p = any_cast::type>(&operand); detail::check_any_cast(p); return *p; } /// /// If ANY_IMPL_ANYCAST_MOVEABLE is not defined, does as N4562 specifies: /// Performs *any_cast>(&operand), or throws bad_any_cast on failure. /// /// If ANY_IMPL_ANYCAST_MOVEABLE is defined, does as LWG Defect 2509 specifies: /// If ValueType is MoveConstructible and isn't a lvalue reference, performs /// std::move(*any_cast>(&operand)), otherwise /// *any_cast>(&operand). Throws bad_any_cast on failure. /// template inline ValueType any_cast(any&& operand) { #ifdef ANY_IMPL_ANY_CAST_MOVEABLE // https://cplusplus.github.io/LWG/lwg-active.html#2509 using can_move = std::integral_constant::value && !std::is_lvalue_reference::value>; #else using can_move = std::false_type; #endif auto p = any_cast::type>(&operand); detail::check_any_cast(p); return detail::any_cast_move_if_true(p, can_move()); } /// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object /// contained by operand, otherwise nullptr. template inline const T* any_cast(const any* operand) noexcept { if (operand == nullptr || !operand->is_typed(typeid(T))) return nullptr; else return operand->cast(); } /// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object /// contained by operand, otherwise nullptr. template inline T* any_cast(any* operand) noexcept { if (operand == nullptr || !operand->is_typed(typeid(T))) return nullptr; else return operand->cast(); } } namespace std { inline void swap(xtl::any& lhs, xtl::any& rhs) noexcept { lhs.swap(rhs); } } #endif xtl-0.6.9/include/xtl/xbase64.hpp000066400000000000000000000044411357123723600165700ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Sylvain Corlay and Johan Mabille and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_BASE64_HPP #define XTL_BASE64_HPP #include #include #include #include "xsequence.hpp" namespace xtl { inline std::string base64decode(const std::string& input) { std::array T; T.fill(-1); for (std::size_t i = 0; i < 64; ++i) { T[std::size_t("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i])] = int(i); } std::string output; int val = 0; int valb = -8; for (char c : input) { if (T[std::size_t(c)] == -1) { break; } val = (val << 6) + T[std::size_t(c)]; valb += 6; if (valb >= 0) { output.push_back(char((val >> valb) & 0xFF)); valb -= 8; } } return output; } inline std::string base64encode(const std::string& input) { std::string output; int val = 0; int valb = -6; for (char sc : input) { unsigned char c = static_cast(sc); val = (val << 8) + c; valb += 8; while (valb >= 0) { output.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val >> valb) & 0x3F]); valb -= 6; } } if (valb > -6) { output.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val << 8) >> (valb + 8)) & 0x3F]); } while (output.size() % 4) { output.push_back('='); } return output; } } #endif xtl-0.6.9/include/xtl/xbasic_fixed_string.hpp000066400000000000000000003007101357123723600213300ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Sylvain Corlay and Johan Mabille and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_BASIC_FIXED_STRING_HPP #define XTL_BASIC_FIXED_STRING_HPP #include #include #include #include #include #include #ifdef __CLING__ #include #endif #include "xhash.hpp" #include "xtl_config.hpp" namespace xtl { namespace string_policy { template struct silent_error; template struct throwing_error; } /*********************** * xbasic_fixed_string * ***********************/ enum storage_options { buffer = 1 << 0, pointer = 1 << 1, store_size = 1 << 2, is_const = 1 << 3 }; template class EP = string_policy::silent_error, class TR = std::char_traits> class xbasic_fixed_string; template class EP, class TR> std::basic_ostream& operator<<(std::basic_ostream& os, const xbasic_fixed_string& str); template class EP, class TR> std::basic_istream& operator>>(std::basic_istream& is, xbasic_fixed_string& str); template using xbasic_string_view = xbasic_fixed_string; namespace detail { template struct select_storage; template struct fixed_string_storage_impl { fixed_string_storage_impl() = default; fixed_string_storage_impl(T ptr, std::size_t size) : m_buffer(ptr), m_size(size) { } T& buffer() { return m_buffer; } const T& buffer() const { return m_buffer; } std::size_t size() const { return m_size; } void set_size(std::size_t sz) { m_size = sz; m_buffer[sz] = '\0'; } void adjust_size(std::ptrdiff_t val) { m_size += std::size_t(val); m_buffer[m_size] = '\0'; } T m_buffer; std::size_t m_size; }; template struct fixed_string_external_storage_impl { fixed_string_external_storage_impl() = default; fixed_string_external_storage_impl(T ptr, std::ptrdiff_t/*size*/) { m_buffer = ptr; } T& buffer() { return m_buffer; } const T& buffer() const { return m_buffer; } void set_size(std::size_t sz) { m_buffer[sz] = '\0'; } void adjust_size(std::ptrdiff_t val) { m_buffer[size() + val] = '\0'; } std::size_t size() const { return std::strlen(m_buffer); } T m_buffer; }; template <> struct select_storage { template using type = fixed_string_storage_impl; }; template <> struct select_storage { template using type = fixed_string_external_storage_impl; }; } template class EP, class TR> class xbasic_fixed_string { public: using traits_type = TR; using value_type = CT; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using storage_type = typename detail::select_storage::template type; using reference = value_type&; using const_reference = const value_type&; using pointer = value_type*; using const_pointer = const value_type*; using iterator = pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; static const size_type npos; using self_type = xbasic_fixed_string; using initializer_type = std::initializer_list; using string_type = std::basic_string; using error_policy = EP; xbasic_fixed_string(); explicit xbasic_fixed_string(size_type count, value_type ch); explicit xbasic_fixed_string(const self_type& other, size_type pos, size_type count = npos); explicit xbasic_fixed_string(const string_type& other); explicit xbasic_fixed_string(const string_type& other, size_type pos, size_type count = npos); xbasic_fixed_string(const_pointer s, size_type count); xbasic_fixed_string(const_pointer s); xbasic_fixed_string(initializer_type ilist); template xbasic_fixed_string(InputIt first, InputIt last); operator string_type() const; ~xbasic_fixed_string() = default; xbasic_fixed_string(const self_type&) = default; xbasic_fixed_string(self_type&&) = default; self_type& operator=(const self_type&) = default; self_type& operator=(self_type&&) = default; self_type& operator=(const_pointer s); self_type& operator=(value_type ch); self_type& operator=(initializer_type ilist); self_type& operator=(const string_type& str); self_type& assign(size_type count, value_type ch); self_type& assign(const self_type& other, size_type pos, size_type count = npos); self_type& assign(const_pointer s, size_type count); self_type& assign(const_pointer s); self_type& assign(initializer_type ilist); template self_type& assign(InputIt first, InputIt last); self_type& assign(const self_type& rhs); self_type& assign(self_type&& rhs); self_type& assign(const string_type& str); self_type& assign(const string_type& other, size_type pos, size_type count = npos); reference at(size_type pos); const_reference at(size_type pos) const; reference operator[](size_type pos); const_reference operator[](size_type pos) const; reference front(); const_reference front() const; reference back(); const_reference back() const; pointer data() noexcept; const_pointer data() const noexcept; const_pointer c_str() const noexcept; iterator begin() noexcept; iterator end() noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; reverse_iterator rbegin() noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; bool empty() const noexcept; size_type size() const noexcept; size_type length() const noexcept; size_type max_size() const noexcept; void clear() noexcept; void push_back(value_type ch); void pop_back(); self_type substr(size_type pos = 0, size_type count = npos) const; size_type copy(pointer dest, size_type count, size_type pos = 0) const; void resize(size_type count); void resize(size_type count, value_type ch); void swap(self_type& rhs) noexcept; self_type& insert(size_type index, size_type count, value_type ch); self_type& insert(size_type index, const_pointer s); self_type& insert(size_type index, const_pointer s, size_type count); self_type& insert(size_type index, const self_type& str); self_type& insert(size_type index, const self_type& str, size_type index_str, size_type count = npos); self_type& insert(size_type index, const string_type& str); self_type& insert(size_type index, const string_type& str, size_type index_str, size_type count = npos); iterator insert(const_iterator pos, value_type ch); iterator insert(const_iterator pos, size_type count, value_type ch); iterator insert(const_iterator pos, initializer_type ilist); template iterator insert(const_iterator pos, InputIt first, InputIt last); self_type& erase(size_type index = 0, size_type count = npos); iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); self_type& append(size_type count, value_type ch); self_type& append(const self_type& str); self_type& append(const self_type& str, size_type pos, size_type count = npos); self_type& append(const string_type& str); self_type& append(const string_type& str, size_type pos, size_type count = npos); self_type& append(const_pointer s, size_type count); self_type& append(const_pointer s); self_type& append(initializer_type ilist); template self_type& append(InputIt first, InputIt last); self_type& operator+=(const self_type& str); self_type& operator+=(const string_type& str); self_type& operator+=(value_type ch); self_type& operator+=(const_pointer s); self_type& operator+=(initializer_type ilist); int compare(const self_type& str) const noexcept; int compare(size_type pos1, size_type count1, const self_type& str) const; int compare(size_type pos1, size_type count1, const self_type& str, size_type pos2, size_type count2 = npos) const; int compare(const string_type& str) const noexcept; int compare(size_type pos1, size_type count1, const string_type& str) const; int compare(size_type pos1, size_type count1, const string_type& str, size_type pos2, size_type count2 = npos) const; int compare(const_pointer s) const noexcept; int compare(size_type pos1, size_type count1, const_pointer s) const; int compare(size_type pos1, size_type count1, const_pointer s, size_type count2) const; self_type& replace(size_type pos, size_type count, const self_type& str); self_type& replace(const_iterator first, const_iterator last, const self_type& str); self_type& replace(size_type pos1, size_type count1, const self_type& str, size_type pos2, size_type count2 = npos); self_type& replace(size_type pos, size_type count, const string_type& str); self_type& replace(const_iterator first, const_iterator last, const string_type& str); self_type& replace(size_type pos1, size_type count1, const string_type& str, size_type pos2, size_type count2 = npos); self_type& replace(size_type pos, size_type count, const_pointer cstr, size_type count2); self_type& replace(const_iterator first, const_iterator last, const_pointer cstr, size_type count2); self_type& replace(size_type pos, size_type count, const_pointer cstr); self_type& replace(const_iterator first, const_iterator last, const_pointer cstr); self_type& replace(size_type pos, size_type count, size_type count2, value_type ch); self_type& replace(const_iterator first, const_iterator last, size_type count2, value_type ch); self_type& replace(const_iterator first, const_iterator last, initializer_type ilist); template self_type& replace(const_iterator first, const_iterator last, InputIt first2, InputIt last2); size_type find(const self_type& str, size_type pos = 0) const noexcept; size_type find(const string_type& str, size_type pos = 0) const noexcept; size_type find(const_pointer s, size_type pos, size_type count) const; size_type find(const_pointer s, size_type pos = 0) const; size_type find(value_type ch, size_type pos = 0) const; size_type rfind(const self_type& str, size_type pos = npos) const noexcept; size_type rfind(const string_type& str, size_type pos = npos) const noexcept; size_type rfind(const_pointer s, size_type pos, size_type count) const; size_type rfind(const_pointer s, size_type pos = npos) const; size_type rfind(value_type ch, size_type pos = npos) const; size_type find_first_of(const self_type& str, size_type pos = 0) const noexcept; size_type find_first_of(const string_type& str, size_type pos = 0) const noexcept; size_type find_first_of(const_pointer s, size_type pos, size_type count) const; size_type find_first_of(const_pointer s, size_type pos = 0) const; size_type find_first_of(value_type ch, size_type pos = 0) const; size_type find_first_not_of(const self_type& str, size_type pos = 0) const noexcept; size_type find_first_not_of(const string_type& str, size_type pos = 0) const noexcept; size_type find_first_not_of(const_pointer s, size_type pos, size_type count) const; size_type find_first_not_of(const_pointer s, size_type pos = 0) const; size_type find_first_not_of(value_type ch, size_type pos = 0) const; size_type find_last_of(const self_type& str, size_type pos = 0) const noexcept; size_type find_last_of(const string_type& str, size_type pos = 0) const noexcept; size_type find_last_of(const_pointer s, size_type pos, size_type count) const; size_type find_last_of(const_pointer s, size_type pos = 0) const; size_type find_last_of(value_type ch, size_type pos = 0) const; size_type find_last_not_of(const self_type& str, size_type pos = npos) const noexcept; size_type find_last_not_of(const string_type& str, size_type pos = npos) const noexcept; size_type find_last_not_of(const_pointer s, size_type pos, size_type count) const; size_type find_last_not_of(const_pointer s, size_type pos = npos) const; size_type find_last_not_of(value_type ch, size_type pos = npos) const; private: int compare_impl(const_pointer s1, size_type count1, const_pointer s2, size_type count2) const noexcept; void update_null_termination() noexcept; void check_index(size_type pos, size_type size, const char* what) const; void check_index_strict(size_type pos, size_type size, const char* what) const; storage_type m_storage; }; template class EP, class TR> const typename xbasic_fixed_string::size_type xbasic_fixed_string::npos = std::basic_string::npos; template using xfixed_string = xbasic_fixed_string; template using xwfixed_string = xbasic_fixed_string; template using xu16fixed_string = xbasic_fixed_string; template using xu32fixed_string = xbasic_fixed_string; /************************** * Concatenation operator * **************************/ template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs); template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, const CT* rhs); template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, CT rhs); template class EP, class TR> xbasic_fixed_string operator+(const CT* lhs, const xbasic_fixed_string& rhs); template class EP, class TR> xbasic_fixed_string operator+(CT lhs, const xbasic_fixed_string& rhs); template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, const xbasic_fixed_string& rhs); template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, const xbasic_fixed_string&& rhs); template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, const xbasic_fixed_string&& rhs); template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, const CT* rhs); template class EP, class TR> xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, CT rhs); template class EP, class TR> xbasic_fixed_string operator+(const CT* lhs, const xbasic_fixed_string&& rhs); template class EP, class TR> xbasic_fixed_string operator+(CT lhs, const xbasic_fixed_string&& rhs); /************************ * Comparison operators * ************************/ template class EP, class TR> bool operator==(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator==(const xbasic_fixed_string& lhs, const CT* rhs) noexcept; template class EP, class TR> bool operator==(const CT* lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator==(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept; template class EP, class TR> bool operator==(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator!=(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator!=(const xbasic_fixed_string& lhs, const CT* rhs) noexcept; template class EP, class TR> bool operator!=(const CT* lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator!=(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept; template class EP, class TR> bool operator!=(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator<(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator<(const xbasic_fixed_string& lhs, const CT* rhs) noexcept; template class EP, class TR> bool operator<(const CT* lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator<(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept; template class EP, class TR> bool operator<(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator<=(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator<=(const xbasic_fixed_string& lhs, const CT* rhs) noexcept; template class EP, class TR> bool operator<=(const CT* lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator<=(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept; template class EP, class TR> bool operator<=(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator>(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator>(const xbasic_fixed_string& lhs, const CT* rhs) noexcept; template class EP, class TR> bool operator>(const CT* lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator>(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept; template class EP, class TR> bool operator>(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator>=(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator>=(const xbasic_fixed_string& lhs, const CT* rhs) noexcept; template class EP, class TR> bool operator>=(const CT* lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> bool operator>=(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept; template class EP, class TR> bool operator>=(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept; template class EP, class TR> void swap(xbasic_fixed_string& lhs, xbasic_fixed_string& rhs); /****************************** * Input / output declaration * ******************************/ template class EP, class TR> std::basic_istream& getline(std::basic_istream& input, xbasic_fixed_string& str, CT delim); template class EP, class TR> std::basic_istream& getline(std::basic_istream&& input, xbasic_fixed_string& str, CT delim); template class EP, class TR> std::basic_istream& getline(std::basic_istream& input, xbasic_fixed_string& str); template class EP, class TR> std::basic_istream& getline(std::basic_istream&& input, xbasic_fixed_string& str); } // namespace xtl namespace std { template class EP, class TR> struct hash<::xtl::xbasic_fixed_string> { using argument_type = ::xtl::xbasic_fixed_string; using result_type = std::size_t; inline result_type operator()(const argument_type& arg) const { return ::xtl::hash_bytes(arg.data(), arg.size(), static_cast(0xc70f6907UL)); } }; } // namespace std namespace xtl { /******************************** * xbasic_fixed_string policies * ********************************/ namespace string_policy { template struct silent_error { inline static std::size_t check_size(std::size_t size) { return size; } inline static std::size_t check_add(std::size_t size1, std::size_t size2) { return size1 + size2; } }; template struct throwing_error { inline static std::size_t check_size(std::size_t size) { if (size > N) { std::ostringstream oss; oss << "Invalid size (" << size << ") for xbasic_fixed_string - maximal size: " << N; #if defined(XTL_NO_EXCEPTIONS) std::fprintf(stderr, "%s\n", oss.str().c_str()); std::terminate(); #else throw std::length_error(oss.str()); #endif } return size; } inline static std::size_t check_add(std::size_t size1, std::size_t size2) { return check_size(size1 + size2); } }; } // string_policy /************************************** * xbasic_fixed_string implementation * **************************************/ /**************** * Constructors * ****************/ template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string() : m_storage() { } template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string(size_type count, value_type ch) : m_storage() { assign(count, ch); } template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string(const self_type& other, size_type pos, size_type count) : m_storage() { assign(other, pos, count); } template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string(const string_type& other) : m_storage() { assign(other); } template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string(const string_type& other, size_type pos, size_type count) : m_storage() { assign(other, pos, count); } template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string(const_pointer s, size_type count) : m_storage() { assign(s, count); } template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string(const_pointer s) : m_storage() { assign(s); } template class EP, class TR> inline xbasic_fixed_string::xbasic_fixed_string(initializer_type ilist) : m_storage() { assign(ilist); } template class EP, class TR> template inline xbasic_fixed_string::xbasic_fixed_string(InputIt first, InputIt last) : m_storage() { assign(first, last); } template class EP, class TR> inline xbasic_fixed_string::operator string_type() const { return string_type(data()); } /************** * Assignment * **************/ template class EP, class TR> inline auto xbasic_fixed_string::operator=(const_pointer s) -> self_type& { return assign(s); } template class EP, class TR> inline auto xbasic_fixed_string::operator=(value_type ch) -> self_type& { return assign(size_type(1), ch); } template class EP, class TR> inline auto xbasic_fixed_string::operator=(initializer_type ilist) -> self_type& { return assign(ilist); } template class EP, class TR> inline auto xbasic_fixed_string::operator=(const string_type& str) -> self_type& { return assign(str); } template class EP, class TR> inline auto xbasic_fixed_string::assign(size_type count, value_type ch) -> self_type& { m_storage.set_size(error_policy::check_size(count)); traits_type::assign(data(), count, ch); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::assign(const self_type& other, size_type pos, size_type count) -> self_type& { check_index_strict(pos, other.size(), "xbasic_fixed_string::assign"); size_type copy_count = std::min(other.size() - pos, count); m_storage.set_size(error_policy::check_size(copy_count)); traits_type::copy(data(), other.data() + pos, copy_count); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::assign(const_pointer s, size_type count) -> self_type& { m_storage.set_size(error_policy::check_size(count)); traits_type::copy(data(), s, count); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::assign(const_pointer s) -> self_type& { std::size_t ssize = traits_type::length(s); return assign(s, ssize); } template class EP, class TR> inline auto xbasic_fixed_string::assign(initializer_type ilist) -> self_type& { return assign(ilist.begin(), ilist.end()); } template class EP, class TR> template inline auto xbasic_fixed_string::assign(InputIt first, InputIt last) -> self_type& { m_storage.set_size(error_policy::check_size(static_cast(std::distance(first, last)))); std::copy(first, last, data()); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::assign(const self_type& rhs) -> self_type& { if (this != &rhs) { m_storage.set_size(rhs.size()); traits_type::copy(data(), rhs.data(), rhs.size()); } return *this; } template class EP, class TR> inline auto xbasic_fixed_string::assign(self_type&& rhs) -> self_type& { if (this != &rhs) { m_storage.set_size(rhs.size()); traits_type::copy(data(), rhs.data(), rhs.size()); } return *this; } template class EP, class TR> inline auto xbasic_fixed_string::assign(const string_type& other) -> self_type& { return assign(other.c_str()); } template class EP, class TR> inline auto xbasic_fixed_string::assign(const string_type& other, size_type pos, size_type count) -> self_type& { return assign(other.c_str() + pos, std::min(count, other.size() - pos)); } /****************** * Element access * ******************/ template class EP, class TR> inline auto xbasic_fixed_string::at(size_type pos) -> reference { check_index(pos, size(), "basic_fixed_string::at"); return this->operator[](pos); } template class EP, class TR> inline auto xbasic_fixed_string::at(size_type pos) const -> const_reference { check_index(pos, size(), "basic_fixed_string::at"); return this->operator[](pos); } template class EP, class TR> inline auto xbasic_fixed_string::operator[](size_type pos) -> reference { return data()[pos]; } template class EP, class TR> inline auto xbasic_fixed_string::operator[](size_type pos) const -> const_reference { return data()[pos]; } template class EP, class TR> inline auto xbasic_fixed_string::front() -> reference { return this->operator[](0); } template class EP, class TR> inline auto xbasic_fixed_string::front() const -> const_reference { return this->operator[](0); } template class EP, class TR> inline auto xbasic_fixed_string::back() -> reference { return this->operator[](size() - 1); } template class EP, class TR> inline auto xbasic_fixed_string::back() const -> const_reference { return this->operator[](size() - 1); } template class EP, class TR> inline auto xbasic_fixed_string::data() noexcept -> pointer { return m_storage.buffer(); } template class EP, class TR> inline auto xbasic_fixed_string::data() const noexcept -> const_pointer { return m_storage.buffer(); } template class EP, class TR> inline auto xbasic_fixed_string::c_str() const noexcept -> const_pointer { return m_storage.buffer(); } /************* * Iterators * *************/ template class EP, class TR> inline auto xbasic_fixed_string::begin() noexcept -> iterator { return data(); } template class EP, class TR> inline auto xbasic_fixed_string::end() noexcept -> iterator { return data() + size(); } template class EP, class TR> inline auto xbasic_fixed_string::begin() const noexcept -> const_iterator { return cbegin(); } template class EP, class TR> inline auto xbasic_fixed_string::end() const noexcept -> const_iterator { return cend(); } template class EP, class TR> inline auto xbasic_fixed_string::cbegin() const noexcept -> const_iterator { return data(); } template class EP, class TR> inline auto xbasic_fixed_string::cend() const noexcept -> const_iterator { return data() + size(); } template class EP, class TR> inline auto xbasic_fixed_string::rbegin() noexcept -> reverse_iterator { return reverse_iterator(end()); } template class EP, class TR> inline auto xbasic_fixed_string::rend() noexcept -> reverse_iterator { return reverse_iterator(begin()); } template class EP, class TR> inline auto xbasic_fixed_string::rbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(end()); } template class EP, class TR> inline auto xbasic_fixed_string::rend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(begin()); } template class EP, class TR> inline auto xbasic_fixed_string::crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(end()); } template class EP, class TR> inline auto xbasic_fixed_string::crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(begin()); } /************ * Capacity * ************/ template class EP, class TR> inline bool xbasic_fixed_string::empty() const noexcept { return size() == 0; } template class EP, class TR> inline auto xbasic_fixed_string::size() const noexcept -> size_type { return m_storage.size(); } template class EP, class TR> inline auto xbasic_fixed_string::length() const noexcept -> size_type { return m_storage.size(); } template class EP, class TR> inline auto xbasic_fixed_string::max_size() const noexcept -> size_type { return N; } /************** * Operations * **************/ template class EP, class TR> inline void xbasic_fixed_string::clear() noexcept { m_storage.set_size(0); } template class EP, class TR> inline void xbasic_fixed_string::push_back(value_type ch) { error_policy::check_add(size(), size_type(1)); data()[size()] = ch; m_storage.adjust_size(+1); } template class EP, class TR> inline void xbasic_fixed_string::pop_back() { m_storage.adjust_size(-1); } template class EP, class TR> inline auto xbasic_fixed_string::substr(size_type pos, size_type count) const -> self_type { return self_type(*this, pos, count); } template class EP, class TR> inline auto xbasic_fixed_string::copy(pointer dest, size_type count, size_type pos) const -> size_type { check_index_strict(pos, size(), "xbasic_fixed_string::copy"); size_type nb_copied = std::min(count, size() - pos); traits_type::copy(dest, data() + pos, nb_copied); return nb_copied; } template class EP, class TR> inline void xbasic_fixed_string::resize(size_type count) { resize(count, value_type(' ')); // need to initialize with some value != \0 } template class EP, class TR> inline void xbasic_fixed_string::resize(size_type count, value_type ch) { size_type old_size = size(); m_storage.set_size(error_policy::check_size(count)); if (old_size < size()) { traits_type::assign(data() + old_size, size() - old_size, ch); } } template class EP, class TR> inline void xbasic_fixed_string::swap(self_type& rhs) noexcept { self_type tmp(std::move(rhs)); rhs = std::move(*this); *this = std::move(tmp); } /********** * insert * **********/ template class EP, class TR> auto xbasic_fixed_string::insert(size_type index, size_type count, value_type ch) -> self_type& { check_index_strict(index, size(), "xbasic_fixed_string::insert"); size_type old_size = size(); m_storage.set_size(error_policy::check_add(size(), count)); std::copy_backward(data() + index, data() + old_size, end()); traits_type::assign(data() + index, count, ch); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::insert(size_type index, const_pointer s) -> self_type& { return insert(index, s, traits_type::length(s)); } template class EP, class TR> auto xbasic_fixed_string::insert(size_type index, const_pointer s, size_type count) -> self_type& { check_index_strict(index, size(), "xbasic_fixed_string::insert"); size_type old_size = size(); m_storage.set_size(error_policy::check_add(size(), count)); std::copy_backward(data() + index, data() + old_size, end()); traits_type::copy(data() + index, s, count); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::insert(size_type index, const self_type& str) -> self_type& { return insert(index, str.data(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::insert(size_type index, const self_type& str, size_type index_str, size_type count) -> self_type& { check_index_strict(index_str, str.size(), "xbasic_fixed_string::insert"); return insert(index, str.data() + index_str, std::min(count, str.size() - index_str)); } template class EP, class TR> inline auto xbasic_fixed_string::insert(size_type index, const string_type& str) -> self_type& { return insert(index, str.c_str(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::insert(size_type index, const string_type& str, size_type index_str, size_type count) -> self_type& { check_index_strict(index_str, str.size(), "xbasic_fixed_string::insert"); return insert(index, str.c_str() + index_str, std::min(count, str.size() - index_str)); } template class EP, class TR> inline auto xbasic_fixed_string::insert(const_iterator pos, value_type ch) -> iterator { return insert(pos, size_type(1), ch); } template class EP, class TR> inline auto xbasic_fixed_string::insert(const_iterator pos, size_type count, value_type ch) -> iterator { if (cbegin() <= pos && pos < cend()) { size_type index = static_cast(pos - cbegin()); insert(index, count, ch); return const_cast(pos); } return end(); } template class EP, class TR> inline auto xbasic_fixed_string::insert(const_iterator pos, initializer_type ilist) -> iterator { return insert(pos, ilist.begin(), ilist.end()); } template class EP, class TR> template auto xbasic_fixed_string::insert(const_iterator pos, InputIt first, InputIt last) -> iterator { if (cbegin() <= pos && pos < cend()) { size_type index = static_cast(pos - cbegin()); size_type count = static_cast(std::distance(first, last)); size_type old_size = size(); m_storage.set_size(error_policy::check_add(size(), count)); std::copy_backward(data() + index, data() + old_size, end()); std::copy(first, last, data() + index); return begin() + index; } return end(); } /********* * erase * *********/ template class EP, class TR> auto xbasic_fixed_string::erase(size_type index, size_type count) -> self_type& { check_index_strict(index, size(), "xbasic_fixed_string::erase"); size_type erase_count = std::min(count, size() - index); // cannot use traits_type::copy because of overlapping std::copy(data() + index + erase_count, data() + size(), data() + index); m_storage.adjust_size(-static_cast(erase_count)); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::erase(const_iterator position) -> iterator { return erase(position, position + 1); } template class EP, class TR> auto xbasic_fixed_string::erase(const_iterator first, const_iterator last) -> iterator { if (cbegin() <= first && first < cend()) { const_iterator adapted_last = std::min(last, cend()); size_type erase_count = static_cast(adapted_last - first); // cannot use traits_type::copy because of overlapping std::copy(adapted_last, cend(), iterator(first)); m_storage.adjust_size(-static_cast(erase_count)); return const_cast(first); } return end(); } /********** * append * **********/ template class EP, class TR> inline auto xbasic_fixed_string::append(size_type count, value_type ch) -> self_type& { size_type old_size = m_storage.size(); m_storage.set_size(error_policy::check_add(size(), count)); traits_type::assign(data() + old_size, count, ch); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::append(const self_type& str) -> self_type& { return append(str.data(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::append(const self_type& str, size_type pos, size_type count) -> self_type& { check_index_strict(pos, str.size(), "xbasic_fixed_string::append"); return append(str.data() + pos, std::min(count, str.size() - pos)); } template class EP, class TR> inline auto xbasic_fixed_string::append(const string_type& str) -> self_type& { return append(str.c_str(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::append(const string_type& str, size_type pos, size_type count) -> self_type& { check_index_strict(pos, str.size(), "xbasic_fixed_string::append"); return append(str.c_str() + pos, std::min(count, str.size() - pos)); } template class EP, class TR> inline auto xbasic_fixed_string::append(const_pointer s, size_type count) -> self_type& { size_type old_size = m_storage.size(); m_storage.set_size(error_policy::check_add(size(), count)); traits_type::copy(data() + old_size, s, count); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::append(const_pointer s) -> self_type& { return append(s, traits_type::length(s)); } template class EP, class TR> inline auto xbasic_fixed_string::append(initializer_type ilist) -> self_type& { return append(ilist.begin(), ilist.end()); } template class EP, class TR> template inline auto xbasic_fixed_string::append(InputIt first, InputIt last) -> self_type& { size_type count = static_cast(std::distance(first, last)); size_type old_size = m_storage.size(); m_storage.set_size(error_policy::check_add(size(), count)); std::copy(first, last, data() + old_size); return *this; } template class EP, class TR> inline auto xbasic_fixed_string::operator+=(const self_type& str) -> self_type& { return append(str); } template class EP, class TR> inline auto xbasic_fixed_string::operator+=(const string_type& str) -> self_type& { return append(str); } template class EP, class TR> inline auto xbasic_fixed_string::operator+=(value_type ch) -> self_type& { return append(size_type(1), ch); } template class EP, class TR> inline auto xbasic_fixed_string::operator+=(const_pointer s) -> self_type& { return append(s); } template class EP, class TR> inline auto xbasic_fixed_string::operator+=(initializer_type ilist) -> self_type& { return append(ilist); } /*********** * compare * ***********/ template class EP, class TR> inline int xbasic_fixed_string::compare(const self_type& str) const noexcept { return compare_impl(data(), size(), str.data(), str.size()); } template class EP, class TR> inline int xbasic_fixed_string::compare(size_type pos1, size_type count1, const self_type& str) const { check_index_strict(pos1, size(), "xbasic_fixed_string::compare"); return compare_impl(data() + pos1, std::min(count1, size() - pos1), str.data(), str.size()); } template class EP, class TR> inline int xbasic_fixed_string::compare(size_type pos1, size_type count1, const self_type& str, size_type pos2, size_type count2) const { check_index_strict(pos1, size(), "xbasic_fixed_string::compare"); check_index_strict(pos2, str.size(), "xbasic_fixed_string::compare"); return compare_impl(data() + pos1, std::min(count1, size() - pos1), str.data() + pos2, std::min(count2, str.size() - pos2)); } template class EP, class TR> inline int xbasic_fixed_string::compare(const string_type& str) const noexcept { return compare_impl(data(), size(), str.data(), str.size()); } template class EP, class TR> inline int xbasic_fixed_string::compare(size_type pos1, size_type count1, const string_type& str) const { check_index_strict(pos1, size(), "xbasic_fixed_string::compare"); return compare_impl(data() + pos1, std::min(count1, size() - pos1), str.data(), str.size()); } template class EP, class TR> inline int xbasic_fixed_string::compare(size_type pos1, size_type count1, const string_type& str, size_type pos2, size_type count2) const { check_index_strict(pos1, size(), "xbasic_fixed_string::compare"); check_index_strict(pos2, str.size(), "xbasic_fixed_string::compare"); return compare_impl(data() + pos1, std::min(count1, size() - pos1), str.data() + pos2, std::min(count2, str.size() - pos2)); } template class EP, class TR> inline int xbasic_fixed_string::compare(const_pointer s) const noexcept { return compare_impl(data(), size(), s, traits_type::length(s)); } template class EP, class TR> int xbasic_fixed_string::compare(size_type pos1, size_type count1, const_pointer s) const { return compare(pos1, count1, s, traits_type::length(s)); } template class EP, class TR> int xbasic_fixed_string::compare(size_type pos1, size_type count1, const_pointer s, size_type count2) const { check_index_strict(pos1, size(), "xbasic_fixed_string::compare"); return compare_impl(data() + pos1, std::min(count1, size() - pos1), s, count2); } /*********** * replace * ***********/ template class EP, class TR> inline auto xbasic_fixed_string::replace(size_type pos, size_type count, const self_type& str) -> self_type& { return replace(pos, count, str.data(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::replace(const_iterator first, const_iterator last, const self_type& str) -> self_type& { return replace(first, last, str.data(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::replace(size_type pos1, size_type count1, const self_type& str, size_type pos2, size_type count2) -> self_type& { check_index_strict(pos2, str.size(), "xbasic_fixed_string::replace"); return replace(pos1, count1, str.data() + pos2, std::min(count2, str.size() - pos2)); } template class EP, class TR> inline auto xbasic_fixed_string::replace(size_type pos, size_type count, const string_type& str) -> self_type& { return replace(pos, count, str.data(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::replace(const_iterator first, const_iterator last, const string_type& str) -> self_type& { return replace(first, last, str.data(), str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::replace(size_type pos1, size_type count1, const string_type& str, size_type pos2, size_type count2) -> self_type& { check_index_strict(pos2, str.size(), "xbasic_fixed_string::replace"); return replace(pos1, count1, str.data() + pos2, std::min(count2, str.size() - pos2)); } template class EP, class TR> auto xbasic_fixed_string::replace(size_type pos, size_type count, const_pointer cstr, size_type count2) -> self_type& { check_index_strict(pos, size(), "xbasic_fixed_string::replace"); size_type erase_count = std::min(count, size() - pos); size_type new_size = error_policy::check_add(size() - erase_count, count2); if (erase_count > count2) { traits_type::copy(data() + pos, cstr, count2); std::copy(cbegin() + pos + erase_count, cend(), data() + pos + count2); m_storage.set_size(new_size); } else if (erase_count < count2) { std::copy_backward(cbegin() + pos + erase_count, cend(), data() + new_size); traits_type::copy(data() + pos, cstr, count2); m_storage.set_size(new_size); } else { traits_type::copy(data() + pos, cstr, count2); } return *this; } template class EP, class TR> inline auto xbasic_fixed_string::replace(const_iterator first, const_iterator last, const_pointer cstr, size_type count2) -> self_type& { if (cbegin() <= first && first < last && last <= cend()) { size_type pos = static_cast(first - cbegin()); size_type count = static_cast(last - first); return replace(pos, count, cstr, count2); } return *this; } template class EP, class TR> inline auto xbasic_fixed_string::replace(size_type pos, size_type count, const_pointer cstr) -> self_type& { return replace(pos, count, cstr, traits_type::length(cstr)); } template class EP, class TR> inline auto xbasic_fixed_string::replace(const_iterator first, const_iterator last, const_pointer cstr) -> self_type& { return replace(first, last, cstr, traits_type::length(cstr)); } template class EP, class TR> inline auto xbasic_fixed_string::replace(size_type pos, size_type count, size_type count2, value_type ch) -> self_type& { check_index_strict(pos, size(), "xbasic_fixed_string::replace"); size_type erase_count = std::min(count, size() - pos); size_type new_size = error_policy::check_add(size() - erase_count, count2); if (erase_count > count2) { traits_type::assign(data() + pos, count2, ch); std::copy(cbegin() + pos + erase_count, cend(), data() + pos + count2); m_storage.set_size(new_size); } else if (erase_count < count2) { std::copy_backward(cbegin() + pos + erase_count, cend(), data() + new_size); traits_type::assign(data() + pos, count2, ch); m_storage.set_size(new_size); } else { traits_type::assign(data() + pos, count2, ch); } return *this; } template class EP, class TR> inline auto xbasic_fixed_string::replace(const_iterator first, const_iterator last, size_type count2, value_type ch) -> self_type& { if (cbegin() <= first && first < last && last <= cend()) { size_type pos = static_cast(first - cbegin()); size_type count = static_cast(last - first); return replace(pos, count, count2, ch); } return *this; } template class EP, class TR> inline auto xbasic_fixed_string::replace(const_iterator first, const_iterator last, initializer_type ilist) -> self_type& { return replace(first, last, ilist.begin(), ilist.end()); } template class EP, class TR> template inline auto xbasic_fixed_string::replace(const_iterator first, const_iterator last, InputIt first2, InputIt last2) -> self_type& { if (cbegin() <= first && first < last && last <= cend()) { size_type pos = static_cast(first - cbegin()); size_type erase_count = static_cast(last - first); size_type count2 = static_cast(std::distance(first2, last2)); size_type new_size = error_policy::check_add(size() - erase_count, count2); if (erase_count > count2) { std::copy(first2, last2, data() + pos); std::copy(cbegin() + pos + erase_count, cend(), data() + pos + count2); m_storage.set_size(new_size); } else if (erase_count < count2) { std::copy_backward(cbegin() + pos + erase_count, cend(), data() + new_size); std::copy(first2, last2, data() + pos); m_storage.set_size(new_size); } else { std::copy(first2, last2, data() + pos); } } return *this; } /******** * find * ********/ template class EP, class TR> inline auto xbasic_fixed_string::find(const self_type& str, size_type pos) const noexcept -> size_type { return find(str.data(), pos, str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::find(const string_type& str, size_type pos) const noexcept -> size_type { return find(str.data(), pos, str.size()); } template class EP, class TR> auto xbasic_fixed_string::find(const_pointer s, size_type pos, size_type count) const -> size_type { if (count == size_type(0) && pos <= size()) { return pos; } size_type nm; if (pos < size() && count <= (nm = size() - pos)) { const_pointer uptr, vptr; for (nm -= count - 1, vptr = data() + pos; (uptr = traits_type::find(vptr, nm, *s)) != 0; nm -= size_type(uptr - vptr) + 1ul, vptr = uptr + 1ul) { if (traits_type::compare(uptr, s, count) == 0) { return size_type(uptr - data()); } } } return npos; } template class EP, class TR> inline auto xbasic_fixed_string::find(const_pointer s, size_type pos) const -> size_type { return find(s, pos, traits_type::length(s)); } template class EP, class TR> inline auto xbasic_fixed_string::find(value_type ch, size_type pos) const -> size_type { return find((const_pointer)(&ch), pos, size_type(1)); } /********* * rfind * *********/ template class EP, class TR> inline auto xbasic_fixed_string::rfind(const self_type& str, size_type pos) const noexcept -> size_type { return rfind(str.data(), pos, str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::rfind(const string_type& str, size_type pos) const noexcept -> size_type { return rfind(str.data(), pos, str.size()); } template class EP, class TR> auto xbasic_fixed_string::rfind(const_pointer s, size_type pos, size_type count) const -> size_type { if (count == 0) { return std::min(pos, size()); } if (count <= size()) { const_pointer uptr = data() + std::min(pos, size() - count); for (;; --uptr) { if (traits_type::eq(*uptr, *s) && traits_type::compare(uptr, s, count) == 0) { return size_type(uptr - data()); } else if (uptr == data()) { break; } } } return npos; } template class EP, class TR> inline auto xbasic_fixed_string::rfind(const_pointer s, size_type pos) const -> size_type { return rfind(s, pos, traits_type::length(s)); } template class EP, class TR> inline auto xbasic_fixed_string::rfind(value_type ch, size_type pos) const -> size_type { return rfind((const_pointer)(&ch), pos, size_type(1)); } /***************** * find_first_of * *****************/ template class EP, class TR> inline auto xbasic_fixed_string::find_first_of(const self_type& str, size_type pos) const noexcept -> size_type { return find_first_of(str.data(), pos, str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::find_first_of(const string_type& str, size_type pos) const noexcept -> size_type { return find_first_of(str.data(), pos, str.size()); } template class EP, class TR> auto xbasic_fixed_string::find_first_of(const_pointer s, size_type pos, size_type count) const -> size_type { if (size_type(0) < count && pos < size()) { const_pointer vptr = data() + size(); for (const_pointer uptr = data() + pos; uptr < vptr; ++uptr) { if (traits_type::find(s, count, *uptr) != 0) { return size_type(uptr - data()); } } } return npos; } template class EP, class TR> inline auto xbasic_fixed_string::find_first_of(const_pointer s, size_type pos) const -> size_type { return find_first_of(s, pos, traits_type::length(s)); } template class EP, class TR> inline auto xbasic_fixed_string::find_first_of(value_type ch, size_type pos) const -> size_type { return find_first_of((const_pointer)(&ch), pos, size_type(1)); } /********************* * find_first_not_of * *********************/ template class EP, class TR> inline auto xbasic_fixed_string::find_first_not_of(const self_type& str, size_type pos) const noexcept -> size_type { return find_first_not_of(str.data(), pos, str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::find_first_not_of(const string_type& str, size_type pos) const noexcept -> size_type { return find_first_not_of(str.data(), pos, str.size()); } template class EP, class TR> auto xbasic_fixed_string::find_first_not_of(const_pointer s, size_type pos, size_type count) const -> size_type { if (pos < size()) { const_pointer vptr = data() + size(); for (const_pointer uptr = data() + pos; uptr < vptr; ++uptr) { if (traits_type::find(s, count, *uptr) == 0) { return size_type(uptr - data()); } } } return npos; } template class EP, class TR> inline auto xbasic_fixed_string::find_first_not_of(const_pointer s, size_type pos) const -> size_type { return find_first_not_of(s, pos, traits_type::length(s)); } template class EP, class TR> inline auto xbasic_fixed_string::find_first_not_of(value_type ch, size_type pos) const -> size_type { return find_first_not_of((const_pointer)(&ch), pos, size_type(1)); } /**************** * find_last_of * ****************/ template class EP, class TR> inline auto xbasic_fixed_string::find_last_of(const self_type& str, size_type pos) const noexcept -> size_type { return find_last_of(str.data(), pos, str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::find_last_of(const string_type& str, size_type pos) const noexcept -> size_type { return find_last_of(str.data(), pos, str.size()); } template class EP, class TR> auto xbasic_fixed_string::find_last_of(const_pointer s, size_type pos, size_type count) const -> size_type { if (size_type(0) < count && size_type(0) < size()) { const_pointer uptr = data() + std::min(pos, size() - 1); for (;; --uptr) { if (traits_type::find(s, count, *uptr) != 0) { return size_type(uptr - data()); } else if (uptr == data()) { break; } } } return npos; } template class EP, class TR> inline auto xbasic_fixed_string::find_last_of(const_pointer s, size_type pos) const -> size_type { return find_last_of(s, pos, traits_type::length(s)); } template class EP, class TR> inline auto xbasic_fixed_string::find_last_of(value_type ch, size_type pos) const -> size_type { return find_last_of((const_pointer)(&ch), pos, size_type(1)); } /******************** * find_last_not_of * ********************/ template class EP, class TR> inline auto xbasic_fixed_string::find_last_not_of(const self_type& str, size_type pos) const noexcept -> size_type { return find_last_not_of(str.data(), pos, str.size()); } template class EP, class TR> inline auto xbasic_fixed_string::find_last_not_of(const string_type& str, size_type pos) const noexcept -> size_type { return find_last_not_of(str.data(), pos, str.size()); } template class EP, class TR> auto xbasic_fixed_string::find_last_not_of(const_pointer s, size_type pos, size_type count) const -> size_type { if (size_type(0) < size()) { const_pointer uptr = data() + std::min(pos, size() - 1); for (;; --uptr) { if (traits_type::find(s, count, *uptr) == 0) { return size_type(uptr - data()); } else if (uptr == data()) { break; } } } return npos; } template class EP, class TR> inline auto xbasic_fixed_string::find_last_not_of(const_pointer s, size_type pos) const -> size_type { return find_last_not_of(s, pos, traits_type::length(s)); } template class EP, class TR> inline auto xbasic_fixed_string::find_last_not_of(value_type ch, size_type pos) const -> size_type { return find_last_not_of((const_pointer)(&ch), pos, size_type(1)); } /******************* * Private methods * *******************/ template class EP, class TR> int xbasic_fixed_string::compare_impl(const_pointer s1, size_type count1, const_pointer s2, size_type count2) const noexcept { size_type rlen = std::min(count1, count2); int res = traits_type::compare(s1, s2, rlen); if (res == 0) { return count1 < count2 ? -1 : (count1 > count2 ? 1 : 0); } else { return res; } } template class EP, class TR> inline void xbasic_fixed_string::update_null_termination() noexcept { data()[size()] = '\0'; } template class EP, class TR> void xbasic_fixed_string::check_index(size_type pos, size_type size, const char* what) const { if (pos >= size) { #if defined(XTL_NO_EXCEPTIONS) std::fprintf(stderr, "%s\n", what); std::terminate(); #else throw std::out_of_range(what); #endif } } template class EP, class TR> void xbasic_fixed_string::check_index_strict(size_type pos, size_type size, const char* what) const { check_index(pos, size + 1, what); } /************************** * Concatenation operator * **************************/ template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) { xbasic_fixed_string res(lhs); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, const CT* rhs) { xbasic_fixed_string res(lhs); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, CT rhs) { xbasic_fixed_string res(lhs); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(const CT* lhs, const xbasic_fixed_string& rhs) { xbasic_fixed_string res(lhs); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(CT lhs, const xbasic_fixed_string& rhs) { using size_type = typename xbasic_fixed_string::size_type; xbasic_fixed_string res(size_type(1), lhs); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, const xbasic_fixed_string& rhs) { xbasic_fixed_string res(std::move(lhs)); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string& lhs, const xbasic_fixed_string&& rhs) { xbasic_fixed_string res(lhs); return res += std::move(rhs); } template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, const xbasic_fixed_string&& rhs) { xbasic_fixed_string res(std::move(lhs)); return res += std::move(rhs); } template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, const CT* rhs) { xbasic_fixed_string res(std::move(lhs)); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(const xbasic_fixed_string&& lhs, CT rhs) { xbasic_fixed_string res(std::move(lhs)); return res += rhs; } template class EP, class TR> inline xbasic_fixed_string operator+(const CT* lhs, const xbasic_fixed_string&& rhs) { xbasic_fixed_string res(lhs); return res += std::move(rhs); } template class EP, class TR> inline xbasic_fixed_string operator+(CT lhs, const xbasic_fixed_string&& rhs) { using size_type = typename xbasic_fixed_string::size_type; xbasic_fixed_string res(size_type(1), lhs); return res += std::move(rhs); } /************************ * Comparison operators * ************************/ template class EP, class TR> inline bool operator==(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.compare(rhs) == 0; } template class EP, class TR> inline bool operator==(const xbasic_fixed_string& lhs, const CT* rhs) noexcept { return lhs.compare(rhs) == 0; } template class EP, class TR> inline bool operator==(const CT* lhs, const xbasic_fixed_string& rhs) noexcept { return rhs == lhs; } template class EP, class TR> inline bool operator==(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept { return lhs == rhs.c_str(); } template class EP, class TR> inline bool operator==(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.c_str() == rhs; } template class EP, class TR> inline bool operator!=(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.compare(rhs) != 0; } template class EP, class TR> inline bool operator!=(const xbasic_fixed_string& lhs, const CT* rhs) noexcept { return lhs.compare(rhs) != 0; } template class EP, class TR> inline bool operator!=(const CT* lhs, const xbasic_fixed_string& rhs) noexcept { return rhs != lhs; } template class EP, class TR> inline bool operator!=(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept { return lhs != rhs.c_str(); } template class EP, class TR> inline bool operator!=(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.c_str() != rhs; } template class EP, class TR> inline bool operator<(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.compare(rhs) < 0; } template class EP, class TR> inline bool operator<(const xbasic_fixed_string& lhs, const CT* rhs) noexcept { return lhs.compare(rhs) < 0; } template class EP, class TR> inline bool operator<(const CT* lhs, const xbasic_fixed_string& rhs) noexcept { return rhs > lhs; } template class EP, class TR> inline bool operator<(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept { return lhs < rhs.c_str(); } template class EP, class TR> inline bool operator<(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.c_str() < rhs; } template class EP, class TR> inline bool operator<=(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.compare(rhs) <= 0; } template class EP, class TR> inline bool operator<=(const xbasic_fixed_string& lhs, const CT* rhs) noexcept { return lhs.compare(rhs) <= 0; } template class EP, class TR> inline bool operator<=(const CT* lhs, const xbasic_fixed_string& rhs) noexcept { return rhs >= lhs; } template class EP, class TR> inline bool operator<=(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept { return lhs <= rhs.c_str(); } template class EP, class TR> inline bool operator<=(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.c_str() <= rhs; } template class EP, class TR> inline bool operator>(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.compare(rhs) > 0; } template class EP, class TR> inline bool operator>(const xbasic_fixed_string& lhs, const CT* rhs) noexcept { return lhs.compare(rhs) > 0; } template class EP, class TR> inline bool operator>(const CT* lhs, const xbasic_fixed_string& rhs) noexcept { return rhs < lhs; } template class EP, class TR> inline bool operator>(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept { return lhs > rhs.c_str(); } template class EP, class TR> inline bool operator>(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.c_str() > rhs; } template class EP, class TR> inline bool operator>=(const xbasic_fixed_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.compare(rhs) >= 0; } template class EP, class TR> inline bool operator>=(const xbasic_fixed_string& lhs, const CT* rhs) noexcept { return lhs.compare(rhs) >= 0; } template class EP, class TR> inline bool operator>=(const CT* lhs, const xbasic_fixed_string& rhs) noexcept { return rhs <= lhs; } template class EP, class TR> inline bool operator>=(const xbasic_fixed_string& lhs, const std::basic_string& rhs) noexcept { return lhs >= rhs.c_str(); } template class EP, class TR> inline bool operator>=(const std::basic_string& lhs, const xbasic_fixed_string& rhs) noexcept { return lhs.c_str() >= rhs; } template class EP, class TR> inline void swap(xbasic_fixed_string& lhs, xbasic_fixed_string& rhs) { lhs.swap(rhs); } /****************** * Input / output * ******************/ template class EP, class TR> inline std::basic_ostream& operator<<(std::basic_ostream& os, const xbasic_fixed_string& str) { os << str.c_str(); return os; } #ifdef __CLING__ template class EP, class TR> nlohmann::json mime_bundle_repr(const xbasic_fixed_string& str) { auto bundle = nlohmann::json::object(); bundle["text/plain"] = str.c_str(); return bundle; } #endif template class EP, class TR> inline std::basic_istream& operator>>(std::basic_istream& is, xbasic_fixed_string& str) { // Not optimal std::string tmp; is >> tmp; str = tmp.c_str(); return is; } template class EP, class TR> inline std::basic_istream& getline(std::basic_istream& input, xbasic_fixed_string& str, CT delim) { std::string tmp; auto& ret = std::getline(input, tmp, delim); str = tmp; return ret; } template class EP, class TR> inline std::basic_istream& getline(std::basic_istream&& input, xbasic_fixed_string& str, CT delim) { std::string tmp; auto& ret = std::getline(std::move(input), tmp, delim); str = tmp; return ret; } template class EP, class TR> inline std::basic_istream& getline(std::basic_istream& input, xbasic_fixed_string& str) { std::string tmp; auto& ret = std::getline(input, tmp); str = tmp; return ret; } template class EP, class TR> inline std::basic_istream& getline(std::basic_istream&& input, xbasic_fixed_string& str) { std::string tmp; auto& ret = std::getline(std::move(input), tmp); str = tmp; return ret; } } #endif // xtl xtl-0.6.9/include/xtl/xclosure.hpp000066400000000000000000000306071357123723600171630ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Sylvain Corlay and Johan Mabille and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_CLOSURE_HPP #define XTL_CLOSURE_HPP #include #include #include #include "xtl_config.hpp" namespace xtl { #ifdef __cpp_lib_as_const using std::as_const; #else template constexpr std::add_const_t& as_const(T& t) noexcept { return t; } template constexpr std::add_const_t& as_const(T&& t) noexcept = delete; #endif /**************** * closure_type * ****************/ template struct closure_type { using underlying_type = std::conditional_t>::value, const std::decay_t, std::decay_t>; using type = typename std::conditional::value, underlying_type&, underlying_type>::type; }; template using closure_type_t = typename closure_type::type; template struct const_closure_type { using underlying_type = std::decay_t; using type = typename std::conditional::value, std::add_const_t&, underlying_type>::type; }; template using const_closure_type_t = typename const_closure_type::type; /**************************** * ptr_closure_closure_type * ****************************/ template struct ptr_closure_type { using underlying_type = std::conditional_t>::value, const std::decay_t, std::decay_t>; using type = std::conditional_t::value, underlying_type*, underlying_type>; }; template using ptr_closure_type_t = typename ptr_closure_type::type; template struct const_ptr_closure_type { using underlying_type = const std::decay_t; using type = std::conditional_t::value, underlying_type*, underlying_type>; }; template using const_ptr_closure_type_t = typename const_ptr_closure_type::type; /******************** * xclosure_wrapper * ********************/ template class xclosure_wrapper { public: using self_type = xclosure_wrapper; using closure_type = CT; using const_closure_type = std::add_const_t; using value_type = std::decay_t; using reference = std::conditional_t< std::is_const>::value, const value_type&, value_type& >; using pointer = std::conditional_t< std::is_const>::value, const value_type*, value_type* >; xclosure_wrapper(value_type&& e); xclosure_wrapper(reference e); xclosure_wrapper(const self_type& rhs) = default; xclosure_wrapper(self_type&& rhs) = default; self_type& operator=(const self_type& rhs); self_type& operator=(self_type&& rhs); template self_type& operator=(T&&); operator closure_type() noexcept; operator const_closure_type() const noexcept; std::add_lvalue_reference_t get() & noexcept; std::add_lvalue_reference_t> get() const & noexcept; closure_type get() && noexcept; pointer operator&() noexcept; bool equal(const self_type& rhs) const; void swap(self_type& rhs); private: using storing_type = ptr_closure_type_t; storing_type m_wrappee; template std::enable_if_t::value, std::add_lvalue_reference_t>> deref(T val) const; template std::enable_if_t::value, std::add_lvalue_reference_t> deref(T& val) const; template std::enable_if_t::value, T> get_pointer(T val) const; template std::enable_if_t::value, std::add_pointer_t> get_pointer(T& val) const; template std::enable_if_t::value, T> get_storage_init(CTA&& e) const; template std::enable_if_t::value, T> get_storage_init(CTA&& e) const; }; // TODO: remove this (backward compatibility) template using closure_wrapper = xclosure_wrapper; /******************** * xclosure_pointer * ********************/ template class xclosure_pointer { public: using self_type = xclosure_pointer; using closure_type = CT; using value_type = std::decay_t; using reference = std::conditional_t< std::is_const>::value, const value_type&, value_type& >; using const_reference = const value_type&; using pointer = std::conditional_t< std::is_const>::value, const value_type*, value_type* >; xclosure_pointer(value_type&& e); xclosure_pointer(reference e); reference operator*() noexcept; const_reference operator*() const noexcept; pointer operator->() const noexcept; private: using storing_type = closure_type_t; storing_type m_wrappee; }; /*********************************** * xclosure_wrapper implementation * ***********************************/ template inline xclosure_wrapper::xclosure_wrapper(value_type&& e) : m_wrappee(get_storage_init(std::move(e))) { } template inline xclosure_wrapper::xclosure_wrapper(reference e) : m_wrappee(get_storage_init(e)) { } template inline auto xclosure_wrapper::operator=(const self_type& rhs) -> self_type& { deref(m_wrappee) = deref(rhs.m_wrappee); return *this; } template inline auto xclosure_wrapper::operator=(self_type&& rhs) -> self_type& { swap(rhs); return *this; } template template inline auto xclosure_wrapper::operator=(T&& t) -> self_type& { deref(m_wrappee) = std::forward(t); return *this; } template inline xclosure_wrapper::operator typename xclosure_wrapper::closure_type() noexcept { return deref(m_wrappee); } template inline xclosure_wrapper::operator typename xclosure_wrapper::const_closure_type() const noexcept { return deref(m_wrappee); } template inline auto xclosure_wrapper::get() & noexcept -> std::add_lvalue_reference_t { return deref(m_wrappee); } template inline auto xclosure_wrapper::get() const & noexcept -> std::add_lvalue_reference_t> { return deref(m_wrappee); } template inline auto xclosure_wrapper::get() && noexcept -> closure_type { return deref(m_wrappee); } template inline auto xclosure_wrapper::operator&() noexcept -> pointer { return get_pointer(m_wrappee); } template template inline std::enable_if_t::value, std::add_lvalue_reference_t>> xclosure_wrapper::deref(T val) const { return *val; } template template inline std::enable_if_t::value, std::add_lvalue_reference_t> xclosure_wrapper::deref(T& val) const { return val; } template template inline std::enable_if_t::value, T> xclosure_wrapper::get_pointer(T val) const { return val; } template template inline std::enable_if_t::value, std::add_pointer_t> xclosure_wrapper::get_pointer(T& val) const { return &val; } template template inline std::enable_if_t::value, T> xclosure_wrapper::get_storage_init(CTA&& e) const { return &e; } template template inline std::enable_if_t::value, T> xclosure_wrapper::get_storage_init(CTA&& e) const { return e; } template inline bool xclosure_wrapper::equal(const self_type& rhs) const { return deref(m_wrappee) == rhs.deref(rhs.m_wrappee); } template inline void xclosure_wrapper::swap(self_type& rhs) { using std::swap; swap(deref(m_wrappee), deref(rhs.m_wrappee)); } template inline bool operator==(const xclosure_wrapper& lhs, const xclosure_wrapper& rhs) { return lhs.equal(rhs); } template inline bool operator!=(const xclosure_wrapper& lhs, const xclosure_wrapper& rhs) { return !(lhs == rhs); } template inline void swap(xclosure_wrapper& lhs, xclosure_wrapper& rhs) { lhs.swap(rhs); } /*********************************** * xclosure_pointer implementation * ***********************************/ template inline xclosure_pointer::xclosure_pointer(value_type&& e) : m_wrappee(std::move(e)) { } template inline xclosure_pointer::xclosure_pointer(reference e) : m_wrappee(e) { } template inline auto xclosure_pointer::operator*() noexcept -> reference { return m_wrappee; } template inline auto xclosure_pointer::operator*() const noexcept -> const_reference { return m_wrappee; } template inline auto xclosure_pointer::operator->() const noexcept -> pointer { return const_cast(std::addressof(m_wrappee)); } /***************************** * closure and const_closure * *****************************/ template inline decltype(auto) closure(T&& t) { return xclosure_wrapper>(std::forward(t)); } template inline decltype(auto) const_closure(T&& t) { return xclosure_wrapper>(std::forward(t)); } /******************************************** * closure_pointer et const_closure_pointer * ********************************************/ template inline auto closure_pointer(T&& t) { return xclosure_pointer>(std::forward(t)); } template inline auto const_closure_pointer(T&& t) { return xclosure_pointer>(std::forward(t)); } } #endif xtl-0.6.9/include/xtl/xcomplex.hpp000066400000000000000000001350551357123723600171610ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Sylvain Corlay and Johan Mabille and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_COMPLEX_HPP #define XTL_COMPLEX_HPP #if !defined(_MSC_VER) #include using std::copysign; #endif #include #include #include #include #include #include #include #ifdef __CLING__ #include #endif #include "xclosure.hpp" #include "xtl_config.hpp" #include "xtype_traits.hpp" namespace xtl { template class xcomplex; /************** * is_complex * **************/ namespace detail { template struct is_complex : std::false_type { }; template struct is_complex> : std::true_type { }; } template struct is_complex { static constexpr bool value = detail::is_complex>::value; }; /*************** * is_xcomplex * ***************/ namespace detail { template struct is_xcomplex : std::false_type { }; template struct is_xcomplex> : std::true_type { }; } template struct is_xcomplex { static constexpr bool value = detail::is_xcomplex>::value; }; /****************** * is_gen_complex * ******************/ template using is_gen_complex = disjunction>, is_xcomplex>>; /**************************** * enable / disable complex * ****************************/ template using disable_xcomplex = std::enable_if_t::value, R>; template using enable_xcomplex = std::enable_if_t::value, R>; /***************** * enable_scalar * *****************/ template using enable_scalar = std::enable_if_t::value, R>; /******************* * common_xcomplex * *******************/ template struct common_xcomplex { using type = xcomplex, std::common_type_t, ieee1 || ieee2>; }; template using common_xcomplex_t = typename common_xcomplex::type; /********************** * temporary_xcomplex * **********************/ template struct temporary_xcomplex { using type = xcomplex, std::decay_t, ieee>; }; template using temporary_xcomplex_t = typename temporary_xcomplex::type; /************ * xcomplex * ************/ template class xcomplex { public: static_assert(std::is_same, std::decay_t>::value, "closure types must have the same value type"); using value_type = std::common_type_t; using self_type = xcomplex; using temporary_type = temporary_xcomplex_t; using real_reference = std::add_lvalue_reference_t; using real_const_reference = std::add_lvalue_reference_t>; using real_rvalue_reference = std::conditional_t::value, apply_cv_t&, value_type>; using real_rvalue_const_reference = std::conditional_t::value, const value_type&, value_type>; using imag_reference = std::add_lvalue_reference_t; using imag_const_reference = std::add_lvalue_reference_t>; using imag_rvalue_reference = std::conditional_t::value, apply_cv_t&, value_type>; using imag_rvalue_const_reference = std::conditional_t::value, const value_type&, value_type>; constexpr xcomplex() noexcept : m_real(), m_imag() { } template >, std::is_constructible, std::is_convertible >::value, bool > = true> constexpr xcomplex(OCTR&& re) noexcept : m_real(std::forward(re)), m_imag() { } template >, std::is_constructible, negation> >::value, bool > = true> explicit constexpr xcomplex(OCTR&& re) noexcept : m_real(std::forward(re)), m_imag() { } template explicit constexpr xcomplex(OCTR&& re, OCTI&& im) noexcept : m_real(std::forward(re)), m_imag(std::forward(im)) { } template explicit constexpr xcomplex(const xcomplex& rhs) noexcept : m_real(rhs.real()), m_imag(rhs.imag()) { } template explicit constexpr xcomplex(xcomplex&& rhs) noexcept : m_real(std::move(rhs).real()), m_imag(std::move(rhs).imag()) { } template constexpr xcomplex(const std::complex& rhs) noexcept : m_real(rhs.real()), m_imag(rhs.imag()) { } template constexpr xcomplex(std::complex&& rhs) noexcept : m_real(std::move(rhs).real()), m_imag(std::move(rhs).imag()) { } template disable_xcomplex operator=(OCTR&& rhs) noexcept; template self_type& operator=(const xcomplex& rhs) noexcept; template self_type& operator=(xcomplex&& rhs) noexcept; operator std::complex>() const noexcept; template self_type& operator+=(const xcomplex& rhs) noexcept; template self_type& operator-=(const xcomplex& rhs) noexcept; template self_type& operator*=(const xcomplex& rhs) noexcept; template self_type& operator/=(const xcomplex& rhs) noexcept; template disable_xcomplex operator+=(const T& rhs) noexcept; template disable_xcomplex operator-=(const T& rhs) noexcept; template disable_xcomplex operator*=(const T& rhs) noexcept; template disable_xcomplex operator/=(const T& rhs) noexcept; real_reference real() & noexcept; real_rvalue_reference real() && noexcept; constexpr real_const_reference real() const & noexcept; constexpr real_rvalue_const_reference real() const && noexcept; imag_reference imag() & noexcept; imag_rvalue_reference imag() && noexcept; constexpr imag_const_reference imag() const & noexcept; constexpr imag_rvalue_const_reference imag() const && noexcept; xclosure_pointer operator&() & noexcept; xclosure_pointer operator&() const & noexcept; xclosure_pointer operator&() && noexcept; private: CTR m_real; CTI m_imag; }; /********************** * xcomplex operators * **********************/ template bool operator==(const xcomplex& lhs, const xcomplex& rhs) noexcept; template bool operator!=(const xcomplex& lhs, const xcomplex& rhs) noexcept; template std::basic_ostream& operator<<(std::basic_ostream& out, const xcomplex& c) noexcept; template temporary_xcomplex_t operator+(const xcomplex& rhs) noexcept; template temporary_xcomplex_t operator-(const xcomplex& rhs) noexcept; template common_xcomplex_t operator+(const xcomplex& lhs, const xcomplex& rhs) noexcept; template enable_scalar> operator+(const xcomplex& lhs, const T& rhs) noexcept; template enable_scalar> operator+(const T& lhs, const xcomplex& rhs) noexcept; template common_xcomplex_t operator-(const xcomplex& lhs, const xcomplex& rhs) noexcept; template enable_scalar> operator-(const xcomplex& lhs, const T& rhs) noexcept; template enable_scalar> operator-(const T& lhs, const xcomplex& rhs) noexcept; template common_xcomplex_t operator*(const xcomplex& lhs, const xcomplex& rhs) noexcept; template enable_scalar> operator*(const xcomplex& lhs, const T& rhs) noexcept; template enable_scalar> operator*(const T& lhs, const xcomplex& rhs) noexcept; template common_xcomplex_t operator/(const xcomplex& lhs, const xcomplex& rhs) noexcept; template enable_scalar> operator/(const xcomplex& lhs, const T& rhs) noexcept; template enable_scalar> operator/(const T& lhs, const xcomplex& rhs) noexcept; /***************** * real and imag * *****************/ template decltype(auto) real(E&& e) noexcept; template decltype(auto) imag(E&& e) noexcept; /*************************** * xcomplex free functions * ***************************/ template typename xcomplex::value_type abs(const xcomplex& rhs); template typename xcomplex::value_type arg(const xcomplex& rhs); template typename xcomplex::value_type norm(const xcomplex& rhs); template temporary_xcomplex_t conj(const xcomplex& rhs); template temporary_xcomplex_t proj(const xcomplex& rhs); /********************************** * xcomplex exponential functions * **********************************/ template temporary_xcomplex_t exp(const xcomplex& rhs); template temporary_xcomplex_t log(const xcomplex& rhs); template temporary_xcomplex_t log10(const xcomplex& rhs); /**************************** * xcomplex power functions * ****************************/ template common_xcomplex_t pow(const xcomplex& x, const xcomplex& y); template enable_scalar> pow(const xcomplex& x, const T& y); template enable_scalar> pow(const T& x, const xcomplex& y); template temporary_xcomplex_t sqrt(const xcomplex& x); /************************************ * xcomplex trigonometric functions * ************************************/ template temporary_xcomplex_t sin(const xcomplex& x); template temporary_xcomplex_t cos(const xcomplex& x); template temporary_xcomplex_t tan(const xcomplex& x); template temporary_xcomplex_t asin(const xcomplex& x); template temporary_xcomplex_t acos(const xcomplex& x); template temporary_xcomplex_t atan(const xcomplex& x); /********************************* * xcomplex hyperbolic functions * *********************************/ template temporary_xcomplex_t sinh(const xcomplex& x); template temporary_xcomplex_t cosh(const xcomplex& x); template temporary_xcomplex_t tanh(const xcomplex& x); template temporary_xcomplex_t asinh(const xcomplex& x); template temporary_xcomplex_t acosh(const xcomplex& x); template temporary_xcomplex_t atanh(const xcomplex& x); /*************************** * xcomplex implementation * ***************************/ template template inline auto xcomplex::operator=(OCTR&& rhs) noexcept -> disable_xcomplex { m_real = std::forward(rhs); m_imag = std::decay_t(); return *this; } template template inline auto xcomplex::operator=(const xcomplex& rhs) noexcept -> self_type& { m_real = rhs.m_real; m_imag = rhs.m_imag; return *this; } template template inline auto xcomplex::operator=(xcomplex&& rhs) noexcept -> self_type& { m_real = std::move(rhs.m_real); m_imag = std::move(rhs.m_imag); return *this; } template inline xcomplex::operator std::complex>() const noexcept { return std::complex>(m_real, m_imag); } template template inline auto xcomplex::operator+=(const xcomplex& rhs) noexcept -> self_type& { m_real += rhs.m_real; m_imag += rhs.m_imag; return *this; } template template inline auto xcomplex::operator-=(const xcomplex& rhs) noexcept -> self_type& { m_real -= rhs.m_real; m_imag -= rhs.m_imag; return *this; } namespace detail { template struct xcomplex_multiplier { template static auto mul(const xcomplex& lhs, const xcomplex& rhs) { using return_type = temporary_xcomplex_t; using value_type = typename return_type::value_type; value_type a = lhs.real(); value_type b = lhs.imag(); value_type c = rhs.real(); value_type d = rhs.imag(); return return_type(a*c - b*d, a*d + b*c); } template static auto div(const xcomplex& lhs, const xcomplex& rhs) { using return_type = temporary_xcomplex_t; using value_type = typename return_type::value_type; value_type a = lhs.real(); value_type b = lhs.imag(); value_type c = rhs.real(); value_type d = rhs.imag(); value_type e = c*c + d*d; return return_type((c*a + d*b) / e, (c*b - d*a) / e); } }; template <> struct xcomplex_multiplier { template static auto mul(const xcomplex& lhs, const xcomplex& rhs) { using return_type = temporary_xcomplex_t; using value_type = typename return_type::value_type; value_type a = lhs.real(); value_type b = lhs.imag(); value_type c = rhs.real(); value_type d = rhs.imag(); value_type ac = a * c; value_type bd = b * d; value_type ad = a * d; value_type bc = b * c; value_type x = ac - bd; value_type y = ad + bc; if (std::isnan(x) && std::isnan(y)) { bool recalc = false; if (std::isinf(a) || std::isinf(b)) { a = copysign(std::isinf(a) ? value_type(1) : value_type(0), a); b = copysign(std::isinf(b) ? value_type(1) : value_type(0), b); if (std::isnan(c)) { c = copysign(value_type(0), c); } if (std::isnan(d)) { d = copysign(value_type(0), d); } recalc = true; } if (std::isinf(c) || std::isinf(d)) { c = copysign(std::isinf(c) ? value_type(1) : value_type(0), c); d = copysign(std::isinf(c) ? value_type(1) : value_type(0), d); if (std::isnan(a)) { a = copysign(value_type(0), a); } if (std::isnan(b)) { b = copysign(value_type(0), b); } recalc = true; } if (!recalc && (std::isinf(ac) || std::isinf(bd) || std::isinf(ad) || std::isinf(bc))) { if (std::isnan(a)) { a = copysign(value_type(0), a); } if (std::isnan(b)) { b = copysign(value_type(0), b); } if (std::isnan(c)) { c = copysign(value_type(0), c); } if (std::isnan(d)) { d = copysign(value_type(0), d); } recalc = true; } if (recalc) { x = std::numeric_limits::infinity() * (a * c - b * d); y = std::numeric_limits::infinity() * (a * d + b * c); } } return return_type(x, y); } template static auto div(const xcomplex& lhs, const xcomplex& rhs) { using return_type = temporary_xcomplex_t; using value_type = typename return_type::value_type; value_type a = lhs.real(); value_type b = lhs.imag(); value_type c = rhs.real(); value_type d = rhs.imag(); value_type logbw = std::logb(std::fmax(std::fabs(c), std::fabs(d))); int ilogbw = 0; if (std::isfinite(logbw)) { ilogbw = static_cast(logbw); c = std::scalbn(c, -ilogbw); d = std::scalbn(d, -ilogbw); } value_type denom = c*c + d*d; value_type x = std::scalbn((a*c + b*d) / denom, -ilogbw); value_type y = std::scalbn((b*c - a*d) / denom, -ilogbw); if (std::isnan(x) && std::isnan(y)) { if ((denom == value_type(0)) && (!std::isnan(a) || !std::isnan(b))) { x = copysign(std::numeric_limits::infinity(), c) * a; y = copysign(std::numeric_limits::infinity(), c) * b; } else if ((std::isinf(a) || std::isinf(b)) && std::isfinite(c) && std::isfinite(d)) { a = copysign(std::isinf(a) ? value_type(1) : value_type(0), a); b = copysign(std::isinf(b) ? value_type(1) : value_type(0), b); x = std::numeric_limits::infinity() * (a*c + b*d); y = std::numeric_limits::infinity() * (b*c - a*d); } else if (std::isinf(logbw) && logbw > value_type(0) && std::isfinite(a) && std::isfinite(b)) { c = copysign(std::isinf(c) ? value_type(1) : value_type(0), c); d = copysign(std::isinf(d) ? value_type(1) : value_type(0), d); x = value_type(0) * (a*c + b*d); y = value_type(0) * (b*c - a*d); } } return std::complex(x, y); } }; } template template inline auto xcomplex::operator*=(const xcomplex& rhs) noexcept -> self_type& { *this = detail::xcomplex_multiplier::mul(*this, rhs); return *this; } template template inline auto xcomplex::operator/=(const xcomplex& rhs) noexcept -> self_type& { *this = detail::xcomplex_multiplier::div(*this, rhs); return *this; } template template inline auto xcomplex::operator+=(const T& rhs) noexcept -> disable_xcomplex { m_real += rhs; return *this; } template template inline auto xcomplex::operator-=(const T& rhs) noexcept -> disable_xcomplex { m_real -= rhs; return *this; } template template inline auto xcomplex::operator*=(const T& rhs) noexcept -> disable_xcomplex { m_real *= rhs; m_imag *= rhs; return *this; } template template inline auto xcomplex::operator/=(const T& rhs) noexcept -> disable_xcomplex { m_real /= rhs; m_imag /= rhs; return *this; } template auto xcomplex::real() & noexcept -> real_reference { return m_real; } template auto xcomplex::real() && noexcept -> real_rvalue_reference { return m_real; } template constexpr auto xcomplex::real() const & noexcept -> real_const_reference { return m_real; } template constexpr auto xcomplex::real() const && noexcept -> real_rvalue_const_reference { return m_real; } template auto xcomplex::imag() & noexcept -> imag_reference { return m_imag; } template auto xcomplex::imag() && noexcept -> imag_rvalue_reference { return m_imag; } template constexpr auto xcomplex::imag() const & noexcept -> imag_const_reference { return m_imag; } template constexpr auto xcomplex::imag() const && noexcept -> imag_rvalue_const_reference { return m_imag; } template inline auto xcomplex::operator&() & noexcept -> xclosure_pointer { return xclosure_pointer(*this); } template inline auto xcomplex::operator&() const & noexcept -> xclosure_pointer { return xclosure_pointer(*this); } template inline auto xcomplex::operator&() && noexcept -> xclosure_pointer { return xclosure_pointer(std::move(*this)); } /************************************* * xcomplex operators implementation * *************************************/ template inline bool operator==(const xcomplex& lhs, const xcomplex& rhs) noexcept { return lhs.real() == rhs.real() && lhs.imag() == rhs.imag(); } template inline bool operator!=(const xcomplex& lhs, const xcomplex& rhs) noexcept { return !(lhs == rhs); } template inline std::basic_ostream& operator<<(std::basic_ostream& out, const xcomplex& c) noexcept { out << "(" << c.real() << "," << c.imag() << ")"; return out; } #ifdef __CLING__ template nlohmann::json mime_bundle_repr(const xcomplex& c) { auto bundle = nlohmann::json::object(); std::stringstream tmp; tmp << c; bundle["text/plain"] = tmp.str(); return bundle; } #endif template inline temporary_xcomplex_t operator+(const xcomplex& rhs) noexcept { return rhs; } template inline temporary_xcomplex_t operator-(const xcomplex& rhs) noexcept { return temporary_xcomplex_t(-rhs.real(), -rhs.imag()); } template inline common_xcomplex_t operator+(const xcomplex& lhs, const xcomplex& rhs) noexcept { common_xcomplex_t res(lhs); res += rhs; return res; } template inline enable_scalar> operator+(const xcomplex& lhs, const T& rhs) noexcept { temporary_xcomplex_t res(lhs); res += rhs; return res; } template inline enable_scalar> operator+(const T& lhs, const xcomplex& rhs) noexcept { temporary_xcomplex_t res(lhs); res += rhs; return res; } template inline common_xcomplex_t operator-(const xcomplex& lhs, const xcomplex& rhs) noexcept { common_xcomplex_t res(lhs); res -= rhs; return res; } template inline enable_scalar> operator-(const xcomplex& lhs, const T& rhs) noexcept { temporary_xcomplex_t res(lhs); res -= rhs; return res; } template inline enable_scalar> operator-(const T& lhs, const xcomplex& rhs) noexcept { temporary_xcomplex_t res(lhs); res -= rhs; return res; } template inline common_xcomplex_t operator*(const xcomplex& lhs, const xcomplex& rhs) noexcept { common_xcomplex_t res(lhs); res *= rhs; return res; } template inline enable_scalar> operator*(const xcomplex& lhs, const T& rhs) noexcept { temporary_xcomplex_t res(lhs); res *= rhs; return res; } template inline enable_scalar> operator*(const T& lhs, const xcomplex& rhs) noexcept { temporary_xcomplex_t res(lhs); res *= rhs; return res; } template inline common_xcomplex_t operator/(const xcomplex& lhs, const xcomplex& rhs) noexcept { common_xcomplex_t res(lhs); res /= rhs; return res; } template inline enable_scalar> operator/(const xcomplex& lhs, const T& rhs) noexcept { temporary_xcomplex_t res(lhs); res /= rhs; return res; } template inline enable_scalar> operator/(const T& lhs, const xcomplex& rhs) noexcept { temporary_xcomplex_t res(lhs); res /= rhs; return res; } /*************************** * xcomplex free functions * ***************************/ template inline typename xcomplex::value_type abs(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::abs(std::complex(rhs)); } template inline typename xcomplex::value_type arg(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::arg(std::complex(rhs)); } template inline typename xcomplex::value_type norm(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::norm(std::complex(rhs)); } template inline temporary_xcomplex_t conj(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::conj(std::complex(rhs)); } template inline temporary_xcomplex_t proj(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::proj(std::complex(rhs)); } /************************************************* * xcomplex exponential functions implementation * *************************************************/ template inline temporary_xcomplex_t exp(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::exp(std::complex(rhs)); } template inline temporary_xcomplex_t log(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::log(std::complex(rhs)); } template inline temporary_xcomplex_t log10(const xcomplex& rhs) { using value_type = typename xcomplex::value_type; return std::log10(std::complex(rhs)); } /******************************************* * xcomplex power functions implementation * *******************************************/ template inline common_xcomplex_t pow(const xcomplex& x, const xcomplex& y) { using value_type1 = typename xcomplex::value_type; using value_type2 = typename xcomplex::value_type; return std::pow(std::complex(x), std::complex(y)); } template inline enable_scalar> pow(const xcomplex& x, const T& y) { using value_type = typename xcomplex::value_type; return std::pow(std::complex(x), y); } template inline enable_scalar> pow(const T& x, const xcomplex& y) { using value_type = typename xcomplex::value_type; return std::pow(x, std::complex(y)); } template inline temporary_xcomplex_t sqrt(const xcomplex& x) { using value_type = typename xcomplex::value_type; return std::sqrt(std::complex(x)); } /*************************************************** * xcomplex trigonometric functions implementation * ***************************************************/ template inline temporary_xcomplex_t sin(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::sin(std::complex(x)); } template inline temporary_xcomplex_t cos(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::cos(std::complex(x)); } template inline temporary_xcomplex_t tan(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::tan(std::complex(x)); } template inline temporary_xcomplex_t asin(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::asin(std::complex(x)); } template inline temporary_xcomplex_t acos(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::acos(std::complex(x)); } template inline temporary_xcomplex_t atan(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::atan(std::complex(x)); } /************************************************ * xcomplex hyperbolic functions implementation * ************************************************/ template inline temporary_xcomplex_t sinh(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::sinh(std::complex(x)); } template inline temporary_xcomplex_t cosh(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::cosh(std::complex(x)); } template inline temporary_xcomplex_t tanh(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::tanh(std::complex(x)); } template inline temporary_xcomplex_t asinh(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::asinh(std::complex(x)); } template inline temporary_xcomplex_t acosh(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::acosh(std::complex(x)); } template inline temporary_xcomplex_t atanh(const xcomplex& x) { using value_type = typename temporary_xcomplex_t::value_type; return std::atanh(std::complex(x)); } /********************************* * forward_offset implementation * *********************************/ namespace detail { template struct forward_type { using type = apply_cv_t; }; template struct forward_type { using type = apply_cv_t&; }; template using forward_type_t = typename forward_type::type; } template constexpr detail::forward_type_t forward_offset(T&& v) noexcept { using forward_type = detail::forward_type_t; using cv_value_type = std::remove_reference_t; using byte_type = apply_cv_t, char>; return static_cast( *reinterpret_cast( reinterpret_cast(&v) + I ) ); } /********************************************** * forward_real & forward_imag implementation * **********************************************/ // forward_real template auto forward_real(T&& v) -> std::enable_if_t::value, detail::forward_type_t> // real case -> forward { return static_cast>(v); } template auto forward_real(T&& v) -> std::enable_if_t::value, detail::forward_type_t::value_type>> // complex case -> forward the real part { return forward_offset::value_type, 0>(v); } template auto forward_real(T&& v) -> std::enable_if_t::value, decltype(std::forward(v).real())> { return std::forward(v).real(); } // forward_imag template auto forward_imag(T &&) -> std::enable_if_t::value, std::decay_t> // real case -> always return 0 by value { return 0; } template auto forward_imag(T&& v) -> std::enable_if_t::value, detail::forward_type_t::value_type>> // complex case -> forwards the imaginary part { using real_type = typename std::decay_t::value_type; return forward_offset(v); } template auto forward_imag(T&& v) -> std::enable_if_t::value, decltype(std::forward(v).imag())> { return std::forward(v).imag(); } /****************************** * real & imag implementation * ******************************/ template inline decltype(auto) real(E&& e) noexcept { return forward_real(std::forward(e)); } template inline decltype(auto) imag(E&& e) noexcept { return forward_imag(std::forward(e)); } /********************** * complex_value_type * **********************/ template struct complex_value_type { using type = T; }; template struct complex_value_type> { using type = T; }; template struct complex_value_type> { using type = xcomplex; }; template using complex_value_type_t = typename complex_value_type::type; /****************************************************** * operator overloads for complex and closure wrapper * *****************************************************/ template ::value, int> = 0> std::complex operator+(const std::complex& c, const T& t) { std::complex result(c); result += t; return result; } template ::value, int> = 0> std::complex operator+(const T& t, const std::complex& c) { std::complex result(t); result += c; return result; } template ::value, int> = 0> std::complex operator-(const std::complex& c, const T& t) { std::complex result(c); result -= t; return result; } template ::value, int> = 0> std::complex operator-(const T& t, const std::complex& c) { std::complex result(t); result -= c; return result; } template ::value, int> = 0> std::complex operator*(const std::complex& c, const T& t) { std::complex result(c); result *= t; return result; } template ::value, int> = 0> std::complex operator*(const T& t, const std::complex& c) { std::complex result(t); result *= c; return result; } template ::value, int> = 0> std::complex operator/(const std::complex& c, const T& t) { std::complex result(c); result /= t; return result; } template ::value, int> = 0> std::complex operator/(const T& t, const std::complex& c) { std::complex result(t); result /= c; return result; } } #endif xtl-0.6.9/include/xtl/xcomplex_sequence.hpp000066400000000000000000000434071357123723600210500ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_XCOMPLEX_SEQUENCE_HPP #define XTL_XCOMPLEX_SEQUENCE_HPP #include #include #include #include "xclosure.hpp" #include "xcomplex.hpp" #include "xiterator_base.hpp" #include "xsequence.hpp" namespace xtl { /************************************ * Optimized 1-D xcomplex container * ************************************/ template class xcomplex_iterator; template class xcomplex_sequence { public: using container_type = C; using cvt = typename C::value_type; using value_type = xcomplex; using reference = xcomplex; using const_reference = xcomplex; using pointer = xclosure_pointer; using const_pointer = xclosure_pointer; using size_type = typename container_type::size_type; using difference_type = typename container_type::difference_type; using iterator = xcomplex_iterator; using const_iterator = xcomplex_iterator; using reverse_iterator = xcomplex_iterator; using const_reverse_iterator = xcomplex_iterator; bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; reference at(size_type i); const_reference at(size_type i) const; reference operator[](size_type i); const_reference operator[](size_type i) const; reference front(); const_reference front() const; reference back(); const_reference back() const; iterator begin() noexcept; iterator end() noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; reverse_iterator rbegin() noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; container_type real() && noexcept; container_type& real() & noexcept; const container_type& real() const & noexcept; container_type imag() && noexcept; container_type& imag() & noexcept; const container_type& imag() const & noexcept; protected: xcomplex_sequence() = default; xcomplex_sequence(size_type s); xcomplex_sequence(size_type s, const value_type& v); template xcomplex_sequence(size_type s, const xcomplex& v); xcomplex_sequence(std::initializer_list init); ~xcomplex_sequence() = default; xcomplex_sequence(const xcomplex_sequence&) = default; xcomplex_sequence& operator=(const xcomplex_sequence&) = default; xcomplex_sequence(xcomplex_sequence&&) = default; xcomplex_sequence& operator=(xcomplex_sequence&&) = default; container_type m_real; container_type m_imag; }; template bool operator==(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs); template bool operator!=(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs); /****************** * xcomplex_array * ******************/ template class xcomplex_array : public xcomplex_sequence, ieee_compliant> { public: using base_type = xcomplex_sequence, ieee_compliant>; using value_type = typename base_type::value_type; using size_type = typename base_type::size_type; xcomplex_array() = default; xcomplex_array(size_type s); xcomplex_array(size_type s, const value_type& v); template xcomplex_array(size_type s, const xcomplex& v); }; /******************* * xcomplex_vector * *******************/ template > class xcomplex_vector : public xcomplex_sequence, ieee_compliant> { public: using base_type = xcomplex_sequence, ieee_compliant>; using value_type = typename base_type::value_type; using size_type = typename base_type::size_type; xcomplex_vector() = default; xcomplex_vector(size_type s); xcomplex_vector(size_type s, const value_type& v); xcomplex_vector(std::initializer_list init); template xcomplex_vector(size_type s, const xcomplex& v); void resize(size_type); void resize(size_type, const value_type&); template void resize(size_type s, const xcomplex& v); }; /********************* * xcomplex_iterator * *********************/ template struct xcomplex_iterator_traits { using iterator_type = xcomplex_iterator; using value_type = xcomplex; using reference = xcomplex; using pointer = xclosure_pointer; using difference_type = typename IT::difference_type; }; template class xcomplex_iterator : public xrandom_access_iterator_base2> { public: using self_type = xcomplex_iterator; using base_type = xrandom_access_iterator_base2>; using value_type = typename base_type::value_type; using reference = typename base_type::reference; using pointer = typename base_type::pointer; using difference_type = typename base_type::difference_type; xcomplex_iterator() = default; xcomplex_iterator(IT it_real, IT it_imag); self_type& operator++(); self_type& operator--(); self_type& operator+=(difference_type n); self_type& operator-=(difference_type n); difference_type operator-(const self_type& rhs) const; reference operator*() const; pointer operator->() const; bool operator==(const self_type& rhs) const; private: IT m_it_real; IT m_it_imag; }; /************************************ * xcomplex_sequence implementation * ************************************/ template inline xcomplex_sequence::xcomplex_sequence(size_type s) : m_real(make_sequence(s)), m_imag(make_sequence(s)) { } template inline xcomplex_sequence::xcomplex_sequence(size_type s, const value_type& v) : m_real(make_sequence(s, v.real())), m_imag(make_sequence(s, v.imag())) { } template template inline xcomplex_sequence::xcomplex_sequence(size_type s, const xcomplex& v) : m_real(make_sequence(s, v.real())), m_imag(make_sequence(s, v.imag())) { } template inline xcomplex_sequence::xcomplex_sequence(std::initializer_list init) : m_real(make_sequence(init.size())), m_imag(make_sequence(init.size())) { std::transform(init.begin(), init.end(), m_real.begin(), [](const auto& v) { return v.real(); }); std::transform(init.begin(), init.end(), m_imag.begin(), [](const auto& v) { return v.imag(); }); } template inline bool xcomplex_sequence::empty() const noexcept { return m_real.empty(); } template inline auto xcomplex_sequence::size() const noexcept -> size_type { return m_real.size(); } template inline auto xcomplex_sequence::max_size() const noexcept -> size_type { return m_real.max_size(); } template inline auto xcomplex_sequence::at(size_type i) -> reference { return reference(m_real.at(i), m_imag.at(i)); } template inline auto xcomplex_sequence::at(size_type i) const -> const_reference { return const_reference(m_real.at(i), m_imag.at(i)); } template inline auto xcomplex_sequence::operator[](size_type i) -> reference { return reference(m_real[i], m_imag[i]); } template inline auto xcomplex_sequence::operator[](size_type i) const -> const_reference { return const_reference(m_real[i], m_imag[i]); } template inline auto xcomplex_sequence::front() -> reference { return reference(m_real.front(), m_imag.front()); } template inline auto xcomplex_sequence::front() const -> const_reference { return const_reference(m_real.front(), m_imag.front()); } template inline auto xcomplex_sequence::back() -> reference { return reference(m_real.back(), m_imag.back()); } template inline auto xcomplex_sequence::back() const -> const_reference { return const_reference(m_real.back(), m_imag.back()); } template inline auto xcomplex_sequence::begin() noexcept -> iterator { return iterator(m_real.begin(), m_imag.begin()); } template inline auto xcomplex_sequence::end() noexcept -> iterator { return iterator(m_real.end(), m_imag.end()); } template inline auto xcomplex_sequence::begin() const noexcept -> const_iterator { return cbegin(); } template inline auto xcomplex_sequence::end() const noexcept -> const_iterator { return cend(); } template inline auto xcomplex_sequence::cbegin() const noexcept -> const_iterator { return const_iterator(m_real.cbegin(), m_imag.cbegin()); } template inline auto xcomplex_sequence::cend() const noexcept -> const_iterator { return const_iterator(m_real.cend(), m_imag.cend()); } template inline auto xcomplex_sequence::rbegin() noexcept -> reverse_iterator { return reverse_iterator(m_real.rbegin(), m_imag.rbegin()); } template inline auto xcomplex_sequence::rend() noexcept -> reverse_iterator { return reverse_iterator(m_real.rend(), m_imag.rend()); } template inline auto xcomplex_sequence::rbegin() const noexcept -> const_reverse_iterator { return crbegin(); } template inline auto xcomplex_sequence::rend() const noexcept -> const_reverse_iterator { return crend(); } template inline auto xcomplex_sequence::crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(m_real.crbegin(), m_imag.crbegin()); } template inline auto xcomplex_sequence::crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(m_real.crend(), m_imag.crend()); } template inline auto xcomplex_sequence::real() && noexcept -> container_type { return m_real; } template inline auto xcomplex_sequence::real() & noexcept -> container_type& { return m_real; } template inline auto xcomplex_sequence::real() const & noexcept -> const container_type& { return m_real; } template inline auto xcomplex_sequence::imag() && noexcept -> container_type { return m_imag; } template inline auto xcomplex_sequence::imag() & noexcept -> container_type& { return m_imag; } template inline auto xcomplex_sequence::imag() const & noexcept -> const container_type& { return m_imag; } template inline bool operator==(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs) { return lhs.real() == rhs.real() && lhs.imag() == rhs.imag(); } template inline bool operator!=(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs) { return !(lhs == rhs); } /********************************* * xcomplex_array implementation * *********************************/ template inline xcomplex_array::xcomplex_array(size_type s) : base_type(s) { } template inline xcomplex_array::xcomplex_array(size_type s, const value_type& v) : base_type(s, v) { } template template inline xcomplex_array::xcomplex_array(size_type s, const xcomplex& v) : base_type(s, v) { } /********************************** * xcomplex_vector implementation * **********************************/ template inline xcomplex_vector::xcomplex_vector(size_type s) : base_type(s) { } template inline xcomplex_vector::xcomplex_vector(size_type s, const value_type& v) : base_type(s, v) { } template template inline xcomplex_vector::xcomplex_vector(size_type s, const xcomplex& v) : base_type(s, v) { } template inline xcomplex_vector::xcomplex_vector(std::initializer_list init) : base_type(init) { } template void xcomplex_vector::resize(size_type s) { this->m_real.resize(s); this->m_imag.resize(s); } template void xcomplex_vector::resize(size_type s, const value_type& v) { this->m_real.resize(s, v.real()); this->m_imag.resize(s, v.imag()); } template template inline void xcomplex_vector::resize(size_type s, const xcomplex& v) { this->m_real.resize(s, v.real()); this->m_imag.resize(s, v.imag()); } /************************************ * xcomplex_iterator implementation * ************************************/ template inline xcomplex_iterator::xcomplex_iterator(IT it_real, IT it_imag) : m_it_real(it_real), m_it_imag(it_imag) { } template inline auto xcomplex_iterator::operator++() -> self_type& { ++m_it_real; ++m_it_imag; return *this; } template inline auto xcomplex_iterator::operator--() -> self_type& { --m_it_real; --m_it_imag; return *this; } template inline auto xcomplex_iterator::operator+=(difference_type n) -> self_type& { m_it_real += n; m_it_imag += n; return *this; } template inline auto xcomplex_iterator::operator-=(difference_type n) -> self_type& { m_it_real -= n; m_it_imag -= n; return *this; } template inline auto xcomplex_iterator::operator-(const self_type& rhs) const -> difference_type { return m_it_real - rhs.m_it_real; } template inline auto xcomplex_iterator::operator*() const -> reference { return reference(*m_it_real, *m_it_imag); } template inline auto xcomplex_iterator::operator->() const -> pointer { return pointer(operator*()); } template inline bool xcomplex_iterator::operator==(const self_type& rhs) const { return m_it_real == rhs.m_it_real && m_it_imag == rhs.m_it_imag; } } #endif xtl-0.6.9/include/xtl/xdynamic_bitset.hpp000066400000000000000000001223371357123723600205070ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XDYNAMIC_BITSET_HPP #define XDYNAMIC_BITSET_HPP #include #include #include #include "xclosure.hpp" #include "xspan.hpp" #include "xiterator_base.hpp" namespace xtl { template class xbitset_reference; template class xbitset_iterator; /****************** * xdyamic_bitset * ******************/ template class xdynamic_bitset_base; template class xdynamic_bitset; template class xdynamic_bitset_view; template struct xdynamic_bitset_traits; template struct xdynamic_bitset_traits> { using storage_type = std::vector; using block_type = typename storage_type::value_type; }; template struct xdynamic_bitset_traits> { using storage_type = xtl::span; using block_type = typename storage_type::value_type; }; template struct container_internals; template struct container_internals> { using value_type = typename xtl::span::value_type; static_assert(std::is_scalar::value, ""); using allocator_type = std::allocator; using size_type = std::size_t; using difference_type = typename xtl::span::difference_type; }; template struct container_internals> { using value_type = X; static_assert(std::is_scalar::value, ""); using allocator_type = A; using size_type = typename std::vector::size_type; using difference_type = typename std::vector::difference_type; }; template class xdynamic_bitset_base { public: using self_type = xdynamic_bitset_base; using derived_class = B; using storage_type = typename xdynamic_bitset_traits::storage_type; using block_type = typename xdynamic_bitset_traits::block_type; using temporary_type = xdynamic_bitset>; using allocator_type = typename container_internals::allocator_type; using value_type = bool; using reference = xbitset_reference; using const_reference = xbitset_reference; using pointer = typename reference::pointer; using const_pointer = typename const_reference::pointer; using size_type = typename container_internals::size_type; using difference_type = typename storage_type::difference_type; using iterator = xbitset_iterator; using const_iterator = xbitset_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using const_block_iterator = typename storage_type::const_iterator; bool empty() const noexcept; size_type size() const noexcept; void swap(self_type& rhs); reference at(size_type i); const_reference at(size_type i) const; reference operator[](size_type i); const_reference operator[](size_type i) const; reference front(); const_reference front() const; reference back(); const_reference back() const; iterator begin() noexcept; iterator end() noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; reverse_iterator rbegin() noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; const_block_iterator block_begin() const noexcept; const_block_iterator block_end() const noexcept; template self_type& operator&=(const xdynamic_bitset_base& rhs); template self_type& operator|=(const xdynamic_bitset_base& rhs); template self_type& operator^=(const xdynamic_bitset_base& rhs); temporary_type operator<<(size_type pos); self_type& operator<<=(size_type pos); temporary_type operator>>(size_type pos); self_type& operator>>=(size_type pos); self_type& set(); self_type& set(size_type pos, value_type value = true); self_type& reset(); self_type& reset(size_type pos); self_type& flip(); self_type& flip(size_type pos); bool all() const noexcept; bool any() const noexcept; bool none() const noexcept; size_type count() const noexcept; size_type block_count() const noexcept; block_type* data() noexcept; const block_type* data() const noexcept; template bool operator==(const xdynamic_bitset_base& rhs) const noexcept; template bool operator!=(const xdynamic_bitset_base& rhs) const noexcept; derived_class& derived_cast(); const derived_class& derived_cast() const; protected: xdynamic_bitset_base(const storage_type& buffer, std::size_t size); ~xdynamic_bitset_base() = default; xdynamic_bitset_base(const xdynamic_bitset_base& rhs) = default; xdynamic_bitset_base(xdynamic_bitset_base&& rhs) = default; xdynamic_bitset_base& operator=(const xdynamic_bitset_base& rhs) = default; xdynamic_bitset_base& operator=(xdynamic_bitset_base&& rhs) = default; size_type m_size; storage_type m_buffer; static constexpr std::size_t s_bits_per_block = CHAR_BIT * sizeof(block_type); size_type compute_block_count(size_type bits_count) const noexcept; size_type block_index(size_type pos) const noexcept; size_type bit_index(size_type pos) const noexcept; block_type bit_mask(size_type pos) const noexcept; size_type count_extra_bits() const noexcept; void zero_unused_bits(); private: // Make views and buffers friends template friend class xdynamic_bitset_base; }; // NOTE this view ZEROS out remaining bits! template class xdynamic_bitset_view : public xdynamic_bitset_base> { public: using base_class = xdynamic_bitset_base>; using storage_type = typename base_class::storage_type; using block_type = typename base_class::block_type; xdynamic_bitset_view(block_type* ptr, std::size_t size); xdynamic_bitset_view() = default; ~xdynamic_bitset_view() = default; xdynamic_bitset_view(const xdynamic_bitset_view& rhs) = default; xdynamic_bitset_view(xdynamic_bitset_view&& rhs) = default; xdynamic_bitset_view& operator=(const xdynamic_bitset_view& rhs) = default; xdynamic_bitset_view& operator=(xdynamic_bitset_view&& rhs) = default; void resize(std::size_t sz); }; namespace detail_bitset { template constexpr T integer_ceil(T n, T div) { return (n + div - T(1)) / div; } } template inline xdynamic_bitset_view::xdynamic_bitset_view(block_type* ptr, std::size_t size) : base_class(storage_type(ptr, detail_bitset::integer_ceil(size, base_class::s_bits_per_block)), size) { base_class::zero_unused_bits(); } template inline void xdynamic_bitset_view::resize(std::size_t sz) { if (sz != this->m_size) { #if defined(XTL_NO_EXCEPTIONS) std::fprintf(stderr, "cannot resize bitset_view\n"); std::terminate(); #else throw std::runtime_error("cannot resize bitset_view"); #endif } } template > class xdynamic_bitset; template auto operator~(const xdynamic_bitset_base& lhs); template auto operator&(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs); template auto operator|(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs); template auto operator^(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs); template void swap(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs); /********************* * xbitset_reference * *********************/ template class xbitset_reference { public: using self_type = xbitset_reference; using pointer = std::conditional_t, xclosure_pointer>; operator bool() const noexcept; xbitset_reference(const self_type&) = default; xbitset_reference(self_type&&) = default; self_type& operator=(const self_type&) noexcept; self_type& operator=(self_type&&) noexcept; self_type& operator=(bool) noexcept; bool operator~() const noexcept; self_type& operator&=(bool) noexcept; self_type& operator|=(bool) noexcept; self_type& operator^=(bool) noexcept; self_type& flip() noexcept; pointer operator&() noexcept; private: using block_type = typename xdynamic_bitset_traits::block_type; using closure_type = std::conditional_t; xbitset_reference(closure_type block, block_type pos); void assign(bool) noexcept; void set() noexcept; void reset() noexcept; closure_type m_block; const block_type m_mask; template friend class xbitset_reference; friend class xdynamic_bitset_base; }; /******************** * xbitset_iterator * ********************/ template class xbitset_iterator : public xrandom_access_iterator_base, typename xdynamic_bitset_base::value_type, typename xdynamic_bitset_base::difference_type, std::conditional_t::const_pointer, typename xdynamic_bitset_base::pointer>, std::conditional_t::const_reference, typename xdynamic_bitset_base::reference>> { public: using self_type = xbitset_iterator; using container_type = xdynamic_bitset_base; using value_type = typename container_type::value_type; using reference = std::conditional_t; using pointer = std::conditional_t; using size_type = typename container_type::size_type; using difference_type = typename container_type::difference_type; using base_type = xrandom_access_iterator_base; using container_reference = std::conditional_t; using container_pointer = std::conditional_t; xbitset_iterator() noexcept; xbitset_iterator(container_reference c, size_type index) noexcept; self_type& operator++(); self_type& operator--(); self_type& operator+=(difference_type n); self_type& operator-=(difference_type n); difference_type operator-(const self_type& rhs) const; reference operator*() const; pointer operator->() const; bool operator==(const self_type& rhs) const; bool operator<(const self_type& rhs) const; private: container_pointer p_container; size_type m_index; }; template class xdynamic_bitset : public xdynamic_bitset_base> { public: using allocator_type = Allocator; using storage_type = std::vector; using base_type = xdynamic_bitset_base>; using self_type = xdynamic_bitset; using block_type = B; using reference = typename base_type::reference; using const_reference = typename base_type::const_reference; using pointer = typename reference::pointer; using const_pointer = typename const_reference::pointer; using size_type = typename storage_type::size_type; using difference_type = typename storage_type::difference_type; using iterator = xbitset_iterator; using const_iterator = xbitset_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using base_type::base_type; using base_type::begin; using base_type::cbegin; using base_type::end; using base_type::cend; using base_type::rbegin; using base_type::rend; using base_type::size; xdynamic_bitset(); explicit xdynamic_bitset(const allocator_type& allocator); xdynamic_bitset(size_type count, bool b, const allocator_type& alloc = allocator_type()); explicit xdynamic_bitset(size_type count, const allocator_type& alloc = allocator_type()); xdynamic_bitset(std::initializer_list init, const allocator_type& alloc = allocator_type()); template xdynamic_bitset(BlockInputIt first, BlockInputIt last, const allocator_type& alloc = allocator_type()); xdynamic_bitset(const xdynamic_bitset& rhs); // Allow creation from views for e.g. temporary creation template xdynamic_bitset(const xdynamic_bitset_base& rhs); ~xdynamic_bitset() = default; xdynamic_bitset(xdynamic_bitset&& rhs) = default; xdynamic_bitset& operator=(const xdynamic_bitset& rhs) = default; xdynamic_bitset& operator=(xdynamic_bitset&& rhs) = default; void assign(size_type count, bool b); template void assign(BlockInputIt first, BlockInputIt last); void assign(std::initializer_list init); size_type max_size() const noexcept; void reserve(size_type new_cap); size_type capacity() const noexcept; allocator_type get_allocator() const; void resize(size_type size, bool b = false); void clear() noexcept; void push_back(bool b); void pop_back(); }; /********************************** * xdynamic_bitset implementation * **********************************/ template inline xdynamic_bitset::xdynamic_bitset() : base_type(storage_type(), size_type(0)) { } template inline xdynamic_bitset::xdynamic_bitset(const allocator_type& allocator) : base_type(storage_type(allocator), size_type(0)) { } template inline xdynamic_bitset::xdynamic_bitset(size_type count, bool b, const allocator_type& alloc) : base_type(storage_type(this->compute_block_count(count), b ? ~block_type(0) : block_type(0), alloc), count) { this->zero_unused_bits(); } template inline xdynamic_bitset::xdynamic_bitset(size_type count, const allocator_type& alloc) : base_type(storage_type(this->compute_block_count(count), block_type(0), alloc), count) { } template template inline xdynamic_bitset::xdynamic_bitset(BlockInputIt first, BlockInputIt last, const allocator_type& alloc) : base_type(storage_type(first, last, alloc), size_type(std::distance(first, last)) * base_type::s_bits_per_block) { } template inline xdynamic_bitset::xdynamic_bitset(std::initializer_list init, const allocator_type& alloc) : xdynamic_bitset(init.size(), alloc) { std::copy(init.begin(), init.end(), begin()); } template inline xdynamic_bitset::xdynamic_bitset(const xdynamic_bitset& rhs) : base_type(storage_type(rhs.block_begin(), rhs.block_end()), rhs.size()) { } template template inline xdynamic_bitset::xdynamic_bitset(const xdynamic_bitset_base& rhs) : base_type(storage_type(rhs.block_begin(), rhs.block_end()), rhs.size()) { } template inline void xdynamic_bitset::assign(size_type count, bool b) { resize(count); b ? this->set() : this->reset(); } template template inline void xdynamic_bitset::assign(BlockInputIt first, BlockInputIt last) { resize(size_type(std::distance(first, last)) * base_type::s_bits_per_block); std::copy(first, last, this->m_buffer.begin()); } template inline void xdynamic_bitset::assign(std::initializer_list init) { resize(init.size()); std::copy(init.begin(), init.end(), begin()); } template inline auto xdynamic_bitset::get_allocator() const -> allocator_type { return base_type::m_buffer.get_allocator(); } template inline bool xdynamic_bitset_base::empty() const noexcept { return m_size == 0; } template inline auto xdynamic_bitset_base::size() const noexcept -> size_type { return m_size; } template inline auto xdynamic_bitset::max_size() const noexcept -> size_type { return base_type::m_buffer.max_size() * base_type::s_bits_per_block; } template inline void xdynamic_bitset::reserve(size_type new_cap) { base_type::m_buffer.reserve(this->compute_block_count(new_cap)); } template inline auto xdynamic_bitset::capacity() const noexcept -> size_type { return base_type::m_buffer.capacity() * base_type::s_bits_per_block; } template inline void xdynamic_bitset::resize(size_type size, bool b) { size_type old_block_count = base_type::block_count(); size_type new_block_count = base_type::compute_block_count(size); block_type value = b ? ~block_type(0) : block_type(0); if (new_block_count != old_block_count) { base_type::m_buffer.resize(new_block_count, value); } if (b && size > base_type::m_size) { size_type extra_bits = base_type::count_extra_bits(); if (extra_bits > 0) { base_type::m_buffer[old_block_count - 1] |= (value << extra_bits); } } base_type::m_size = size; base_type::zero_unused_bits(); } template inline void xdynamic_bitset::clear() noexcept { base_type::m_buffer.clear(); base_type::m_size = size_type(0); } template inline void xdynamic_bitset::push_back(bool b) { size_type s = size(); resize(s + 1); this->set(s, b); } template inline void xdynamic_bitset::pop_back() { size_type old_block_count = base_type::m_buffer.size(); size_type new_block_count = base_type::compute_block_count(base_type::m_size - 1); if (new_block_count != old_block_count) { base_type::m_buffer.pop_back(); } --base_type::m_size; base_type::zero_unused_bits(); } template inline void xdynamic_bitset_base::swap(self_type& rhs) { using std::swap; swap(m_buffer, rhs.m_buffer); swap(m_size, rhs.m_size); } template inline auto xdynamic_bitset_base::at(size_type i) -> reference { // TODO add real check, remove m_buffer.at ... return reference(m_buffer.at(block_index(i)), bit_index(i)); } template inline auto xdynamic_bitset_base::at(size_type i) const -> const_reference { // TODO add real check, remove m_buffer.at ... return const_reference(m_buffer.at(block_index(i)), bit_index(i)); } template inline auto xdynamic_bitset_base::operator[](size_type i) -> reference { return reference(m_buffer[block_index(i)], bit_index(i)); } template inline auto xdynamic_bitset_base::operator[](size_type i) const -> const_reference { return const_reference(m_buffer[block_index(i)], bit_index(i)); } template inline auto xdynamic_bitset_base::front() -> reference { return (*this)[0]; } template inline auto xdynamic_bitset_base::front() const -> const_reference { return (*this)[0]; } template inline auto xdynamic_bitset_base::back() -> reference { return (*this)[m_size - 1]; } template inline auto xdynamic_bitset_base::back() const -> const_reference { return (*this)[m_size - 1]; } template inline auto xdynamic_bitset_base::begin() noexcept -> iterator { return iterator(*this, size_type(0)); } template inline auto xdynamic_bitset_base::end() noexcept -> iterator { return iterator(*this, size()); } template inline auto xdynamic_bitset_base::begin() const noexcept -> const_iterator { return cbegin(); } template inline auto xdynamic_bitset_base::end() const noexcept -> const_iterator { return cend(); } template inline auto xdynamic_bitset_base::cbegin() const noexcept -> const_iterator { return const_iterator(*this, size_type(0)); } template inline auto xdynamic_bitset_base::cend() const noexcept -> const_iterator { return const_iterator(*this, size()); } template inline auto xdynamic_bitset_base::rbegin() noexcept -> reverse_iterator { return reverse_iterator(end()); } template inline auto xdynamic_bitset_base::rend() noexcept -> reverse_iterator { return reverse_iterator(begin()); } template inline auto xdynamic_bitset_base::rbegin() const noexcept -> const_reverse_iterator { return crbegin(); } template inline auto xdynamic_bitset_base::rend() const noexcept -> const_reverse_iterator { return crend(); } template inline auto xdynamic_bitset_base::crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(cend()); } template inline auto xdynamic_bitset_base::crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(cbegin()); } template inline auto xdynamic_bitset_base::block_begin() const noexcept -> const_block_iterator { return m_buffer.begin(); } template inline auto xdynamic_bitset_base::block_end() const noexcept -> const_block_iterator { return m_buffer.end(); } template template inline auto xdynamic_bitset_base::operator&=(const xdynamic_bitset_base& rhs) -> self_type& { size_type size = block_count(); for (size_type i = 0; i < size; ++i) { m_buffer[i] &= rhs.m_buffer[i]; } return *this; } template template inline auto xdynamic_bitset_base::operator|=(const xdynamic_bitset_base& rhs) -> self_type& { size_type size = block_count(); for (size_type i = 0; i < size; ++i) { m_buffer[i] |= rhs.m_buffer[i]; } return *this; } template template inline auto xdynamic_bitset_base::operator^=(const xdynamic_bitset_base& rhs) -> self_type& { size_type size = block_count(); for (size_type i = 0; i < size; ++i) { m_buffer[i] ^= rhs.m_buffer[i]; } return *this; } template inline auto xdynamic_bitset_base::operator<<(size_type pos) -> temporary_type { temporary_type tmp(this->derived_cast()); tmp <<= pos; return tmp; } template inline auto xdynamic_bitset_base::operator<<=(size_type pos) -> self_type& { if (pos >= m_size) { return reset(); } if (pos > 0) { size_type last = block_count() - 1; size_type div = pos / s_bits_per_block; size_type r = bit_index(pos); block_type* b = &m_buffer[0]; if (r != 0) { size_type rs = s_bits_per_block - r; for (size_type i = last - div; i > 0; --i) { b[i + div] = (b[i] << r) | (b[i - 1] >> rs); } b[div] = b[0] << r; } else { for (size_type i = last - div; i > 0; --i) { b[i + div] = b[i]; } b[div] = b[0]; } std::fill_n(m_buffer.begin(), div, block_type(0)); zero_unused_bits(); } return *this; } template inline auto xdynamic_bitset_base::operator>>(size_type pos) -> temporary_type { temporary_type tmp(this->derived_cast()); tmp >>= pos; return tmp; } template inline auto xdynamic_bitset_base::operator>>=(size_type pos) -> self_type& { if (pos >= m_size) { return reset(); } if (pos > 0) { size_type last = block_count() - 1; size_type div = pos / s_bits_per_block; size_type r = bit_index(pos); block_type* b = &m_buffer[0]; if (r != 0) { size_type ls = s_bits_per_block - r; for (size_type i = div; i < last; ++i) { b[i - div] = (b[i] >> r) | (b[i + 1] << ls); } b[last - div] = b[last] >> r; } else { for (size_type i = div; i <= last; ++i) { b[i - div] = b[i]; } } std::fill_n(m_buffer.begin() + static_cast(block_count() - div), div, block_type(0)); } return *this; } template inline auto xdynamic_bitset_base::set() -> self_type& { std::fill(m_buffer.begin(), m_buffer.end(), ~block_type(0)); zero_unused_bits(); return *this; } template inline auto xdynamic_bitset_base::set(size_type pos, value_type value) -> self_type& { if (value) { m_buffer[block_index(pos)] |= bit_mask(pos); } else { reset(pos); } return *this; } template inline auto xdynamic_bitset_base::reset() -> self_type& { std::fill(m_buffer.begin(), m_buffer.end(), block_type(0)); return *this; } template inline auto xdynamic_bitset_base::reset(size_type pos) -> self_type& { m_buffer[block_index(pos)] &= ~bit_mask(pos); return *this; } template inline auto xdynamic_bitset_base::flip() -> self_type& { size_type size = block_count(); for (size_type i = 0; i < size; ++i) { m_buffer[i] = ~m_buffer[i]; } zero_unused_bits(); return *this; } template inline auto xdynamic_bitset_base::flip(size_type pos) -> self_type& { m_buffer[block_index(pos)] ^= bit_mask(pos); return *this; } template inline bool xdynamic_bitset_base::all() const noexcept { if (empty()) return true; size_type extra_bits = count_extra_bits(); constexpr block_type all_ones = ~block_type(0); size_type size = extra_bits != 0 ? block_count() - 1 : block_count(); for (size_type i = 0; i < size; ++i) { if (m_buffer[i] != all_ones) return false; } if (extra_bits != 0) { block_type mask = ~(~block_type(0) << extra_bits); if (m_buffer.back() != mask) return false; } return true; } template inline bool xdynamic_bitset_base::any() const noexcept { size_type size = block_count(); for (size_type i = 0; i < size; ++i) { if (m_buffer[i]) return true; } return false; } template inline bool xdynamic_bitset_base::none() const noexcept { return !any(); } template inline auto xdynamic_bitset_base::count() const noexcept -> size_type { static constexpr unsigned char table[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; size_type res = 0; const unsigned char* p = static_cast(static_cast(&m_buffer[0])); size_type length = m_buffer.size() * sizeof(block_type); for (size_type i = 0; i < length; ++i, ++p) { res += table[*p]; } return res; } template inline auto xdynamic_bitset_base::block_count() const noexcept -> size_type { return m_buffer.size(); } template inline auto xdynamic_bitset_base::data() noexcept -> block_type* { return m_buffer.data(); } template inline auto xdynamic_bitset_base::data() const noexcept -> const block_type* { return m_buffer.data(); } template template inline bool xdynamic_bitset_base::operator==(const xdynamic_bitset_base& rhs) const noexcept { bool is_equal = m_size == rhs.m_size; if (!is_equal) { return false; } // we know that block type of lhs & rhs is the same auto n_blocks = block_count(); for (std::size_t i = 0; i < n_blocks; ++i) { if (m_buffer[i] != rhs.m_buffer[i]) { return false; } } return true; } template template inline bool xdynamic_bitset_base::operator!=(const xdynamic_bitset_base& rhs) const noexcept { return !(*this == rhs); } template inline auto xdynamic_bitset_base::derived_cast() -> derived_class& { return *(reinterpret_cast(this)); } template inline auto xdynamic_bitset_base::derived_cast() const -> const derived_class& { return *(reinterpret_cast(this)); } template inline xdynamic_bitset_base::xdynamic_bitset_base(const storage_type& buffer, std::size_t size) : m_size(size), m_buffer(buffer) { } template inline auto xdynamic_bitset_base::compute_block_count(size_type bits_count) const noexcept -> size_type { return bits_count / s_bits_per_block + static_cast(bits_count % s_bits_per_block != 0); } template inline auto xdynamic_bitset_base::block_index(size_type pos) const noexcept -> size_type { return pos / s_bits_per_block; } template inline auto xdynamic_bitset_base::bit_index(size_type pos) const noexcept -> size_type { return pos % s_bits_per_block; } template inline auto xdynamic_bitset_base::bit_mask(size_type pos) const noexcept -> block_type { return block_type(1) << bit_index(pos); } template inline auto xdynamic_bitset_base::count_extra_bits() const noexcept -> size_type { return bit_index(size()); } template inline void xdynamic_bitset_base::zero_unused_bits() { size_type extra_bits = count_extra_bits(); if (extra_bits != 0) { m_buffer.back() &= ~(~block_type(0) << extra_bits); } } template inline auto operator~(const xdynamic_bitset_base& lhs) { using temporary_type = typename xdynamic_bitset_base::temporary_type; temporary_type res(lhs.derived_cast()); res.flip(); return res; } template inline auto operator&(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs) { using temporary_type = typename xdynamic_bitset_base::temporary_type; temporary_type res(lhs.derived_cast()); res &= rhs; return res; } template inline auto operator|(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs) { using temporary_type = typename xdynamic_bitset_base::temporary_type; temporary_type res(lhs.derived_cast()); res |= rhs; return res; } template inline auto operator^(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs) { using temporary_type = typename xdynamic_bitset_base::temporary_type; temporary_type res(lhs.derived_cast()); res ^= rhs; return res; } template inline void swap(const xdynamic_bitset_base& lhs, const xdynamic_bitset_base& rhs) { return lhs.swap(rhs); } /************************************ * xbitset_reference implementation * ************************************/ template inline xbitset_reference::xbitset_reference(closure_type block, block_type pos) : m_block(block), m_mask(block_type(1) << pos) { } template inline xbitset_reference::operator bool() const noexcept { return (m_block & m_mask) != 0; } template inline auto xbitset_reference::operator=(const self_type& rhs) noexcept -> self_type& { assign(rhs); return *this; } template inline auto xbitset_reference::operator=(self_type&& rhs) noexcept -> self_type& { assign(rhs); return *this; } template inline auto xbitset_reference::operator=(bool rhs) noexcept -> self_type& { assign(rhs); return *this; } template inline bool xbitset_reference::operator~() const noexcept { return (m_block & m_mask) == 0; } template inline auto xbitset_reference::operator&=(bool rhs) noexcept -> self_type& { if (!rhs) { reset(); } return *this; } template inline auto xbitset_reference::operator|=(bool rhs) noexcept -> self_type& { if (rhs) { set(); } return *this; } template inline auto xbitset_reference::operator^=(bool rhs) noexcept -> self_type& { return rhs ? flip() : *this; } template inline auto xbitset_reference::flip() noexcept -> self_type& { m_block ^= m_mask; return *this; } template inline auto xbitset_reference::operator&() noexcept -> pointer { return pointer(*this); } template inline void xbitset_reference::assign(bool rhs) noexcept { rhs ? set() : reset(); } template inline void xbitset_reference::set() noexcept { m_block |= m_mask; } template inline void xbitset_reference::reset() noexcept { m_block &= ~m_mask; } /*********************************** * xbitset_iterator implementation * ***********************************/ template inline xbitset_iterator::xbitset_iterator() noexcept : p_container(nullptr), m_index(0) { } template inline xbitset_iterator::xbitset_iterator(container_reference c, size_type index) noexcept : p_container(&c), m_index(index) { } template inline auto xbitset_iterator::operator++() -> self_type& { ++m_index; return *this; } template inline auto xbitset_iterator::operator--() -> self_type& { --m_index; return *this; } template inline auto xbitset_iterator::operator+=(difference_type n) -> self_type& { difference_type res = static_cast(m_index) + n; m_index = static_cast(res); return *this; } template inline auto xbitset_iterator::operator-=(difference_type n) -> self_type& { difference_type res = static_cast(m_index) - n; m_index = static_cast(res); return *this; } template inline auto xbitset_iterator::operator-(const self_type& rhs) const -> difference_type { return difference_type(m_index - rhs.m_index); } template inline auto xbitset_iterator::operator*() const -> reference { return (*p_container)[m_index]; } template inline auto xbitset_iterator::operator->() const -> pointer { return &(operator*()); } template inline bool xbitset_iterator::operator==(const self_type& rhs) const { return p_container == rhs.p_container && m_index == rhs.m_index; } template inline bool xbitset_iterator::operator<(const self_type& rhs) const { return p_container == rhs.p_container && m_index < rhs.m_index; } } #endif xtl-0.6.9/include/xtl/xfunctional.hpp000066400000000000000000000025021357123723600176420ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_FUNCTIONAL_HPP #define XTL_FUNCTIONAL_HPP #include #include "xtl_config.hpp" #include "xtype_traits.hpp" namespace xtl { /*************************** * identity implementation * ***************************/ struct identity { template T&& operator()(T&& x) const { return std::forward(x); } }; /************************* * select implementation * *************************/ template )> inline std::common_type_t select(const B& cond, const T1& v1, const T2& v2) noexcept { return cond ? v1 : v2; } } #endif xtl-0.6.9/include/xtl/xhash.hpp000066400000000000000000000145661357123723600164400ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_HASH_HPP #define XTL_HASH_HPP #include #include #include #include namespace xtl { std::size_t hash_bytes(const void* buffer, std::size_t length, std::size_t seed); uint32_t murmur2_x86(const void* buffer, std::size_t length, uint32_t seed); uint64_t murmur2_x64(const void* buffer, std::size_t length, uint64_t seed); /****************************** * hash_bytes implementation * ******************************/ namespace detail { // Dummy hash implementation for unusual sizeof(std::size_t) template std::size_t murmur_hash(const void* buffer, std::size_t length, std::size_t seed) { std::size_t hash = seed; const char* data = static_cast(buffer); for (; length != 0; --length) { hash = (hash * 131) + static_cast(*data++); } return hash; } // Murmur hash is an algorithm written by Austin Appleby. See https://github.com/aappleby/smhasher/blob/master/src/MurmurHash2.cpp inline uint32_t murmur2_x86_impl(const void* buffer, std::size_t length, uint32_t seed) { const uint32_t m = 0x5bd1e995; uint32_t len = static_cast(length); // Initialize the hash to a 'random' value uint32_t h = seed ^ len; // Mix 4 bytes at a time into the hash const unsigned char * data = (const unsigned char *)buffer; while(len >= 4) { uint32_t k = *(uint32_t*)data; k *= m; k ^= k >> 24; k *= m; h *= m; h ^= k; data += 4; len -= 4; } // Handle the last few bytes of the input array switch(len) { case 3: h ^= static_cast(data[2] << 16); case 2: h ^= static_cast(data[1] << 8); case 1: h ^= static_cast(data[0]); h *= m; }; // Do a few final mixes of the hash to ensure the last few // // bytes are well-incorporated. h ^= h >> 13; h *= m; h ^= h >> 15; return h; } template <> inline std::size_t murmur_hash<4>(const void* buffer, std::size_t length, std::size_t seed) { return std::size_t(murmur2_x86_impl(buffer, length, static_cast(seed))); } inline std::size_t load_bytes(const char* p, int n) { std::size_t result = 0; --n; do { result = (result << 8) + static_cast(p[n]); } while (--n >= 0); return result; } #if INTPTR_MAX == INT64_MAX // 64-bits hash for 64-bits platform template <> inline std::size_t murmur_hash<8>(const void* buffer, std::size_t length, std::size_t seed) { constexpr std::size_t m = (static_cast(0xc6a4a793UL) << 32UL) + static_cast(0x5bd1e995UL); constexpr int r = 47; const char* data = static_cast(buffer); const char* end = data + (length & std::size_t(~0x7)); std::size_t hash = seed ^ (length * m); while (data != end) { std::size_t k; std::memcpy(&k, data, sizeof(k)); k *= m; k ^= k >> r; k *= m; hash ^= k; hash *= m; data += 8; } if ((length & 0x7) != 0) { std::size_t k = load_bytes(end, length & 0x7); hash ^= k; hash *= m; } hash ^= hash >> r; hash *= m; hash ^= hash >> r; return hash; } #elif INTPTR_MAX == INT32_MAX //64-bits hash for 32-bits platform inline void mmix(uint32_t& h, uint32_t& k, uint32_t m, int r) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; } template <> inline std::size_t murmur_hash<8>(const void* buffer, std::size_t length, std::size_t seed) { const uint32_t m = 0x5bd1e995; const int r = 24; uint32_t l = length; const auto* data = reinterpret_cast(buffer); uint32_t h = seed; while (length >= 4) { uint32_t k = *(uint32_t*)data; mmix(h, k, m, r); data += 4; length -= 4; } uint32_t t = 0; switch (length) { case 3: t ^= data[2] << 16; case 2: t ^= data[1] << 8; case 1: t ^= data[0]; }; mmix(h, t, m, r); mmix(h, l, m, r); h ^= h >> 13; h *= m; h ^= h >> 15; return h; } #else #error Unknown pointer size or missing size macros! #endif } inline std::size_t hash_bytes(const void* buffer, std::size_t length, std::size_t seed) { return detail::murmur_hash(buffer, length, seed); } inline uint32_t murmur2_x86(const void* buffer, std::size_t length, uint32_t seed) { return detail::murmur2_x86_impl(buffer, length, seed); } inline uint64_t murmur2_x64(const void* buffer, std::size_t length, uint64_t seed) { return detail::murmur_hash<8>(buffer, length, seed); } } #endif xtl-0.6.9/include/xtl/xhierarchy_generator.hpp000066400000000000000000000045321357123723600215310ustar00rootroot00000000000000/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_HIERARCHY_GENERATOR_HPP #define XTL_HIERARCHY_GENERATOR_HPP #include "xmeta_utils.hpp" namespace xtl { /********************************* * scattered hierarchy generator * *********************************/ template class U> class xscatter_hierarchy_generator; template