diff --git a/.appveyor.yml b/.appveyor.yml index 633d0c120f..08c8dc4468 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,16 +1,10 @@ clone_depth: 10 environment: - BOOST_PROG_OPTION : "C:/projects/mlpack/\ - boost_program_options-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" BOOST_MATH : "C:/projects/mlpack/\ boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" BOOST_RANDOM : "C:/projects/mlpack/\ boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" - BOOST_SERIALIZATION : "C:/projects/mlpack/\ - boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" - BOOST_UNIT_TEST : "C:/projects/mlpack/\ - boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*" ARMADILLO_DOWNLOAD : "https://data.kurg.org/armadillo-8.400.0.tar.xz" ARMADILLO_LIBRARY : "C:/projects/mlpack/armadillo-8.400.0/\ build/Debug/armadillo.lib" @@ -22,50 +16,36 @@ environment: JENKINS_DOC : "C:/projects/mlpack/dist/win-installer/jenkinsdoc.zip" GIT_VERSION_FILE : "C:/projects/mlpack/src/mlpack/core/util/gitversion.hpp" matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - VSVER: Visual Studio 14 2015 Win64 - MSBUILD: C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - VSVER: Visual Studio 15 2017 Win64 - MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe -# Currently, the VS2019 build seems to always time out. This seems to be an -# AppVeyor issue. -# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 -# VSVER: Visual Studio 16 2019 -# MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + VSVER: Visual Studio 16 2019 + MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe +# We have removed the VS studio 15 2017 build since it is not possible to complete +# or finish the build due to the `compiler out of heap space issues`. +# Therefore, in the meanwhile, we are only doing the installation for VS 16 2019. configuration: Release -os: Visual Studio 2015 +os: Visual Studio 2019 install: - ps: nuget install boost -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_unit_test_framework-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_program_options-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - ps: > nuget install boost_random-vc140 -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - - ps: > - nuget install boost_serialization-vc140 - -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 - ps: > nuget install boost_math_c99-vc140 -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0 + - ps: > + nuget install unofficial-flayan-cereal + -o "${env:APPVEYOR_BUILD_FOLDER}" - ps: nuget install OpenBLAS -o "${env:APPVEYOR_BUILD_FOLDER}" - set path=C:\Program Files (x86)\WiX Toolset v3.11\bin;%path% build_script: - mkdir boost_libs - - ps: cp ${env:BOOST_PROG_OPTION} C:\projects\mlpack\boost_libs\ - ps: cp ${env:BOOST_MATH} C:\projects\mlpack\boost_libs\ - ps: cp ${env:BOOST_RANDOM} C:\projects\mlpack\boost_libs\ - - ps: cp ${env:BOOST_SERIALIZATION} C:\projects\mlpack\boost_libs\ - - ps: cp ${env:BOOST_UNIT_TEST} C:\projects\mlpack\boost_libs\ - echo TEST_ARMA is %ARMADILLO_DOWNLOAD% - > appveyor DownloadFile %ARMADILLO_DOWNLOAD% @@ -89,6 +69,7 @@ build_script: -DLAPACK_LIBRARIES:FILEPATH=%BLAS_LIBRARY% -DARMADILLO_INCLUDE_DIR="C:/projects/mlpack/armadillo-8.400.0/include" -DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY% + -DCEREAL_INCLUDE_DIR="C:/projects/mlpack/unofficial-flayan-cereal.1.2.2/build/native/include" -DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE% -DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack/boost_libs" -DDEBUG=OFF @@ -96,6 +77,7 @@ build_script: -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF + -DBUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release .. - > "%MSBUILD%" "C:\projects\mlpack\build\mlpack.sln" @@ -139,9 +121,6 @@ build_script: - ps: > cp C:\projects\mlpack\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll C:\projects\mlpack\dist\win-installer\staging\ - - ps: > - cp C:\projects\mlpack\boost_libs\boost_unit_test_framework-vc*.dll - C:\projects\mlpack\dist\win-installer\staging\ - ps: > cp C:\projects\mlpack\build\include\mlpack C:\projects\mlpack\dist\win-installer\staging -recurse @@ -239,20 +218,3 @@ cache: - packages -> **\packages.config - armadillo.tar.xz -> appveyor.yaml -test_script: - # Copy all DLLs into the right place before running the test. - - ps: cp C:\projects\mlpack\boost_libs\*.* C:\projects\mlpack\build\ - - ps: > - cp C:\projects\mlpack\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.* - C:\projects\mlpack\build\ - - cd "%APPVEYOR_BUILD_FOLDER%/build/" - - > - Release\mlpack_test.exe - --report_level=detailed - --log_level=test_suite --log_format=XML > mlpack_test.xml & exit 0 - # Attempt to upload results to AppVeyor. - - ps: > - $wc = New-Object 'System.Net.WebClient'; - $wc.UploadFile( - "https://ci.appveyor.com/api/testresults/xunit/$($env:APPVEYOR_JOB_ID)", - (Resolve-Path .\mlpack_test.xml)); diff --git a/.ci/ci.yaml b/.ci/ci.yaml index 92753206c8..5348c55cc9 100644 --- a/.ci/ci.yaml +++ b/.ci/ci.yaml @@ -59,24 +59,24 @@ jobs: steps: - template: macos-steps.yaml -- job: WindowsVS15 - timeoutInMinutes: 360 - displayName: Windows VS15 - pool: - vmImage: vs2017-win2016 - strategy: - matrix: - Plain: - CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' - python.version: '2.7' - CMakeGenerator: '-G "Visual Studio 15 2017 Win64"' - MSBuildVersion: '15.0' - ArchiveNoLibs: 'mlpack-windows-vs15-no-libs.zip' - ArchiveLibs: 'mlpack-windows-vs15.zip' - ArchiveTests: 'mlpack_test-vs15.xml' +# - job: WindowsVS15 +# timeoutInMinutes: 360 +# displayName: Windows VS15 +# pool: +# vmImage: vs2017-win2016 +# strategy: +# matrix: +# Plain: +# CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF' +# python.version: '2.7' +# CMakeGenerator: '-G "Visual Studio 15 2017 Win64"' +# MSBuildVersion: '15.0' +# ArchiveNoLibs: 'mlpack-windows-vs15-no-libs.zip' +# ArchiveLibs: 'mlpack-windows-vs15.zip' +# ArchiveTests: 'mlpack_test-vs15.xml' - steps: - - template: windows-steps.yaml +# steps: +# - template: windows-steps.yaml - job: WindowsVS16 timeoutInMinutes: 360 diff --git a/.ci/linux-steps.yaml b/.ci/linux-steps.yaml index 75cd4e2194..21baace148 100644 --- a/.ci/linux-steps.yaml +++ b/.ci/linux-steps.yaml @@ -37,6 +37,11 @@ steps: # Install armadillo. curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo* cmake . && make && sudo make install && cd .. + + # Install cereal. + wget https://github.com/USCiLab/cereal/archive/v1.3.0.tar.gz + tar -xvzpf v1.3.0.tar.gz # Unpack into cereal-1.3.0/. + cd cereal-1.3.0/ displayName: 'Install Build Dependencies' # Configure mlpack (CMake) @@ -47,7 +52,7 @@ steps: export GOPATH=$PWD/src/mlpack/bindings/go go get -u -t gonum.org/v1/gonum/... fi - cmake $(CMakeArgs) -DPYTHON_EXECUTABLE=`which python` .. + cmake $(CMakeArgs) -DPYTHON_EXECUTABLE=`which python` -DCEREAL_INCLUDE_DIR=../cereal-1.3.0/include/ .. displayName: 'CMake' # Build mlpack diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index a7fdead21f..c437344050 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -14,7 +14,7 @@ steps: set -e sudo xcode-select --switch /Applications/Xcode_12.2.app/Contents/Developer unset BOOST_ROOT - brew install openblas armadillo boost + brew install openblas armadillo boost cereal if [ "$(binding)" == "python" ]; then pip install --upgrade pip diff --git a/.ci/windows-steps.yaml b/.ci/windows-steps.yaml index 69a33520a3..4281ab23f8 100644 --- a/.ci/windows-steps.yaml +++ b/.ci/windows-steps.yaml @@ -10,19 +10,14 @@ steps: - powershell: | nuget install OpenBLAS -o $(Agent.ToolsDirectory) nuget install boost -o $(Agent.ToolsDirectory) -Version 1.60.0 - nuget install boost_unit_test_framework-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 - nuget install boost_program_options-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 nuget install boost_random-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 - nuget install boost_serialization-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 nuget install boost_math_c99-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0 nuget install OpenBLAS -o $(Agent.ToolsDirectory) + nuget install unofficial-flayan-cereal -o $(Agent.ToolsDirectory) mkdir -p $(Agent.ToolsDirectory)/boost_libs - cp $(Agent.ToolsDirectory)/boost_program_options-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs cp $(Agent.ToolsDirectory)/boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs cp $(Agent.ToolsDirectory)/boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs - cp $(Agent.ToolsDirectory)/boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs - cp $(Agent.ToolsDirectory)/boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs displayName: 'Fetch build dependencies' # Configure armadillo @@ -66,6 +61,7 @@ steps: -DARMADILLO_LIBRARY="..\armadillo-8.400.0\Release\armadillo.lib" ` -DBOOST_INCLUDEDIR=$(Agent.ToolsDirectory)\boost.1.60.0.0\lib\native\include ` -DBOOST_LIBRARYDIR=$(Agent.ToolsDirectory)\boost_libs ` + -DCEREAL_INCLUDE_DIR=$(Agent.ToolsDirectory)\unofficial-flayan-cereal.1.2.2\build\native\include ` -DBUILD_JULIA_BINDINGS=OFF ` -DCMAKE_BUILD_TYPE=Release .. displayName: 'Configure mlpack' @@ -78,8 +74,6 @@ steps: msbuildVersion: $(MSBuildVersion) configuration: 'Release' msbuildArchitecture: 'x64' - platform: 'x64' - msbuildArguments: /m /p:BuildInParallel=true maximumCpuCount: false clean: false displayName: 'Build mlpack' @@ -94,7 +88,7 @@ steps: # Run tests via ctest. - bash: | cd build - CTEST_OUTPUT_ON_FAILURE=1 ctest -T Test -C Release . + CTEST_OUTPUT_ON_FAILURE=1 ctest -T Test -C Release . -j1 displayName: 'Run tests via ctest' # Copy artifacts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e40ceb91ca..d21ed170da 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -65,7 +65,7 @@ jobs: - name: Install Build Dependencies run: | sudo apt-get update - sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev + sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev libcereal-dev curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo* cmake . && make && sudo make install && cd .. diff --git a/.github/workflows/update-catch.yaml b/.github/workflows/update-catch.yaml new file mode 100644 index 0000000000..a4f7de2c4d --- /dev/null +++ b/.github/workflows/update-catch.yaml @@ -0,0 +1,48 @@ +name: Update Catch +on: + workflow_dispatch: + schedule: + - cron: '0 10 1/16 * *' +jobs: + updateCatch: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Get Latest Catch Tagged Release + id: catch-header + run: | + # Ping version information upstream. + CATCH_RELEASE_JSON=$(curl -sL https://api.github.com/repos/catchorg/Catch2/releases/latest) + CATCH_RELEASE_VERSION=$(jq -r ".tag_name" <<< "$CATCH_RELEASE_JSON" | tr -d v) + echo ::set-output name=release_tag::$(echo $CATCH_RELEASE_VERSION) + # Extract out version information from git repository. + CATCH_VERSION_MAJOR=$(grep -i ".*#define CATCH_VERSION_MAJOR.*" src/mlpack/tests/catch.hpp | grep -o "[0-9]*") + CATCH_VERSION_MINOR=$(grep -i ".*#define CATCH_VERSION_MINOR.*" src/mlpack/tests/catch.hpp | grep -o "[0-9]*") + CATCH_VERSION_PATCH=$(grep -i ".*#define CATCH_VERSION_PATCH.*" src/mlpack/tests/catch.hpp | grep -o "[0-9]*") + # Combine values to match release tag information. + CATCH_VERSION_VALUE=${CATCH_VERSION_MAJOR}.${CATCH_VERSION_MINOR}.${CATCH_VERSION_PATCH} + # Set the current release tag. + echo ::set-output name=current_tag::$(echo $CATCH_VERSION_VALUE) + + - name: Update Catch + if: steps.catch-header.outputs.current_tag != steps.catch-header.outputs.release_tag + env: + CURRENT_TAG: ${{ steps.catch-header.outputs.current_tag }} + RELEASE_TAG: ${{ steps.catch-header.outputs.release_tag }} + run: | + # Delete the catch.hpp. + rm -f src/mlpack/tests/catch.hpp + # Download the release. + curl -sL https://github.com/catchorg/Catch2/releases/latest/download/catch.hpp -o src/mlpack/tests/catch.hpp + + - name: Create Pull Request For Catch + if: steps.catch-header.outputs.current_tag != steps.catch-header.outputs.release_tag + uses: peter-evans/create-pull-request@v3 + with: + commit-message: Upgrade Catch to ${{ steps.catch-header.outputs.release_tag }} + title: Upgrade Catch to ${{ steps.catch-header.outputs.release_tag }} + body: | + Updates [catchorg/Catch2](https://github.com/catchorg/Catch2) to ${{ steps.catch-header.outputs.release_tag }}. + Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request). + labels: update dependencies, automated PR + branch: catch-header-updates-${{ steps.catch-header.outputs.release_tag }} diff --git a/.github/workflows/update-cli11.yaml b/.github/workflows/update-cli11.yaml new file mode 100644 index 0000000000..e935183cdf --- /dev/null +++ b/.github/workflows/update-cli11.yaml @@ -0,0 +1,44 @@ +name: Update CLI11 +on: + workflow_dispatch: + schedule: + - cron: '0 10 1/16 * *' +jobs: + updateCLI11: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Get Latest CLI11 Tagged Release + id: cli11-header + run: | + # Ping version information upstream. + CLI11_RELEASE_JSON=$(curl -sL https://api.github.com/repos/CLIUtils/CLI11/releases/latest) + CLI11_RELEASE_VERSION=$(jq -r ".tag_name" <<< "$CLI11_RELEASE_JSON" | tr -d v) + echo ::set-output name=release_tag::$(echo $CLI11_RELEASE_VERSION) + # Extract out version information from git repository. + CLI11_VERSION_VALUE=$(grep -i ".*#define CLI11_VERSION.*" src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp | grep -Po "(\d+\.)+\d+") + # Set the current release tag. + echo ::set-output name=current_tag::$(echo $CLI11_VERSION_VALUE) + + - name: Update CLI11 + if: steps.cli11-header.outputs.current_tag != steps.cli11-header.outputs.release_tag + env: + CURRENT_TAG: ${{ steps.cli11-header.outputs.current_tag }} + RELEASE_TAG: ${{ steps.cli11-header.outputs.release_tag }} + run: | + # Delete the CLI11.hpp. + rm -f src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp + # Download the release. + curl -sL https://github.com/CLIUtils/CLI11/releases/latest/download/CLI11.hpp -o src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp + + - name: Create Pull Request For CLI11 + if: steps.cli11-header.outputs.current_tag != steps.cli11-header.outputs.release_tag + uses: peter-evans/create-pull-request@v3 + with: + commit-message: Upgrade CLI11 to ${{ steps.cli11-header.outputs.release_tag }} + title: Upgrade CLI11 to ${{ steps.cli11-header.outputs.release_tag }} + body: | + Updates [CLIUtils/CLI11](https://github.com/CLIUtils/CLI11) to ${{ steps.cli11-header.outputs.release_tag }}. + Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request). + labels: update dependencies, automated PR + branch: cli11-header-updates-${{ steps.cli11-header.outputs.release_tag }} diff --git a/CMake/ConfigureGenerate.cmake b/CMake/ConfigureFile.cmake similarity index 82% rename from CMake/ConfigureGenerate.cmake rename to CMake/ConfigureFile.cmake index 68499a1a5f..7e59520a7d 100644 --- a/CMake/ConfigureGenerate.cmake +++ b/CMake/ConfigureFile.cmake @@ -1,4 +1,4 @@ -# ConfigureGenerate.cmake: generate an mlpack binding file given input +# ConfigureFile.cmake: generate an mlpack binding file given input # arguments. # # This file depends on the following variables being set: diff --git a/CMake/FindRModule.cmake b/CMake/FindRModule.cmake index c8c7c55e44..bbb57a0387 100644 --- a/CMake/FindRModule.cmake +++ b/CMake/FindRModule.cmake @@ -28,7 +28,17 @@ function(find_r_module module) string(REGEX MATCHALL "‘[0-9._]*’" _version_compare "${_version_compare}") string(REGEX REPLACE "‘" "" _version_compare "${_version_compare}") string(REGEX REPLACE "’" "" _version_compare "${_version_compare}") - if ("${_version_compare}" GREATER_EQUAL "${VERSION_REQ}") + + # Compare the version of the package using compareVersion(). + execute_process(COMMAND ${RSCRIPT_EXECUTABLE} "-e" + "compareVersion('${_version_compare}', '${VERSION_REQ}')" + RESULT_VARIABLE _compareVersion_status + OUTPUT_VARIABLE _compareVersion_result + OUTPUT_STRIP_TRAILING_WHITESPACE) + + # Extract compareVersion() result i.e. 1 -> Newer, 0 -> Equal and -1 -> Later. + string(REGEX REPLACE "\\[\\1\\]" "" _compareVersion_result "${_compareVersion_result}") + if ("${_compareVersion_result}" GREATER "-1") set(R_${module_upper} "${_${module}_location} (found suitable version \"${_version_compare}\", minimum required is \"${VERSION_REQ}\")" CACHE STRING "Location of R module ${module}" diff --git a/CMake/Findcereal.cmake b/CMake/Findcereal.cmake new file mode 100644 index 0000000000..b4d99fe823 --- /dev/null +++ b/CMake/Findcereal.cmake @@ -0,0 +1,56 @@ +#Findcereal.cmake +find_path(CEREAL_INCLUDE_DIR + NAMES cereal + PATHS "$ENV{ProgramFiles}/cereal/include" + ) + +if(CEREAL_INCLUDE_DIR) + # ------------------------------------------------------------------------ + # Extract version information from + # ------------------------------------------------------------------------ + set(CEREAL_FOUND YES) + set(CEREAL_VERSION_MAJOR 0) + set(CEREAL_VERSION_MINOR 0) + set(CEREAL_VERSION_PATCH 0) + + if(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/version.hpp") + + # Read and parse cereal version header file for version number + file(READ "${CEREAL_INCLUDE_DIR}/cereal/version.hpp" + _CEREAL_HEADER_CONTENTS) + string(REGEX REPLACE ".*#define CEREAL_VERSION_MAJOR ([0-9]+).*" "\\1" + CEREAL_VERSION_MAJOR "${_CEREAL_HEADER_CONTENTS}") + string(REGEX REPLACE ".*#define CEREAL_VERSION_MINOR ([0-9]+).*" "\\1" + CEREAL_VERSION_MINOR "${_CEREAL_HEADER_CONTENTS}") + string(REGEX REPLACE ".*#define CEREAL_VERSION_PATCH ([0-9]+).*" "\\1" + CEREAL_VERSION_PATCH "${_CEREAL_HEADER_CONTENTS}") + + elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/details/polymorphic_impl_fwd.hpp") + + set(CEREAL_VERSION_MAJOR 1) + set(CEREAL_VERSION_MINOR 2) + set(CEREAL_VERSION_PATCH 0) + elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/types/valarray.hpp") + + set(CEREAL_VERSION_MAJOR 1) + set(CEREAL_VERSION_MINOR 1) + set(CEREAL_VERSION_PATCH 2) +elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/cereal.hpp") + + set(CEREAL_VERSION_MAJOR 1) + set(CEREAL_VERSION_MINOR 1) + set(CEREAL_VERSION_PATCH 1) +else() + + set(CEREAL_FOUND NO) + endif() + set(CEREAL_VERSION_STRING "${CEREAL_VERSION_MAJOR}.${CEREAL_VERSION_MINOR}.${CEREAL_VERSION_PATCH}") +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(cereal + REQUIRED_VARS CEREAL_INCLUDE_DIR + VERSION_VAR CEREAL_VERSION_STRING + ) + +mark_as_advanced(CEREAL_INCLUDE_DIR) diff --git a/CMake/R/ConfigureRCPP.cmake b/CMake/R/ConfigureRCPP.cmake index 8b3e8ef3b0..e728c73d34 100644 --- a/CMake/R/ConfigureRCPP.cmake +++ b/CMake/R/ConfigureRCPP.cmake @@ -54,9 +54,9 @@ Rcpp::RawVector Serialize${MODEL_SAFE_TYPE}Ptr(SEXP ptr) { std::ostringstream oss; { - boost::archive::binary_oarchive oa(oss); - oa << boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", - *Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr)); + cereal::BinaryOutputArchive oa(oss); + oa(cereal::make_nvp(\"${MODEL_SAFE_TYPE}\", + *Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr))); } Rcpp::RawVector raw_vec(oss.str().size()); @@ -76,8 +76,8 @@ SEXP Deserialize${MODEL_SAFE_TYPE}Ptr(Rcpp::RawVector str) std::istringstream iss(std::string((char *) &str[0], str.size())); { - boost::archive::binary_iarchive ia(iss); - ia >> boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", *ptr); + cereal::BinaryInputArchive ia(iss); + ia(cereal::make_nvp(\"${MODEL_SAFE_TYPE}\", *ptr)); } // R will be responsible for freeing this. diff --git a/CMake/julia/ConfigureJuliaHCPP.cmake b/CMake/julia/ConfigureJuliaHCPP.cmake index e8794b944a..1fb9a4b4be 100644 --- a/CMake/julia/ConfigureJuliaHCPP.cmake +++ b/CMake/julia/ConfigureJuliaHCPP.cmake @@ -55,9 +55,9 @@ char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length) { std::ostringstream oss; { - boost::archive::binary_oarchive oa(oss); + cereal::BinaryOutputArchive oa(oss); ${MODEL_TYPE}* model = (${MODEL_TYPE}*) ptr; - oa << boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", model); + oa(CEREAL_POINTER(model)); } *length = oss.str().length(); @@ -72,16 +72,16 @@ char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length) // Deserialize a ${MODEL_TYPE} pointer. void* Deserialize${MODEL_SAFE_TYPE}Ptr(const char* buffer, const size_t length) { - ${MODEL_TYPE}* t = new ${MODEL_TYPE}(); + ${MODEL_TYPE}* model = new ${MODEL_TYPE}(); std::istringstream iss(std::string(buffer, length)); { - boost::archive::binary_iarchive ia(iss); - ia >> boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", t); + cereal::BinaryInputArchive ia(iss); + ia(CEREAL_POINTER(model)); } // Julia will be responsible for freeing this. - return (void*) t; + return (void*) model; } ") endforeach () diff --git a/CMakeLists.txt b/CMakeLists.txt index 8235d8fc29..10f126283a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ option(BUILD_GO_SHLIB "Build Go shared library." OFF) set(ARMADILLO_VERSION "8.400.0") set(ENSMALLEN_VERSION "2.10.0") set(BOOST_VERSION "1.58") +set(CEREAL_VERSION "1.1.2") if (WIN32) option(BUILD_SHARED_LIBS @@ -140,7 +141,7 @@ set(COMPILER_SUPPORT_LIBRARIES "") # If we are using MSVC, we need /bigobj. if (MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /Zm400") endif () # If we are using MINGW, we need sections and big-obj, otherwise we create too @@ -353,7 +354,6 @@ else () set(STB_AVAILABLE "1") endif () - # Find ensmallen. # Once ensmallen is readily available in package repos, the automatic downloader # here can be removed. @@ -413,6 +413,9 @@ else () set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} "${ENSMALLEN_INCLUDE_DIR}") endif () +find_package(cereal "${CEREAL_VERSION}" REQUIRED) +set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${CEREAL_INCLUDE_DIR}) + # Unfortunately this configuration variable is necessary and will need to be # updated as time goes on and new versions are released. set(Boost_ADDITIONAL_VERSIONS @@ -441,8 +444,6 @@ set(Boost_ADDITIONAL_VERSIONS set(Boost_NO_BOOST_CMAKE 1) find_package(Boost "${BOOST_VERSION}" COMPONENTS - unit_test_framework - serialization REQUIRED ) diff --git a/Doxyfile b/Doxyfile index 8c5b7ec5b4..465aa90974 100644 --- a/Doxyfile +++ b/Doxyfile @@ -4,7 +4,7 @@ # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = mlpack -PROJECT_NUMBER = 3.4.1 +PROJECT_NUMBER = 3.4.2 OUTPUT_DIRECTORY = ./doc CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/HISTORY.md b/HISTORY.md index b839c8dc9e..e5aad5dcd4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,8 @@ ### mlpack ?.?.? ###### ????-??-?? + +### mlpack 3.4.2 +###### 2020-10-26 * Added Mean Absolute Percentage Error. * Added Softmin activation function as layer in ann/layer. diff --git a/README.md b/README.md index a0f9ea1822..ce4fd3239c 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ src="https://cdn.rawgit.com/mlpack/mlpack.org/e7d36ed8/mlpack-black.svg" style="

Download: - current stable version (3.4.1) + current stable version (3.4.2)

@@ -101,10 +101,10 @@ Citations are beneficial for the growth and improvement of mlpack. mlpack has the following dependencies: Armadillo >= 8.400.0 - Boost (math_c99, unit_test_framework, serialization, - spirit) >= 1.58.0 + Boost (math_c99, spirit) >= 1.58.0 CMake >= 3.2.2 ensmallen >= 2.10.0 + cereal >= 1.1.2 All of those should be available in your distribution's package manager. If not, you will have to compile each of them by hand. See the documentation for @@ -134,6 +134,7 @@ installed with these R packages. RcppEnsmallen >= 0.2.10.0 BH >= 1.58 roxygen2 + Rcereal >= 1.1.2 If the STB library headers are available, image loading support will be compiled. @@ -152,7 +153,7 @@ on Ubuntu, you can install mlpack with the following command: Note: Older Ubuntu versions may not have the most recent version of mlpack available---for instance, at the time of this writing, Ubuntu 16.04 only has -mlpack 3.4.1 available. Options include upgrading your Ubuntu version, finding +mlpack 3.4.2 available. Options include upgrading your Ubuntu version, finding a PPA or other non-official sources, or installing with a manual build. There are some useful pages to consult in addition to this section: diff --git a/doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj b/doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj index 92c3d1ae0a..02d1ed80b4 100644 --- a/doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj +++ b/doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj @@ -104,16 +104,16 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) false - C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.4.1\build\include;%(AdditionalIncludeDirectories) + C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.4.2\build\include;%(AdditionalIncludeDirectories) Console true - C:\mlpack\mlpack-3.4.1\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies) + C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies) - xcopy /y "C:\mlpack\mlpack-3.4.1\build\Debug\mlpack.dll" $(OutDir) -xcopy /y "C:\mlpack\mlpack-3.4.1\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir) + xcopy /y "C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.dll" $(OutDir) +xcopy /y "C:\mlpack\mlpack-3.4.2\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir) xcopy /y "$(ProjectDir)..\..\..\..\src\mlpack\tests\data\german.csv" "$(ProjectDir)data\german.csv*" diff --git a/doc/guide/bindings.hpp b/doc/guide/bindings.hpp index 2ef5db763b..8ad3d0b603 100644 --- a/doc/guide/bindings.hpp +++ b/doc/guide/bindings.hpp @@ -682,8 +682,8 @@ mlpack models. These could be used, for instance, to allow the user to save a trained model (like a linear regression model) or load an input model. The first parameter to the @c PARAM_MODEL_IN() or @c PARAM_MODEL_OUT() macro should be the C++ type of the model to be serialized; this type @b must have a function -template void Serialize(Archive&, const unsigned int) -(i.e. the type must be serializable via mlpack's boost::serialization shim). +template void serialize(Archive&) +(i.e. the type must be serializable via cereal). For example, to allow a user to specify an input model of type `LinearRegression`, the follow definition could be used: diff --git a/doc/guide/build.hpp b/doc/guide/build.hpp index 2c20941421..08068eaa73 100644 --- a/doc/guide/build.hpp +++ b/doc/guide/build.hpp @@ -30,7 +30,7 @@ to build mlpack on Windows, see \ref build_windows (alternatively, you can read is based on older versions). You can download the latest mlpack release from here: -mlpack-3.4.1 +mlpack-3.4.2 @section build_simple Simple Linux build instructions @@ -38,9 +38,9 @@ Assuming all dependencies are installed in the system, you can run the commands below directly to build and install mlpack. @code -$ wget https://www.mlpack.org/files/mlpack-3.4.1.tar.gz -$ tar -xvzpf mlpack-3.4.1.tar.gz -$ mkdir mlpack-3.4.1/build && cd mlpack-3.4.1/build +$ wget https://www.mlpack.org/files/mlpack-3.4.2.tar.gz +$ tar -xvzpf mlpack-3.4.2.tar.gz +$ mkdir mlpack-3.4.2/build && cd mlpack-3.4.2/build $ cmake ../ $ make -j4 # The -j is the number of cores you want to use for a build. $ sudo make install @@ -65,8 +65,8 @@ configure mlpack. First we should unpack the mlpack source and create a build directory. @code -$ tar -xvzpf mlpack-3.4.1.tar.gz -$ cd mlpack-3.4.1 +$ tar -xvzpf mlpack-3.4.2.tar.gz +$ cd mlpack-3.4.2 $ mkdir build @endcode @@ -78,8 +78,8 @@ mlpack depends on the following libraries, which need to be installed on the system and have headers present: - Armadillo >= 8.400.0 (with LAPACK support) - - Boost (math_c99, serialization, unit_test_framework, heap, - spirit) >= 1.58 + - Boost (math_c99, unit_test_framework, heap, spirit) >= 1.58 + - cereal >= 1.1.2 - ensmallen >= 2.10.0 (will be downloaded if not found) In addition, mlpack has the following optional dependencies: @@ -99,7 +99,7 @@ In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be installed through apt: @code -# apt-get install libboost-math-dev libboost-test-dev libboost-serialization-dev +# apt-get install libboost-math-dev libboost-test-dev libcereal-dev libarmadillo-dev binutils-dev python3-pandas python3-numpy cython3 python3-setuptools @endcode @@ -124,7 +124,7 @@ On Fedora, Red Hat, or CentOS, these same dependencies can be obtained via dnf: @code # dnf install boost-devel boost-test boost-math armadillo-devel binutils-devel python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel - stbi-devel + stbi-devel cereal-devel @endcode (It's also possible to use python3 packages from the package manager---mlpack diff --git a/doc/guide/formats.hpp b/doc/guide/formats.hpp index e7f216aae3..6a9577449e 100644 --- a/doc/guide/formats.hpp +++ b/doc/guide/formats.hpp @@ -447,11 +447,11 @@ Multiple images are saved according to the vector of filenames specified. @section formatmodels Loading and saving models -Using \c boost::serialization, mlpack is able to load and save machine learning +Using \c cereal, mlpack is able to load and save machine learning models with ease. These models can currently be saved in three formats: - binary (.bin); this is not human-readable, but it is small - - text (.txt); this is sort of human-readable and relatively small + - json (.json); this is sort of human-readable and relatively small - xml (.xml); this is human-readable but very verbose and large The type of file to save is determined by the given file extension, as with the @@ -471,7 +471,7 @@ options; for more information, see the documentation for each program @section formatmodelscpp Loading and saving models in C++ -mlpack uses the \c boost::serialization library internally to perform loading +mlpack uses the \c cereal library internally to perform loading and saving of models, and provides convenience overloads of mlpack::data::Load() and mlpack::data::Save() to load and save these models. @@ -479,13 +479,12 @@ To be serializable, a class must implement the method \code template -void serialize(Archive& ar, const unsigned int version); +void serialize(Archive& ar); \endcode \note For more information on this method and how it works, see the -boost::serialization documentation at -http://www.boost.org/libs/serialization/doc/. +cereal documentation at https://uscilab.github.io/cereal/index.html. \note Examples of serialize() methods can be found in most classes; one fairly @@ -503,11 +502,11 @@ mlpack::math::Range object. \code // Create range and save it. mlpack::math::Range r(0.0, 5.0); -mlpack::data::Save("range.txt", "range", r); +mlpack::data::Save("range.json", "range", r); // Load into new range. mlpack::math::Range newRange; -mlpack::data::Load("range.txt", "range", newRange); +mlpack::data::Load("range.json", "range", newRange); \endcode It is important to be sure that you load the appropriate type; if you save, for diff --git a/doc/guide/python_quickstart.hpp b/doc/guide/python_quickstart.hpp index 1f442fc39e..2f249ea5b5 100644 --- a/doc/guide/python_quickstart.hpp +++ b/doc/guide/python_quickstart.hpp @@ -32,9 +32,9 @@ build and install mlpack. You can copy-paste the commands into your shell. @code{.sh} sudo apt-get install libboost-all-dev g++ cmake libarmadillo-dev python-pip wget sudo pip install cython setuptools distutils numpy pandas -wget https://www.mlpack.org/files/mlpack-3.4.1.tar.gz -tar -xvzpf mlpack-3.4.1.tar.gz -mkdir -p mlpack-3.4.1/build/ && cd mlpack-3.4.1/build/ +wget https://www.mlpack.org/files/mlpack-3.4.2.tar.gz +tar -xvzpf mlpack-3.4.2.tar.gz +mkdir -p mlpack-3.4.2/build/ && cd mlpack-3.4.2/build/ cmake ../ && make -j4 && sudo make install @endcode diff --git a/doc/guide/sample_ml_app.hpp b/doc/guide/sample_ml_app.hpp index d2a350c85d..72a7253d5a 100644 --- a/doc/guide/sample_ml_app.hpp +++ b/doc/guide/sample_ml_app.hpp @@ -29,17 +29,17 @@ mlpack and dependencies in Release Mode). @code - C:\boost\boost_1_71_0\lib\native\include - C:\mlpack\armadillo-9.800.3\include - - C:\mlpack\mlpack-3.4.1\build\include + - C:\mlpack\mlpack-3.4.2\build\include @endcode - Under Linker > Input > Additional Dependencies add: @code - - C:\mlpack\mlpack-3.4.1\build\Debug\mlpack.lib + - C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.lib - C:\boost\boost_1_71_0\lib64-msvc-14.2\libboost_serialization-vc142-mt-gd-x64-1_71.lib @endcode - Under Build Events > Post-Build Event > Command Line add: @code - - xcopy /y "C:\mlpack\mlpack-3.4.1\build\Debug\mlpack.dll" $(OutDir) - - xcopy /y "C:\mlpack\mlpack-3.4.1\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir) + - xcopy /y "C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.dll" $(OutDir) + - xcopy /y "C:\mlpack\mlpack-3.4.2\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir) @endcode @note Recent versions of Visual Studio set "Conformance Mode" enabled by default. This causes some issues with diff --git a/doc/policies/trees.hpp b/doc/policies/trees.hpp index 5ac6cebfe8..20564ba77f 100644 --- a/doc/policies/trees.hpp +++ b/doc/policies/trees.hpp @@ -225,7 +225,7 @@ class ExampleTree // tree using the given MetricType. ExampleTree(const MatType& data, MetricType& metric); - // Initialize the tree from a given boost::serialization archive. SFINAE (the + // Initialize the tree from a given cereal archive. SFINAE (the // second argument) is necessary to ensure that the archive is loading, not // saving. template @@ -330,16 +330,16 @@ class ExampleTree // Serialize the tree (load from the given archive / save to the given // archive, depending on its type). template - void Serialize(Archive& ar, const unsigned int version); + void serialize(Archive& ar, const uint32_t version); protected: - // A default constructor; only meant to be used by boost::serialization. This - // must be protected so that boost::serialization will work; it does not need + // A default constructor; only meant to be used by cereal. This + // must be protected so that cereal will work; it does not need // to return a valid tree. ExampleTree(); // Friend access must be given for the default constructor. - friend class boost::serialization::access; + friend class cereal::access; }; @endcode @@ -378,7 +378,7 @@ calculation, and (usually) provides a decent bound on the minimum distance between \f$p\f$ and any descendant point of the node. - **Trees need to be able to be serialized.** mlpack uses the -boost::serialization library for saving and loading objects. Trees---which can +cereal library for saving and loading objects. Trees---which can be a part of machine learning models---therefore must have the ability to be saved and loaded. Making this all work requires a protected constructor (part of the API) and generally makes it impossible to hold references instead of @@ -481,10 +481,10 @@ It is possible to implement both these constructors as one by using \c boost::optional. The third constructor requires the tree to be initializable from a \c -boost::serialization archive: +cereal archive: @code -// Initialize the tree from a given boost::serialization archive. SFINAE (the +// Initialize the tree from a given cereal archive. SFINAE (the // second argument) is necessary to ensure that the archive is loading, not // saving. template @@ -507,7 +507,7 @@ will be required: and, if the data matrix is represented internally with a pointer, this destructor will need to release the memory for the data matrix (in the case that -the tree was created via \c boost::serialization ). +the tree was created via \c cereal ). Note that these constructors are not necessarily the only constructors that a \c TreeType implementation can provide. One important example of when more @@ -778,22 +778,22 @@ the node plus one or two levels of children. // Serialize the tree (load from the given archive / save to the given // archive, depending on its type). template -void Serialize(Archive& ar, const unsigned int version); +void serialize(Archive& ar); protected: -// A default constructor; only meant to be used by boost::serialization. This -// must be protected so that boost::serialization will work; it does not need +// A default constructor; only meant to be used by cereal. This +// must be protected so that cereal will work; it does not need // to return a valid tree. ExampleTree(); // Friend access must be given for the default constructor. -friend class boost::serialization::access; +friend class cereal::access; @endcode On the other hand, the specifics of the functionality required for the \c Serialize() function are somewhat more difficult. The \c Serialize() function will be called either when a tree is being saved to disk or loaded from -disk. The \c boost::serialization documentation is fairly comprehensive, but +disk. The \c cereal documentation is fairly comprehensive. when writing a \c Serialize() method for mlpack trees you should use \c data::CreateNVP() instead of \c BOOST_SERIALIZATION_NVP(). This is because mlpack classes implement \c Serialize() instead of \c serialize() in order to @@ -803,10 +803,10 @@ be useful to look at other \c Serialize() methods contained in other mlpack classes as an example. An important note is that it is very difficult to use references with -\c boost::serialization, because \c Serialize() may be called at any time during +\c cereal, because \c serialize() may be called at any time during the object's lifetime, and references cannot be re-seated. In general this will require the use of pointers, which then require manual memory management. -Therefore, be careful that \c Serialize() (and the tree's destructor) properly +Therefore, be careful that \c serialize() (and the tree's destructor) properly handle memory management! @section treetype_traits The TreeTraits trait class diff --git a/doc/tutorials/ann/ann.txt b/doc/tutorials/ann/ann.txt index d7bc023025..7cdb9d1f57 100644 --- a/doc/tutorials/ann/ann.txt +++ b/doc/tutorials/ann/ann.txt @@ -573,8 +573,8 @@ a new reference set. This is functionally equivalent to creating a new model. @section model_saving_loading_anntut Saving & Loading -Using \c boost::serialization (for more information about the internals see -[Serialization - Boost C++ Libraries](www.boost.org/libs/serialization/doc/)), +Using \c cereal (for more information about the internals see +[the Cereal website](http://uscilab.github.io/cereal/)), mlpack is able to load and save machine learning models with ease. To save a trained neural network to disk. The example below builds a model on the \c thyroid dataset and then saves the model to the file \c model.xml for later use. @@ -589,7 +589,7 @@ arma::mat trainData = dataset.submat(0, 0, dataset.n_rows - 4, dataset.n_cols - 1); // Split the data from the training set. -arma::mat trainLabelsTemp = dataset.submat(dataset.n_rows - 3, 0, +arma::mat trainLabels = dataset.submat(dataset.n_rows - 3, 0, dataset.n_rows - 1, dataset.n_cols - 1); // Initialize the network. @@ -615,50 +615,76 @@ Now, we can look at the output model file, \c model.xml: @code $ cat model.xml - - - - - - 66 - 1 - 66 - 0 - -7.55971528334903642e+00 - -9.95435955058058930e+00 - 9.31133928948225353e+00 - -5.36784434861701953e+00 - ... - - 0 - 0 - - 0 - 0 - 0 - 0 - - - 3 - 0 - - 18 - - 21 - 3 - - - - 2 - - - - 20 - - - - - + + + + 0 + + 60 + 1 + 0 + 10.461979353567767 + -10.040855482151116 + 0.18048901768535316 + 4.8989495084787169 + -4.4381643782652276 + 0.049477846402230616 + 2.5271808924795987 + -3.96993488526287 + ... + + 0 + 0 + true + + 3 + + 30 + + 0 + + + 1 + + 0 + 19 + 3 + + + + + + + 6 + + 0 + + + 1 + + 0 + + + + + + + 32 + + 0 + + + 1 + + 0 + + + + + + + + @endcode As you can see, the \c \ section of \c model.xml contains the trained diff --git a/scripts/release-mlpack.sh b/scripts/release-mlpack.sh new file mode 100755 index 0000000000..5997ace895 --- /dev/null +++ b/scripts/release-mlpack.sh @@ -0,0 +1,221 @@ +#!/usr/bin/env bash +# +# Release a new version of mlpack. +# +# Usage: release-mlpack.sh X Y Z +# +# where X is the major version, Y is the minor version, and Z is the patch +# version. Run this from the root of the repository. +# +# Make sure HISTORY.md is updated first! +set +e + +if [ "$#" -ne "4" ]; +then + echo "Usage: mlpack-release.sh "; + exit 1; +fi + +# First, check for any unlicensed files. +output=$( + for i in $(find src/ -iname '*.[hc]pp'); + do + echo -n $i": "; + cat $i | grep 'mlpack is free software;' | wc -l; + done |\ + grep -v ': 1' |\ + grep -v 'arma_extend' |\ + grep -v 'boost_backport' |\ + grep -v 'arma_config.hpp' |\ + grep -v 'gitversion.hpp' |\ + grep -v 'CLI11.hpp' |\ + grep -v 'bindings/R/mlpack/src/boost/serialization' |\ + grep -v 'tests/catch.hpp'); +lines=`echo $output | grep -v '^[ ]*$' | wc -l`; + +if [ "0$lines" -gt "0" ]; +then + echo "Unlicensed files found! Aborting release."; + echo "$output"; + exit 1; +fi + +# Now, check that there are no local changes. +lines=`git diff | wc -l | sed -e 's/^\s*//g'`; +if [ "$lines" != "0" ]; then + echo "git diff returned a nonzero result!"; + echo ""; + git diff; + exit 1; +fi + +# Next, make sure the origin is right. +dest_remote_name=`git remote -v |\ + grep "mlpack/mlpack (fetch)" |\ + head -1 |\ + awk -F' ' '{ print $1 }'`; + +if [ "a$dest_remote_name" == "a" ]; then + echo "No git remote found for https://github.com/mlpack/mlpack!"; + echo "Make sure that you've got the ensmallen repository as a remote, and" \ + "that the master branch from that remote is checked out."; + echo "You can do this with a fresh repository via \`git clone" \ + "https://github.com/mlpack/mlpack\`."; + exit 1; +fi + +# Also check that we're on the master branch, from the correct origin. +current_branch=`git branch --no-color | grep '^\* ' | awk -F' ' '{ print $2 }'`; +current_origin=`git rev-parse --abbrev-ref --symbolic-full-name @{u} |\ + awk -F'/' '{ print $1 }'`; +if [ "a$current_branch" != "amaster" ]; then + echo "Current branch is $current_branch."; + echo "This script has to be run from the master branch."; + exit 1; +elif [ "a$current_origin" != "a$dest_remote_name" ]; then + echo "Current branch does not track from remote mlpack repository!"; + echo "Instead, it tracks from $current_origin/master."; + echo "Make sure to check out a branch that tracks $dest_remote_name/master."; + exit 1; +fi + +# Make sure `hub` is installed. +hub_output="`which hub`" || true; +if [ "a$hub_output" == "a" ]; then + echo "The Hub command-line tool must be installed for this script to run" \ + "successfully."; + echo "See https://hub.github.com for more details and installation" \ + "instructions."; + echo ""; + echo "(apt-get install hub on Debian and Ubuntu)"; + echo "(brew install hub via Homebrew)"; + exit 1; +fi + +# Check git remotes: we need to make sure we have a fork to push to. +github_user=$1; +remote_name`git remote -v |\ + grep "$github_user/mlpack (push)" |\ + head -1 |\ + awk -F' ' '{ print $1 }'`; +if [ "a$remote_name" == "a" ]; then + echo "No git remote found for $github_user/mlpack!"; + echo "Adding remote '$github_user'."; + git remote add $github_user https://github.com/$github_user/mlpack; + remote_name="$github_user"; +fi +git fetch $github_user; + +# Make sure everything is up to date. +git pull; + +# Make updates to files that will be needed for the release. +MAJOR="$2"; +MINOR="$3"; +PATCH="$4"; + +# Update version. +sed --in-place -E 's/PROJECT_NUMBER([ \t]*)= .*$/PROJECT_NUMBER\1= '$MAJOR'.'$MINOR'.'$PATCH'/' \ + Doxyfile; +sed --in-place 's/MLPACK_VERSION_MAJOR [0-9]*$/MLPACK_VERSION_MAJOR '$MAJOR'/' \ + src/mlpack/core/util/version.hpp; +sed --in-place 's/MLPACK_VERSION_MINOR [0-9]*$/MLPACK_VERSION_MINOR '$MINOR'/' \ + src/mlpack/core/util/version.hpp; +sed --in-place 's/MLPACK_VERSION_PATCH [0-9]*$/MLPACK_VERSION_PATCH '$PATCH'/' \ + src/mlpack/core/util/version.hpp; +sed --in-place 's/ VERSION [0-9]*\.[0-9]*/ VERSION '$MAJOR'.'$MINOR'/' \ + src/mlpack/CMakeLists.txt; + +sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \ + doc/guide/build.hpp; +sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \ + doc/guide/python_quickstart.hpp; +sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \ + doc/guide/sample_ml_app.hpp; +sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \ + doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj; + +sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \ + README.md; +sed --in-place 's/([0-9]\.[0-9]\.[0-9])/('$MAJOR'.'$MINOR'.'$PATCH')/g' \ + README.md; +sed --in-place 's/mlpack [0-9]\.[0-9]\.[0-9]/mlpack '$MAJOR'.'$MINOR'.'$PATCH'/g' \ + README.md; + +sed --in-place 's/### mlpack ?[.]?[.]?/### mlpack '$MAJOR'.'$MINOR'.'$PATCH'/g' HISTORY.md; +year=`date +%Y`; +month=`date +%m`; +day=`date +%d`; +sed --in-place 's/###### ????-??-??/###### '$year'-'$month'-'$day'/g' \ + HISTORY.md; + +# Get the latest release of ensmallen. +git clone https://github.com/mlpack/ensmallen /tmp/ensmallen; +cd /tmp/ensmallen; +ens_ver=`git describe --tags $(git rev-list --tags --max-count=1)`; +echo "Latest version of ensmallen: $ens_ver" +cd -; +sed --in-place "s/ensmallen-latest.tar.gz/ensmallen-$ens_ver.tar.gz/" CMakeLists.txt; +rm -rf /tmp/ensmallen; + +# Make these changes on a release branch. +git checkout -b release-$MAJOR.$MINOR.$PATCH; + +git add Doxyfile src/mlpack/core/util/version.hpp src/mlpack/CMakeLists.txt \ + doc/guide/build.hpp doc/guide/python_quickstart.hpp \ + doc/guide/sample_ml_app.hpp \ + doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj \ + CMakeLists.txt \ + README.md \ + HISTORY.md; + +git commit -m "Update and release version $MAJOR.$MINOR.$PATCH."; + +changelog_str=`cat HISTORY.md |\ + awk '/^### /{f=0} /^### mlpack '"$MAJOR"'.'"$MINOR"'.'"$PATCH"'/{f=1} f{print}' |\ + grep -v '^#' |\ + tr '\n' '!' |\ + sed -e 's/! [ ]*/ /g' |\ + tr '!' '\n'`; +echo "Changelog string:" +echo "$changelog_str" + +# Update version again and add a new block for HISTORY.md. +sed --in-place 's/MLPACK_VERSION_PATCH [0-9]*$/MLPACK_VERSION_PATCH '$(($PATCH + 1))'/' \ + src/mlpack/core/util/version.hpp; +sed --in-place 's/ensmallen-'$ens_ver'.tar.gz/ensmallen-latest.tar.gz/' CMakeLists.txt; + +echo "### mlpack ?.?.?" > HISTORY.md.new; +echo "###### ????-??-??" >> HISTORY.md.new; +echo "" >> HISTORY.md.new; +cat HISTORY.md >> HISTORY.md.new; +mv HISTORY.md.new HISTORY.md; + +git add HISTORY.md; +git add src/mlpack/core/util/version.hpp CMakeLists.txt; + +git commit -m "Add new block for next release to HISTORY.md."; + +# Push to new branch. +git push --set-upstream $github_user release-$MAJOR.$MINOR.$PATCH; + +# Next, we have to actually open the PR for the release. +hub pull-request \ + -b mlpack:master \ + -h $github_user:release-$MAJOR.$MINOR.$PATCH \ + -m "Release version $MAJOR.$MINOR.$PATCH" \ + -m "This automatically-generated pull request adds the commits necessary to +make the $MAJOR.$MINOR.$PATCH release." \ + -m "Once the PR is merged, mlpack-bot will tag the release as HEAD~1 (so +that it doesn't include the new HISTORY block) and publish it." \ + -m "Or, well, hopefully that will happen someday." \ + -m "When you merge this PR, be sure to merge it using a *rebase*." \ + -m "### Changelog" \ + -m "$changelog_str" \ + -l "t: release" + +echo ""; +echo "Switching back to 'master' branch."; +echo "If you want to access the release branch again, use \`git checkout " \ + "release-$MAJOR.$MINOR.$PATCH\`."; +echo 0; diff --git a/scripts/update-website-after-release.sh b/scripts/update-website-after-release.sh new file mode 100755 index 0000000000..e80ad8694f --- /dev/null +++ b/scripts/update-website-after-release.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# +# This script is used to update the website after an mlpack release is made. +# Push access to the mlpack.org website repository is needed. Generally, this +# script will be run by mlpack-bot, so it never needs to be run by hand. +# +# Usage: update-website-after-release.sh + +MAJOR=$1; +MINOR=$2; +PATCH=$3; + +# Make sure that the mlpack repository exists. +dest_remote_name=`git remote -v |\ + grep "mlpack/mlpack (fetch)" |\ + head -1 |\ + awk -F' ' '{ print $1 }'`; + +if [ "a$dest_remote_name" == "a" ]; then + echo "No git remote found for mlpack/mlpack!"; + echo "Make sure that you've got the mlpack repository as a remote, and" \ + "that the master branch from that remote is checked out."; + echo "You can do this with a fresh repository via \`git clone" \ + "https://github.com/mlpack/mlpack\`."; + exit 1; +fi + +# Update the checked out repository, so that we can get the tags. +git fetch $dest_remote_name; + +# Check out a copy of the ensmallen.org repository. +git clone git@github.com:mlpack/mlpack.org /tmp/mlpack.org/; + +# Create the release file. +git archive --prefix=mlpack-$MAJOR.$MINOR.$PATCH/ $MAJOR.$MINOR.$PATCH |\ + gzip > /tmp/mlpack.org/files/mlpack-$MAJOR.$MINOR.$PATCH.tar.gz; + +# Now update the website. +wd=`pwd`; +cd /tmp/mlpack.org/; + +# These may be specific to the old website. +sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' index.md; +sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' docs.md; +sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' getstarted.md; +sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' community.md; +git add index.md docs.md getstarted.md community.md; + +# These may be specific to the new website. +sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' html/index.html; +sed --in-place 's/Version [0-9]\.[0-9]\.[0-9]/Version '$MAJOR'.'$MINOR'.'$PATCH'/g' html/index.html; +sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' html/getstarted.html; +sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' html/config/install.md; +git add html/index.html html/getstarted.html html/config/install.md; + +git commit -m "Update links to latest stable version."; + +git add files/mlpack-$MAJOR.$MINOR.$PATCH.tar.gz; +git commit -m "Release version $MAJOR.$MINOR.$PATCH."; + +# Finally, push, and we're done. +git push origin; +cd $wd; + +rm -rf /tmp/mlpack.org; diff --git a/src/mlpack/bindings/R/CMakeLists.txt b/src/mlpack/bindings/R/CMakeLists.txt index 18ac878ac9..f56ef3f379 100644 --- a/src/mlpack/bindings/R/CMakeLists.txt +++ b/src/mlpack/bindings/R/CMakeLists.txt @@ -23,6 +23,7 @@ if (BUILD_R_BINDINGS) set(RcppArmadillo_Version "0.${ARMADILLO_VERSION}") set(RcppEnsmallen_Version "0.${ENSMALLEN_VERSION}") set(BH_Version "${BOOST_VERSION}") + set(Rcereal_Version "${CEREAL_VERSION}") # Import find_r_module. include(${CMAKE_SOURCE_DIR}/CMake/FindRModule.cmake) @@ -54,18 +55,22 @@ if (BUILD_R_BINDINGS) if (NOT R_TESTTHAT) set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - testthat") endif () + find_r_module(Rcereal "${Rcereal_Version}") + if (NOT R_RCEREAL) + set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - Rcereal") + endif () ## We need to check here if R and other dependencies is even available, as ## it is require to build R-bindings. if (FORCE_BUILD_R_BINDINGS) if (NOT R_FOUND OR NOT R_RCPP OR NOT R_RCPPARMADILLO OR NOT R_RCPPENSMALLEN - OR NOT R_BH OR NOT R_ROXYGEN2 OR NOT R_TESTTHAT) + OR NOT R_BH OR NOT R_ROXYGEN2 OR NOT R_TESTTHAT OR NOT R_RCEREAL) unset(BUILD_R_BINDINGS CACHE) message(FATAL_ERROR "Could not Build R Bindings, Following modules are not available:${R_NOT_FOUND_MSG}") endif() else () if (NOT R_FOUND OR NOT R_RCPP OR NOT R_RCPPARMADILLO OR NOT R_RCPPENSMALLEN - OR NOT R_BH OR NOT R_ROXYGEN2 OR NOT R_TESTTHAT) + OR NOT R_BH OR NOT R_ROXYGEN2 OR NOT R_TESTTHAT OR NOT R_RCEREAL) unset(BUILD_R_BINDINGS CACHE) not_found_return("Not building R bindings, Following modules are not available:${R_NOT_FOUND_MSG}") endif() @@ -97,33 +102,6 @@ if (BUILD_R_BINDINGS) "# Generated by roxygen2: do not edit by hand" "\n\n") - # These are all the files we need to compile R bindings for mlpack that are - # not a part of mlpack itself. - # Soon may be mlpack use cereal package for serialization. - # Then we can remove these boost files. - set(BOOST_SOURCES - "${CMAKE_SOURCE_DIR}/src/mlpack/core/boost_backport/unordered_map.hpp" - "${CMAKE_SOURCE_DIR}/src/mlpack/core/boost_backport/unordered_collections_load_imp.hpp" - "${CMAKE_SOURCE_DIR}/src/mlpack/core/boost_backport/unordered_collections_save_imp.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/archive_exception.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_archive.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_oarchive.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_oserializer.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_iarchive.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_iserializer.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_pointer_iserializer.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_pointer_oserializer.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_text_oprimitive.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/basic_serializer_map.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/binary_iarchive.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/binary_oarchive.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/extended_type_info_typeid.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/extended_type_info.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/utf8_codecvt_facet.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/void_cast.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/boost/serialization/variant.hpp" - ) - set(CPP_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/r_util.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/rcpp_mlpack.h" @@ -174,8 +152,6 @@ if (BUILD_R_BINDINGS) ${CMAKE_CURRENT_BINARY_DIR}/mlpack/R/ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/mlpack/tests/testthat - COMMAND ${CMAKE_COMMAND} -E make_directory - ${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/boost/serialization/ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R/tests ) @@ -188,12 +164,6 @@ if (BUILD_R_BINDINGS) endif() # Copy all necessary files for building package. - foreach(boost_file ${BOOST_SOURCES}) - add_custom_command(TARGET r_copy PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different - ${boost_file} - ${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/boost/serialization/) - endforeach() foreach(cpp_file ${CPP_SOURCES}) add_custom_command(TARGET r_copy PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different @@ -307,9 +277,9 @@ if (BUILD_R_BINDINGS) -DGENERATE_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/generate_R.cpp.in -DGENERATE_CPP_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/build/generate_r_${name}.cpp -DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp - -P ${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake + -P ${CMAKE_SOURCE_DIR}/CMake/ConfigureFile.cmake DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/generate_R.cpp.in - ${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake + ${CMAKE_SOURCE_DIR}/CMake/ConfigureFile.cmake ${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/${name}.cpp) add_executable(generate_r_${name} diff --git a/src/mlpack/bindings/R/mlpack/DESCRIPTION.in b/src/mlpack/bindings/R/mlpack/DESCRIPTION.in index 9183f6bb62..db9890f5dd 100644 --- a/src/mlpack/bindings/R/mlpack/DESCRIPTION.in +++ b/src/mlpack/bindings/R/mlpack/DESCRIPTION.in @@ -15,7 +15,8 @@ Imports: Rcpp (>= 0.12.12) LinkingTo: Rcpp, RcppArmadillo (>= @RcppArmadillo_Version@), BH (>= @BH_Version@), - RcppEnsmallen (>= @RcppEnsmallen_Version@) + RcppEnsmallen (>= @RcppEnsmallen_Version@), + Rcereal (>= @Rcereal_Version@) Suggests: testthat (>= 2.1.0) URL: https://www.mlpack.org/doc/mlpack-@PACKAGE_VERSION@/r_documentation.html, https://github.com/mlpack/mlpack diff --git a/src/mlpack/bindings/R/mlpack/inst/include/mlpack.h.in b/src/mlpack/bindings/R/mlpack/inst/include/mlpack.h.in index a2c17842d1..9db76b5c2a 100644 --- a/src/mlpack/bindings/R/mlpack/inst/include/mlpack.h.in +++ b/src/mlpack/bindings/R/mlpack/inst/include/mlpack.h.in @@ -41,32 +41,21 @@ // To suppress warnings related to core/util/arma_util.hpp. #define MLPACK_CORE_UTIL_ARMA_CONFIG_HPP +// Undefine macro due to macro collision. +#undef Realloc +#undef Free + @R_SRC@ #include -// These are all the boost files, we need to compile R bindings for mlpack that -// are not a part of mlpack itself. -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #undef ARMA_EXTRA_MAT_PROTO #undef ARMA_EXTRA_MAT_MEAT +// Define R Internal macro again after including cereal headers. +#define Realloc(p,n,t) (t *) R_chk_realloc( (void *)(p), (R_SIZE_T)((n) * sizeof(t)) ) +#define Free(p) (R_chk_free( (void *)(p) ), (p) = NULL) + // instead of including RcppArmadillo.h -- which re-includes parts // of Armadillo already brought in by mlpack, we just include pieces // needed for sugar wrapping etc diff --git a/src/mlpack/bindings/R/mlpack/src/Makevars.win b/src/mlpack/bindings/R/mlpack/src/Makevars.win index 4cca03b1a5..bb6a88cc84 100644 --- a/src/mlpack/bindings/R/mlpack/src/Makevars.win +++ b/src/mlpack/bindings/R/mlpack/src/Makevars.win @@ -1,3 +1,3 @@ -PKG_CXXFLAGS = -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false -I. $(SHLIB_OPENMP_CXXFLAGS) -ftrack-macro-expansion=0 +PKG_CXXFLAGS = -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false -I. $(SHLIB_OPENMP_CXXFLAGS) PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) CXX_STD = CXX11 diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/archive_exception.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/archive_exception.cpp deleted file mode 100644 index 729a4edb25..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/archive_exception.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// archive_exception.cpp: - -// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#if (defined _MSC_VER) && (_MSC_VER == 1200) -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -#include -#include -#include - -#define BOOST_ARCHIVE_SOURCE -#include -#include - -namespace boost { -namespace archive { - -BOOST_ARCHIVE_DECL -unsigned int -archive_exception::append(unsigned int l, const char * a){ - while(l < (sizeof(m_buffer) - 1)){ - char c = *a++; - if('\0' == c) - break; - m_buffer[l++] = c; - } - m_buffer[l] = '\0'; - return l; -} - -BOOST_ARCHIVE_DECL -archive_exception::archive_exception( - exception_code c, - const char * e1, - const char * e2 -) BOOST_NOEXCEPT : - code(c) -{ - unsigned int length = 0; - switch(code){ - case no_exception: - length = append(length, "uninitialized exception"); - break; - case unregistered_class: - length = append(length, "unregistered class"); - if(NULL != e1){ - length = append(length, " - "); - length = append(length, e1); - } - break; - case invalid_signature: - length = append(length, "invalid signature"); - break; - case unsupported_version: - length = append(length, "unsupported version"); - break; - case pointer_conflict: - length = append(length, "pointer conflict"); - break; - case incompatible_native_format: - length = append(length, "incompatible native format"); - if(NULL != e1){ - length = append(length, " - "); - length = append(length, e1); - } - break; - case array_size_too_short: - length = append(length, "array size too short"); - break; - case input_stream_error: - length = append(length, "input stream error"); - if(NULL != e1){ - length = append(length, "-"); - length = append(length, e1); - } - if(NULL != e2){ - length = append(length, "-"); - length = append(length, e2); - } - break; - case invalid_class_name: - length = append(length, "class name too long"); - break; - case unregistered_cast: - length = append(length, "unregistered void cast "); - length = append(length, (NULL != e1) ? e1 : "?"); - length = append(length, "<-"); - length = append(length, (NULL != e2) ? e2 : "?"); - break; - case unsupported_class_version: - length = append(length, "class version "); - length = append(length, (NULL != e1) ? e1 : ""); - break; - case other_exception: - // if get here - it indicates a derived exception - // was sliced by passing by value in catch - length = append(length, "unknown derived exception"); - break; - case multiple_code_instantiation: - length = append(length, "code instantiated in more than one module"); - if(NULL != e1){ - length = append(length, " - "); - length = append(length, e1); - } - break; - case output_stream_error: - length = append(length, "output stream error"); - if(NULL != e1){ - length = append(length, "-"); - length = append(length, e1); - } - if(NULL != e2){ - length = append(length, "-"); - length = append(length, e2); - } - break; - default: - BOOST_ASSERT(false); - length = append(length, "programming error"); - break; - } -} - -BOOST_ARCHIVE_DECL -archive_exception::archive_exception(archive_exception const & oth) BOOST_NOEXCEPT : - std::exception(oth), - code(oth.code) -{ - std::memcpy(m_buffer,oth.m_buffer,sizeof m_buffer); -} - -BOOST_ARCHIVE_DECL -archive_exception::~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW {} - -BOOST_ARCHIVE_DECL const char * -archive_exception::what() const BOOST_NOEXCEPT_OR_NOTHROW { - return m_buffer; -} - -BOOST_ARCHIVE_DECL -archive_exception::archive_exception() BOOST_NOEXCEPT : - code(no_exception) -{} - -} // archive -} // boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_archive.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_archive.cpp deleted file mode 100644 index 0649388bf5..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_archive.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_archive.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -////////////////////////////////////////////////////////////////////// -// -// objects are stored as -// -// class_id* // -1 for a null pointer -// if a new class id -// [ -// exported key - class name* -// tracking level - always/never -// class version -// ] -// -// if tracking -// [ -// object_id -// ] -// -// [ // if a new object id -// data... -// ] -// -// * required only for pointers - optional for objects - -#define BOOST_ARCHIVE_SOURCE -#include -#include - -namespace boost { -namespace archive { - -/////////////////////////////////////////////////////////////////////// -// constants used in archive signature -//This should never ever change. note that is not an std::string -// string. -BOOST_SYMBOL_VISIBLE const char * -BOOST_ARCHIVE_SIGNATURE(){ - return "serialization::archive"; -} - -// this should change if the capabilities are added to the library -// such that archives can be created which can't be read by previous -// versions of this library -// 1 - initial version -// 2 - made address tracking optional -// 3 - numerous changes - can't guarentee compatibility with previous versions -// 4 - Boost 1.34 -// added item_version to properly support versioning for collections -// 5 - Boost 1.36 -// changed serialization of collections: adding version even for primitive -// types caused backwards compatibility breaking change in 1.35 -// 6 - Boost 1.41 17 Nov 2009 -// serializing collection sizes as std::size_t -// 7 Boost 1.42 2 Feb 2010 -// error - changed binary version to 16 bits w/o changing library version # -// That is - binary archives are recorded with #6 even though they are -// different from the previous versions. This means that binary archives -// created with versions 1.42 and 1.43 will have to be fixed with a special -// program which fixes the library version # in the header -// Boost 1.43 6 May 2010 -// no change -// 8 - Boost 1.44 -// separated version_type into library_version_type and class_version_type -// changed version_type to be stored as 8 bits. -// 10- fixed base64 output/input. -// 11- not changes -// 12- improved serialization of collections -// 13- simplified visibility, removed Borland, removed pfto -// 14- improved visibility, refactor map/set -// 15- corrections to optional and collection loading -// 16- eliminated dependency on which is buggy in some libraries -// and now officially deprecated in the standard -// 17- Boost 1.68 August 2018 -// 18- addressed undefined behavior in archive constuctors. -// init() called from base wrote archive header before archive -// was fully constructed. - -BOOST_SYMBOL_VISIBLE library_version_type -BOOST_ARCHIVE_VERSION(){ - return library_version_type(18); -} - -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_iarchive.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_iarchive.cpp deleted file mode 100644 index 344e37a30b..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_iarchive.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_archive.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // msvc 6.0 needs this to suppress warnings - -#include -#include -#include -#include -#include // size_t, NULL - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -#define BOOST_ARCHIVE_SOURCE -// include this to prevent linker errors when the -// same modules are marked export and import. -#define BOOST_SERIALIZATION_SOURCE -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -using namespace boost::serialization; - -namespace boost { -namespace archive { -namespace detail { - -class basic_iarchive_impl { - friend class basic_iarchive; - library_version_type m_archive_library_version; - unsigned int m_flags; - - ////////////////////////////////////////////////////////////////////// - // information about each serialized object loaded - // indexed on object_id - struct aobject - { - void * address; - bool loaded_as_pointer; - class_id_type class_id; - aobject( - void *a, - class_id_type class_id_ - ) : - address(a), - loaded_as_pointer(false), - class_id(class_id_) - {} - aobject() : - address(NULL), - loaded_as_pointer(false), - class_id(-2) - {} - }; - typedef std::vector object_id_vector_type; - object_id_vector_type object_id_vector; - - ////////////////////////////////////////////////////////////////////// - // used to implement the reset_object_address operation. - struct moveable_objects { - object_id_type start; - object_id_type end; - object_id_type recent; - bool is_pointer; - moveable_objects() : - start(0), - end(0), - recent(0), - is_pointer(false) - {} - } m_moveable_objects; - - void reset_object_address( - const void * new_address, - const void *old_address - ); - - ////////////////////////////////////////////////////////////////////// - // used by load object to look up class id given basic_serializer - struct cobject_type - { - const basic_iserializer * m_bis; - const class_id_type m_class_id; - cobject_type( - std::size_t class_id, - const basic_iserializer & bis - ) : - m_bis(& bis), - m_class_id(class_id) - {} - cobject_type(const cobject_type & rhs) : - m_bis(rhs.m_bis), - m_class_id(rhs.m_class_id) - {} - // the following cannot be defined because of the const - // member. This will generate a link error if an attempt - // is made to assign. This should never be necessary - cobject_type & operator=(const cobject_type & rhs); - bool operator<(const cobject_type &rhs) const - { - return *m_bis < *(rhs.m_bis); - } - }; - typedef std::set cobject_info_set_type; - cobject_info_set_type cobject_info_set; - - ////////////////////////////////////////////////////////////////////// - // information about each serialized class indexed on class_id - class cobject_id - { - public: - cobject_id & operator=(const cobject_id & rhs){ - bis_ptr = rhs.bis_ptr; - bpis_ptr = rhs.bpis_ptr; - file_version = rhs.file_version; - tracking_level = rhs.tracking_level; - initialized = rhs.initialized; - return *this; - } - const basic_iserializer * bis_ptr; - const basic_pointer_iserializer * bpis_ptr; - version_type file_version; - tracking_type tracking_level; - bool initialized; - - cobject_id(const basic_iserializer & bis_) : - bis_ptr(& bis_), - bpis_ptr(NULL), - file_version(0), - tracking_level(track_never), - initialized(false) - {} - cobject_id(const cobject_id &rhs): - bis_ptr(rhs.bis_ptr), - bpis_ptr(rhs.bpis_ptr), - file_version(rhs.file_version), - tracking_level(rhs.tracking_level), - initialized(rhs.initialized) - {} - }; - typedef std::vector cobject_id_vector_type; - cobject_id_vector_type cobject_id_vector; - - ////////////////////////////////////////////////////////////////////// - // address of the most recent object serialized as a poiner - // whose data itself is now pending serialization - struct pending { - void * object; - const basic_iserializer * bis; - version_type version; - pending() : - object(NULL), - bis(NULL), - version(0) - {} - } m_pending; - - basic_iarchive_impl(unsigned int flags) : - m_archive_library_version(BOOST_ARCHIVE_VERSION()), - m_flags(flags) - {} - void set_library_version(library_version_type archive_library_version){ - m_archive_library_version = archive_library_version; - } - bool - track( - basic_iarchive & ar, - void * & t - ); - void - load_preamble( - basic_iarchive & ar, - cobject_id & co - ); - class_id_type register_type( - const basic_iserializer & bis - ); - - // redirect through virtual functions to load functions for this archive - template - void load(basic_iarchive & ar, T & t){ - ar.vload(t); - } - -//public: - void - next_object_pointer(void * t){ - m_pending.object = t; - } - void delete_created_pointers(); - class_id_type register_type( - const basic_pointer_iserializer & bpis - ); - void load_object( - basic_iarchive & ar, - void * t, - const basic_iserializer & bis - ); - const basic_pointer_iserializer * load_pointer( - basic_iarchive & ar, - void * & t, - const basic_pointer_iserializer * bpis, - const basic_pointer_iserializer * (*finder)( - const boost::serialization::extended_type_info & type - ) - ); -}; - -inline void -basic_iarchive_impl::reset_object_address( - void const * const new_address, - void const * const old_address -){ - if(m_moveable_objects.is_pointer) - return; - - // this code handles a couple of situations. - // a) where reset_object_address is applied to an untracked object. - // In such a case the call is really superfluous and its really an - // an error. But we don't have access to the types here so we can't - // know that. However, this code will effectively turn this situation - // into a no-op and every thing will work fine - albeat with a small - // execution time penalty. - // b) where the call to reset_object_address doesn't immediatly follow - // the << operator to which it corresponds. This would be a bad idea - // but the code may work anyway. Naturally, a bad practice on the part - // of the programmer but we can't detect it - as above. So maybe we - // can save a few more people from themselves as above. - object_id_type i = m_moveable_objects.recent; - for(; i < m_moveable_objects.end; ++i){ - if(old_address == object_id_vector[i].address) - break; - } - for(; i < m_moveable_objects.end; ++i){ - const aobject & ao = object_id_vector[i]; - if(ao.loaded_as_pointer) - continue; - void const * const this_address = ao.address; - // calculate displacement from this level - // warning - pointer arithmetic on void * is in herently non-portable - // but expected to work on all platforms in current usage - if(this_address > old_address){ - std::size_t member_displacement - = reinterpret_cast(this_address) - - reinterpret_cast(old_address); - object_id_vector[i].address = reinterpret_cast( - reinterpret_cast(new_address) + member_displacement - ); - } - else{ - std::size_t member_displacement - = reinterpret_cast(old_address) - - reinterpret_cast(this_address); - object_id_vector[i].address = reinterpret_cast( - reinterpret_cast(new_address) - member_displacement - ); - } - } -} - -inline void -basic_iarchive_impl::delete_created_pointers() -{ - object_id_vector_type::iterator i; - for( - i = object_id_vector.begin(); - i != object_id_vector.end(); - ++i - ){ - if(i->loaded_as_pointer){ - // borland complains without this minor hack - const int j = i->class_id; - const cobject_id & co = cobject_id_vector[j]; - //const cobject_id & co = cobject_id_vector[i->class_id]; - // with the appropriate input serializer, - // delete the indicated object - co.bis_ptr->destroy(i->address); - } - } -} - -inline class_id_type -basic_iarchive_impl::register_type( - const basic_iserializer & bis -){ - class_id_type cid(cobject_info_set.size()); - cobject_type co(cid, bis); - std::pair - result = cobject_info_set.insert(co); - - if(result.second){ - cobject_id_vector.push_back(cobject_id(bis)); - BOOST_ASSERT(cobject_info_set.size() == cobject_id_vector.size()); - } - cid = result.first->m_class_id; - // borland complains without this minor hack - const int tid = cid; - cobject_id & coid = cobject_id_vector[tid]; - coid.bpis_ptr = bis.get_bpis_ptr(); - return cid; -} - -void -basic_iarchive_impl::load_preamble( - basic_iarchive & ar, - cobject_id & co -){ - if(! co.initialized){ - if(co.bis_ptr->class_info()){ - class_id_optional_type cid(class_id_type(0)); - load(ar, cid); // to be thrown away - load(ar, co.tracking_level); - load(ar, co.file_version); - } - else{ - // override tracking with indicator from class information - co.tracking_level = co.bis_ptr->tracking(m_flags); - co.file_version = version_type( - co.bis_ptr->version() - ); - } - co.initialized = true; - } -} - -bool -basic_iarchive_impl::track( - basic_iarchive & ar, - void * & t -){ - object_id_type oid; - load(ar, oid); - - // if its a reference to a old object - if(object_id_type(object_id_vector.size()) > oid){ - // we're done - t = object_id_vector[oid].address; - return false; - } - return true; -} - -inline void -basic_iarchive_impl::load_object( - basic_iarchive & ar, - void * t, - const basic_iserializer & bis -){ - m_moveable_objects.is_pointer = false; - serialization::state_saver ss_is_pointer(m_moveable_objects.is_pointer); - // if its been serialized through a pointer and the preamble's been done - if(t == m_pending.object && & bis == m_pending.bis){ - // read data - (bis.load_object_data)(ar, t, m_pending.version); - return; - } - - const class_id_type cid = register_type(bis); - const int i = cid; - cobject_id & co = cobject_id_vector[i]; - - load_preamble(ar, co); - - // save the current move stack position in case we want to truncate it - boost::serialization::state_saver ss_start(m_moveable_objects.start); - - // note: extra line used to evade borland issue - const bool tracking = co.tracking_level; - - object_id_type this_id; - m_moveable_objects.start = - this_id = object_id_type(object_id_vector.size()); - - // if we tracked this object when the archive was saved - if(tracking){ - // if it was already read - if(!track(ar, t)) - // we're done - return; - // add a new enty into the tracking list - object_id_vector.push_back(aobject(t, cid)); - // and add an entry for this object - m_moveable_objects.end = object_id_type(object_id_vector.size()); - } - // read data - (bis.load_object_data)(ar, t, co.file_version); - m_moveable_objects.recent = this_id; -} - -inline const basic_pointer_iserializer * -basic_iarchive_impl::load_pointer( - basic_iarchive &ar, - void * & t, - const basic_pointer_iserializer * bpis_ptr, - const basic_pointer_iserializer * (*finder)( - const boost::serialization::extended_type_info & type_ - ) -){ - m_moveable_objects.is_pointer = true; - serialization::state_saver w(m_moveable_objects.is_pointer); - - class_id_type cid; - load(ar, cid); - - if(NULL_POINTER_TAG == cid){ - t = NULL; - return bpis_ptr; - } - - // if its a new class type - i.e. never been registered - if(class_id_type(cobject_info_set.size()) <= cid){ - // if its either abstract - if(NULL == bpis_ptr - // or polymorphic - || bpis_ptr->get_basic_serializer().is_polymorphic()){ - // is must have been exported - char key[BOOST_SERIALIZATION_MAX_KEY_SIZE]; - class_name_type class_name(key); - load(ar, class_name); - // if it has a class name - const serialization::extended_type_info *eti = NULL; - if(0 != key[0]) - eti = serialization::extended_type_info::find(key); - if(NULL == eti) - boost::serialization::throw_exception( - archive_exception(archive_exception::unregistered_class) - ); - bpis_ptr = (*finder)(*eti); - } - BOOST_ASSERT(NULL != bpis_ptr); - // class_id_type new_cid = register_type(bpis_ptr->get_basic_serializer()); - BOOST_VERIFY(register_type(bpis_ptr->get_basic_serializer()) == cid); - int i = cid; - cobject_id_vector[i].bpis_ptr = bpis_ptr; - } - int i = cid; - cobject_id & co = cobject_id_vector[i]; - bpis_ptr = co.bpis_ptr; - - if (bpis_ptr == NULL) { - boost::serialization::throw_exception( - archive_exception(archive_exception::unregistered_class) - ); - } - - load_preamble(ar, co); - - // extra line to evade borland issue - const bool tracking = co.tracking_level; - // if we're tracking and the pointer has already been read - if(tracking && ! track(ar, t)) - // we're done - return bpis_ptr; - - // save state - serialization::state_saver w_start(m_moveable_objects.start); - - // allocate space on the heap for the object - to be constructed later - t = bpis_ptr->heap_allocation(); - BOOST_ASSERT(NULL != t); - - if(! tracking){ - bpis_ptr->load_object_ptr(ar, t, co.file_version); - } - else{ - serialization::state_saver x(m_pending.object); - serialization::state_saver y(m_pending.bis); - serialization::state_saver z(m_pending.version); - - m_pending.bis = & bpis_ptr->get_basic_serializer(); - m_pending.version = co.file_version; - - // predict next object id to be created - const size_t ui = object_id_vector.size(); - - serialization::state_saver w_end(m_moveable_objects.end); - - // add to list of serialized objects so that we can properly handle - // cyclic strucures - object_id_vector.push_back(aobject(t, cid)); - - // remember that that the address of these elements could change - // when we make another call so don't use the address - bpis_ptr->load_object_ptr( - ar, - t, - m_pending.version - ); - object_id_vector[ui].loaded_as_pointer = true; - } - - return bpis_ptr; -} - -} // namespace detail -} // namespace archive -} // namespace boost - -////////////////////////////////////////////////////////////////////// -// implementation of basic_iarchive functions -namespace boost { -namespace archive { -namespace detail { - -BOOST_ARCHIVE_DECL void -basic_iarchive::next_object_pointer(void *t){ - pimpl->next_object_pointer(t); -} - -BOOST_ARCHIVE_DECL -basic_iarchive::basic_iarchive(unsigned int flags) : - pimpl(new basic_iarchive_impl(flags)) -{} - -BOOST_ARCHIVE_DECL -basic_iarchive::~basic_iarchive() -{} - -BOOST_ARCHIVE_DECL void -basic_iarchive::set_library_version(library_version_type archive_library_version){ - pimpl->set_library_version(archive_library_version); -} - -BOOST_ARCHIVE_DECL void -basic_iarchive::reset_object_address( - const void * new_address, - const void * old_address -){ - pimpl->reset_object_address(new_address, old_address); -} - -BOOST_ARCHIVE_DECL void -basic_iarchive::load_object( - void *t, - const basic_iserializer & bis -){ - pimpl->load_object(*this, t, bis); -} - -// load a pointer object -BOOST_ARCHIVE_DECL const basic_pointer_iserializer * -basic_iarchive::load_pointer( - void * &t, - const basic_pointer_iserializer * bpis_ptr, - const basic_pointer_iserializer * (*finder)( - const boost::serialization::extended_type_info & type_ - ) - -){ - return pimpl->load_pointer(*this, t, bpis_ptr, finder); -} - -BOOST_ARCHIVE_DECL void -basic_iarchive::register_basic_serializer(const basic_iserializer & bis){ - pimpl->register_type(bis); -} - -BOOST_ARCHIVE_DECL void -basic_iarchive::delete_created_pointers() -{ - pimpl->delete_created_pointers(); -} - -BOOST_ARCHIVE_DECL boost::archive::library_version_type -basic_iarchive::get_library_version() const{ - return pimpl->m_archive_library_version; -} - -BOOST_ARCHIVE_DECL unsigned int -basic_iarchive::get_flags() const{ - return pimpl->m_flags; -} - -} // namespace detail -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_iserializer.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_iserializer.cpp deleted file mode 100644 index 3898a6a723..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_iserializer.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_iserializer.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL - -#define BOOST_ARCHIVE_SOURCE -#include -#include - -namespace boost { -namespace archive { -namespace detail { - -BOOST_ARCHIVE_DECL -basic_iserializer::basic_iserializer( - const boost::serialization::extended_type_info & eti -) : - basic_serializer(eti), - m_bpis(NULL) -{} - -BOOST_ARCHIVE_DECL -basic_iserializer::~basic_iserializer(){} - -} // namespace detail -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_oarchive.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_oarchive.cpp deleted file mode 100644 index 4df648dc48..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_oarchive.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_oarchive.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // msvc 6.0 needs this for warning suppression - -#include -#include -#include // NULL - -#include - -// including this here to work around an ICC in intel 7.0 -// normally this would be part of basic_oarchive.hpp below. -#define BOOST_ARCHIVE_SOURCE -// include this to prevent linker errors when the -// same modules are marked export and import. -#define BOOST_SERIALIZATION_SOURCE -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275) -#endif - -using namespace boost::serialization; - -namespace boost { -namespace archive { -namespace detail { - -class basic_oarchive_impl { - friend class basic_oarchive; - unsigned int m_flags; - - ////////////////////////////////////////////////////////////////////// - // information about each serialized object saved - // keyed on address, class_id - struct aobject - { - const void * address; - class_id_type class_id; - object_id_type object_id; - - bool operator<(const aobject &rhs) const - { - BOOST_ASSERT(NULL != address); - BOOST_ASSERT(NULL != rhs.address); - if( address < rhs.address ) - return true; - if( address > rhs.address ) - return false; - return class_id < rhs.class_id; - } - aobject & operator=(const aobject & rhs) - { - address = rhs.address; - class_id = rhs.class_id; - object_id = rhs.object_id; - return *this; - } - aobject( - const void *a, - class_id_type class_id_, - object_id_type object_id_ - ) : - address(a), - class_id(class_id_), - object_id(object_id_) - {} - aobject() : address(NULL){} - }; - // keyed on class_id, address - typedef std::set object_set_type; - object_set_type object_set; - - ////////////////////////////////////////////////////////////////////// - // information about each serialized class saved - // keyed on type_info - struct cobject_type - { - const basic_oserializer * m_bos_ptr; - const class_id_type m_class_id; - bool m_initialized; - cobject_type( - std::size_t class_id, - const basic_oserializer & bos - ) : - m_bos_ptr(& bos), - m_class_id(class_id), - m_initialized(false) - {} - cobject_type(const basic_oserializer & bos) : - m_bos_ptr(& bos), - m_initialized(false) - {} - cobject_type( - const cobject_type & rhs - ) : - m_bos_ptr(rhs.m_bos_ptr), - m_class_id(rhs.m_class_id), - m_initialized(rhs.m_initialized) - {} - // the following cannot be defined because of the const - // member. This will generate a link error if an attempt - // is made to assign. This should never be necessary - // use this only for lookup argument - cobject_type & operator=(const cobject_type &rhs); - bool operator<(const cobject_type &rhs) const { - return *m_bos_ptr < *(rhs.m_bos_ptr); - } - }; - // keyed on type_info - typedef std::set cobject_info_set_type; - cobject_info_set_type cobject_info_set; - - // list of objects initially stored as pointers - used to detect errors - // keyed on object id - std::set stored_pointers; - - // address of the most recent object serialized as a poiner - // whose data itself is now pending serialization - const void * pending_object; - const basic_oserializer * pending_bos; - - basic_oarchive_impl(unsigned int flags) : - m_flags(flags), - pending_object(NULL), - pending_bos(NULL) - {} - - const cobject_type & - find(const basic_oserializer & bos); - const basic_oserializer * - find(const serialization::extended_type_info &ti) const; - -//public: - const cobject_type & - register_type(const basic_oserializer & bos); - void save_object( - basic_oarchive & ar, - const void *t, - const basic_oserializer & bos - ); - void save_pointer( - basic_oarchive & ar, - const void * t, - const basic_pointer_oserializer * bpos - ); -}; - -////////////////////////////////////////////////////////////////////// -// basic_oarchive implementation functions - -// given a type_info - find its bos -// return NULL if not found -inline const basic_oserializer * -basic_oarchive_impl::find(const serialization::extended_type_info & ti) const { - #ifdef BOOST_MSVC - # pragma warning(push) - # pragma warning(disable : 4511 4512) - #endif - class bosarg : - public basic_oserializer - { - bool class_info() const { - BOOST_ASSERT(false); - return false; - } - // returns true if objects should be tracked - bool tracking(const unsigned int) const { - BOOST_ASSERT(false); - return false; - } - // returns class version - version_type version() const { - BOOST_ASSERT(false); - return version_type(0); - } - // returns true if this class is polymorphic - bool is_polymorphic() const{ - BOOST_ASSERT(false); - return false; - } - void save_object_data( - basic_oarchive & /*ar*/, const void * /*x*/ - ) const { - BOOST_ASSERT(false); - } - public: - bosarg(const serialization::extended_type_info & eti) : - boost::archive::detail::basic_oserializer(eti) - {} - }; - #ifdef BOOST_MSVC - #pragma warning(pop) - #endif - bosarg bos(ti); - cobject_info_set_type::const_iterator cit - = cobject_info_set.find(cobject_type(bos)); - // it should already have been "registered" - see below - if(cit == cobject_info_set.end()){ - // if an entry is not found in the table it is because a pointer - // of a derived class has been serialized through its base class - // but the derived class hasn't been "registered" - return NULL; - } - // return pointer to the real class - return cit->m_bos_ptr; -} - -inline const basic_oarchive_impl::cobject_type & -basic_oarchive_impl::find(const basic_oserializer & bos) -{ - std::pair cresult = - cobject_info_set.insert(cobject_type(cobject_info_set.size(), bos)); - return *(cresult.first); -} - -inline const basic_oarchive_impl::cobject_type & -basic_oarchive_impl::register_type( - const basic_oserializer & bos -){ - cobject_type co(cobject_info_set.size(), bos); - std::pair - result = cobject_info_set.insert(co); - return *(result.first); -} - -inline void -basic_oarchive_impl::save_object( - basic_oarchive & ar, - const void *t, - const basic_oserializer & bos -){ - // if its been serialized through a pointer and the preamble's been done - if(t == pending_object && pending_bos == & bos){ - // just save the object data - ar.end_preamble(); - (bos.save_object_data)(ar, t); - return; - } - - // get class information for this object - const cobject_type & co = register_type(bos); - if(bos.class_info()){ - if( ! co.m_initialized){ - ar.vsave(class_id_optional_type(co.m_class_id)); - ar.vsave(tracking_type(bos.tracking(m_flags))); - ar.vsave(version_type(bos.version())); - (const_cast(co)).m_initialized = true; - } - } - - // we're not tracking this type of object - if(! bos.tracking(m_flags)){ - // just windup the preamble - no object id to write - ar.end_preamble(); - // and save the data - (bos.save_object_data)(ar, t); - return; - } - - // look for an existing object id - object_id_type oid(object_set.size()); - // lookup to see if this object has already been written to the archive - basic_oarchive_impl::aobject ao(t, co.m_class_id, oid); - std::pair - aresult = object_set.insert(ao); - oid = aresult.first->object_id; - - // if its a new object - if(aresult.second){ - // write out the object id - ar.vsave(oid); - ar.end_preamble(); - // and data - (bos.save_object_data)(ar, t); - return; - } - - // check that it wasn't originally stored through a pointer - if(stored_pointers.end() != stored_pointers.find(oid)){ - // this has to be a user error. loading such an archive - // would create duplicate objects - boost::serialization::throw_exception( - archive_exception(archive_exception::pointer_conflict) - ); - } - // just save the object id - ar.vsave(object_reference_type(oid)); - ar.end_preamble(); - return; -} - -// colle -inline void -basic_oarchive_impl::save_pointer( - basic_oarchive & ar, - const void * t, - const basic_pointer_oserializer * bpos_ptr -){ - const basic_oserializer & bos = bpos_ptr->get_basic_serializer(); - std::size_t original_count = cobject_info_set.size(); - const cobject_type & co = register_type(bos); - if(! co.m_initialized){ - ar.vsave(co.m_class_id); - // if its a previously unregistered class - if((cobject_info_set.size() > original_count)){ - if(bos.is_polymorphic()){ - const serialization::extended_type_info *eti = & bos.get_eti(); - const char * key = NULL; - if(NULL != eti) - key = eti->get_key(); - if(NULL != key){ - // the following is required by IBM C++ compiler which - // makes a copy when passing a non-const to a const. This - // is permitted by the standard but rarely seen in practice - const class_name_type cn(key); - if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception:: - invalid_class_name) - ); - // write out the external class identifier - ar.vsave(cn); - } - else - // without an external class name - // we won't be able to de-serialize it so bail now - boost::serialization::throw_exception( - archive_exception(archive_exception::unregistered_class) - ); - } - } - if(bos.class_info()){ - ar.vsave(tracking_type(bos.tracking(m_flags))); - ar.vsave(version_type(bos.version())); - } - (const_cast(co)).m_initialized = true; - } - else{ - ar.vsave(class_id_reference_type(co.m_class_id)); - } - - // if we're not tracking - if(! bos.tracking(m_flags)){ - // just save the data itself - ar.end_preamble(); - serialization::state_saver x(pending_object); - serialization::state_saver y(pending_bos); - pending_object = t; - pending_bos = & bpos_ptr->get_basic_serializer(); - bpos_ptr->save_object_ptr(ar, t); - return; - } - - object_id_type oid(object_set.size()); - // lookup to see if this object has already been written to the archive - basic_oarchive_impl::aobject ao(t, co.m_class_id, oid); - std::pair - aresult = object_set.insert(ao); - oid = aresult.first->object_id; - // if the saved object already exists - if(! aresult.second){ - // append the object id to he preamble - ar.vsave(object_reference_type(oid)); - // and windup. - ar.end_preamble(); - return; - } - - // append id of this object to preamble - ar.vsave(oid); - ar.end_preamble(); - - // and save the object itself - serialization::state_saver x(pending_object); - serialization::state_saver y(pending_bos); - pending_object = t; - pending_bos = & bpos_ptr->get_basic_serializer(); - bpos_ptr->save_object_ptr(ar, t); - // add to the set of object initially stored through pointers - stored_pointers.insert(oid); -} - -} // namespace detail -} // namespace archive -} // namespace boost - -////////////////////////////////////////////////////////////////////// -// implementation of basic_oarchive functions - -namespace boost { -namespace archive { -namespace detail { - -BOOST_ARCHIVE_DECL -basic_oarchive::basic_oarchive(unsigned int flags) - : pimpl(new basic_oarchive_impl(flags)) -{} - -BOOST_ARCHIVE_DECL -basic_oarchive::~basic_oarchive() -{} - -BOOST_ARCHIVE_DECL void -basic_oarchive::save_object( - const void *x, - const basic_oserializer & bos -){ - pimpl->save_object(*this, x, bos); -} - -BOOST_ARCHIVE_DECL void -basic_oarchive::save_pointer( - const void * t, - const basic_pointer_oserializer * bpos_ptr -){ - pimpl->save_pointer(*this, t, bpos_ptr); -} - -BOOST_ARCHIVE_DECL void -basic_oarchive::register_basic_serializer(const basic_oserializer & bos){ - pimpl->register_type(bos); -} - -BOOST_ARCHIVE_DECL library_version_type -basic_oarchive::get_library_version() const{ - return BOOST_ARCHIVE_VERSION(); -} - -BOOST_ARCHIVE_DECL unsigned int -basic_oarchive::get_flags() const{ - return pimpl->m_flags; -} - -BOOST_ARCHIVE_DECL void -basic_oarchive::end_preamble(){ -} - -BOOST_ARCHIVE_DECL helper_collection & -basic_oarchive::get_helper_collection(){ - return *this; -} - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_oserializer.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_oserializer.cpp deleted file mode 100644 index afe08c4bb8..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_oserializer.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_oserializer.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL - -#define BOOST_ARCHIVE_SOURCE -#include -#include - -namespace boost { -namespace archive { -namespace detail { - -BOOST_ARCHIVE_DECL -basic_oserializer::basic_oserializer( - const boost::serialization::extended_type_info & eti -) : - basic_serializer(eti), - m_bpos(NULL) -{} - -BOOST_ARCHIVE_DECL -basic_oserializer::~basic_oserializer(){} - -} // namespace detail -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_pointer_iserializer.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_pointer_iserializer.cpp deleted file mode 100644 index 7cf63f306e..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_pointer_iserializer.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_pointer_iserializer.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#define BOOST_ARCHIVE_SOURCE -#include -#include - -namespace boost { -namespace archive { -namespace detail { - -BOOST_ARCHIVE_DECL -basic_pointer_iserializer::basic_pointer_iserializer( - const boost::serialization::extended_type_info & eti -) : - basic_serializer(eti) -{} - -BOOST_ARCHIVE_DECL -basic_pointer_iserializer::~basic_pointer_iserializer() {} - -} // namespace detail -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_pointer_oserializer.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_pointer_oserializer.cpp deleted file mode 100644 index e86f7b78ed..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_pointer_oserializer.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_pointer_oserializer.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#define BOOST_ARCHIVE_SOURCE -#include -#include - -namespace boost { -namespace archive { -namespace detail { - -BOOST_ARCHIVE_DECL -basic_pointer_oserializer::basic_pointer_oserializer( - const boost::serialization::extended_type_info & eti -) : - basic_serializer(eti) -{} - -BOOST_ARCHIVE_DECL -basic_pointer_oserializer::~basic_pointer_oserializer() {} - -} // namespace detail -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_serializer_map.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_serializer_map.cpp deleted file mode 100644 index 5b79107728..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_serializer_map.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serializer_map.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#if (defined _MSC_VER) && (_MSC_VER == 1200) -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -#include -#include - -#define BOOST_ARCHIVE_SOURCE -// include this to prevent linker errors when the -// same modules are marked export and import. -#define BOOST_SERIALIZATION_SOURCE -#include -#include - -#include -#include -#include - -namespace boost { - namespace serialization { - class extended_type_info; - } -namespace archive { -namespace detail { - -bool -basic_serializer_map::type_info_pointer_compare::operator()( - const basic_serializer * lhs, const basic_serializer * rhs -) const { - return *lhs < *rhs; -} - -BOOST_ARCHIVE_DECL bool -basic_serializer_map::insert(const basic_serializer * bs){ - // attempt to insert serializer into it's map - // the following is commented out - rather than being just - // deleted as a reminder not to try this. - - // const std::pair result = - m_map.insert(bs); - - // At first it seemed like a good idea. It enforced the - // idea that a type be exported from at most one code module - // (DLL or mainline). This would enforce a "one definition rule" - // across code modules. This seems a good idea to me. - // But it seems that it's just too hard for many users to implement. - - // Ideally, I would like to make this exception a warning - - // but there isn't anyway to do that. - - // if this fails, it's because it's been instantiated - // in multiple modules - DLLS - a recipe for problems. - // So trap this here - // if(!result.second){ - // boost::serialization::throw_exception( - // archive_exception( - // archive_exception::multiple_code_instantiation, - // bs->get_debug_info() - // ) - // ); - // } - return true; -} - -BOOST_ARCHIVE_DECL void -basic_serializer_map::erase(const basic_serializer * bs){ - map_type::iterator it = m_map.begin(); - map_type::iterator it_end = m_map.end(); - - while(it != it_end){ - // note item 9 from Effective STL !!! it++ - if(*it == bs) - m_map.erase(it++); - else - it++; - } - // note: we can't do this since some of the eti records - // we're pointing to might be expired and the comparison - // won't work. Leave this as a reminder not to "optimize" this. - //it = m_map.find(bs); - //assert(it != m_map.end()); - //if(*it == bs) - // m_map.erase(it); -} -BOOST_ARCHIVE_DECL const basic_serializer * -basic_serializer_map::find( - const boost::serialization::extended_type_info & eti -) const { - const basic_serializer_arg bs(eti); - map_type::const_iterator it; - it = m_map.find(& bs); - if(it == m_map.end()){ - BOOST_ASSERT(false); - return 0; - } - return *it; -} - -} // namespace detail -} // namespace archive -} // namespace boost - diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_text_oprimitive.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_text_oprimitive.cpp deleted file mode 100644 index 601662294e..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/basic_text_oprimitive.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_oprimitive.cpp: - -// (C) Copyright 2004 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#if (defined _MSC_VER) && (_MSC_VER == 1200) -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -#include - -#define BOOST_ARCHIVE_SOURCE -#include -#include -#include - -namespace boost { -namespace archive { - -// explicitly instantiate for this type of text stream -template class basic_text_oprimitive ; - -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/binary_iarchive.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/binary_iarchive.cpp deleted file mode 100644 index 95f026dc16..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/binary_iarchive.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_iarchive.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#define BOOST_ARCHIVE_SOURCE -#include -#include -#include - -#include -#include -#include - -namespace boost { -namespace archive { - -// explicitly instantiate for this type of stream -template class detail::archive_serializer_map; -template class basic_binary_iprimitive< - binary_iarchive, - std::istream::char_type, - std::istream::traits_type ->; -template class basic_binary_iarchive ; -template class binary_iarchive_impl< - binary_iarchive, - std::istream::char_type, - std::istream::traits_type ->; - -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/binary_oarchive.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/binary_oarchive.cpp deleted file mode 100644 index c5220cad47..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/binary_oarchive.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_oarchive.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#define BOOST_ARCHIVE_SOURCE -#include -#include -#include - -#include -#include - -namespace boost { -namespace archive { - -template class detail::archive_serializer_map; -template class basic_binary_oprimitive< - binary_oarchive, - std::ostream::char_type, - std::ostream::traits_type ->; -template class basic_binary_oarchive ; -template class binary_oarchive_impl< - binary_oarchive, - std::ostream::char_type, - std::ostream::traits_type ->; - -} // namespace archive -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/extended_type_info.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/extended_type_info.cpp deleted file mode 100644 index 573336c864..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/extended_type_info.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// extended_type_info.cpp: implementation for portable version of type_info - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#if (defined _MSC_VER) && (_MSC_VER == 1200) -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -#include -#include -#include -#include -#include // NULL - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ using ::strcmp; } -#endif - -#include // msvc needs this to suppress warning - -#include - -// it marks our code with proper attributes as being exported when -// we're compiling it while marking it import when just the headers -// is being included. -#define BOOST_SERIALIZATION_SOURCE -#include -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace serialization { -namespace detail { - -struct key_compare -{ - bool - operator()( - const extended_type_info * lhs, - const extended_type_info * rhs - ) const { - // performance shortcut - if(lhs == rhs) - return false; - const char * l = lhs->get_key(); - BOOST_ASSERT(NULL != l); - const char * r = rhs->get_key(); - BOOST_ASSERT(NULL != r); - // performance shortcut - // shortcut to exploit string pooling - if(l == r) - return false; - // for exported types, use the string key so that - // multiple instances in different translation units - // can be matched up - return std::strcmp(l, r) < 0; - } -}; - -typedef std::multiset ktmap; - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -class extended_type_info_arg : public extended_type_info -{ - virtual bool - is_less_than(const extended_type_info & /*rhs*/) const { - BOOST_ASSERT(false); - return false; - }; - virtual bool - is_equal(const extended_type_info & /*rhs*/) const { - BOOST_ASSERT(false); - return false; - }; - virtual const char * get_debug_info() const { - return get_key(); - } - virtual void * construct(unsigned int /*count*/, ...) const{ - BOOST_ASSERT(false); - return NULL; - } - virtual void destroy(void const * const /*p*/) const { - BOOST_ASSERT(false); - } -public: - extended_type_info_arg(const char * key) : - extended_type_info(0, key) - {} - - ~extended_type_info_arg(){ - } -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -} // namespace detail - -BOOST_SERIALIZATION_DECL void -extended_type_info::key_register() const{ - if(NULL == get_key()) - return; - singleton::get_mutable_instance().insert(this); -} - -BOOST_SERIALIZATION_DECL void -extended_type_info::key_unregister() const{ - if(NULL == get_key()) - return; - // note: it's been discovered that at least one platform is not guaranteed - // to destroy singletons reverse order of construction. So we can't - // use a runtime assert here. Leave this in a reminder not to do this! - // BOOST_ASSERT(! singleton::is_destroyed()); - if(! singleton::is_destroyed()){ - detail::ktmap & x = singleton::get_mutable_instance(); - detail::ktmap::iterator start = x.lower_bound(this); - detail::ktmap::iterator end = x.upper_bound(this); - // remove entry in map which corresponds to this type - for(;start != end; ++start){ - if(this == *start){ - x.erase(start); - break; - } - } - } -} - -BOOST_SERIALIZATION_DECL const extended_type_info * -extended_type_info::find(const char *key) { - BOOST_ASSERT(NULL != key); - const detail::ktmap & k = singleton::get_const_instance(); - const detail::extended_type_info_arg eti_key(key); - const detail::ktmap::const_iterator it = k.find(& eti_key); - if(k.end() == it) - return NULL; - return *(it); -} - -BOOST_SERIALIZATION_DECL -extended_type_info::extended_type_info( - const unsigned int type_info_key, - const char * key -) : - m_type_info_key(type_info_key), - m_key(key) -{ -} - -BOOST_SERIALIZATION_DECL -extended_type_info::~extended_type_info(){ -} - -BOOST_SERIALIZATION_DECL bool -extended_type_info::operator<(const extended_type_info &rhs) const { - // short cut for a common cases - if(this == & rhs) - return false; - if(m_type_info_key == rhs.m_type_info_key){ - return is_less_than(rhs); - } - if(m_type_info_key < rhs.m_type_info_key) - return true; - return false; -} - -BOOST_SERIALIZATION_DECL bool -extended_type_info::operator==(const extended_type_info &rhs) const { - // short cut for a common cases - if(this == & rhs) - return true; - if(m_type_info_key != rhs.m_type_info_key){ - return false; - } - return is_equal(rhs); -} - -} // namespace serialization -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/extended_type_info_typeid.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/extended_type_info_typeid.cpp deleted file mode 100644 index 91ace4c36e..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/extended_type_info_typeid.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// extended_type_info_typeid.cpp: specific implementation of type info -// that is based on typeid - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include // NULL - -#include - -// it marks our code with proper attributes as being exported when -// we're compiling it while marking it import when just the headers -// is being included. -#define BOOST_SERIALIZATION_SOURCE -#include -#include -#include - -namespace boost { -namespace serialization { -namespace typeid_system { - -#define EXTENDED_TYPE_INFO_TYPE_KEY 1 - -struct type_compare -{ - bool - operator()( - const extended_type_info_typeid_0 * lhs, - const extended_type_info_typeid_0 * rhs - ) const { - return lhs->is_less_than(*rhs); - } -}; - -typedef std::multiset< - const extended_type_info_typeid_0 *, - type_compare -> tkmap; - -BOOST_SERIALIZATION_DECL bool -extended_type_info_typeid_0::is_less_than( - const boost::serialization::extended_type_info & rhs -) const { - // shortcut for common case - if(this == & rhs) - return false; - return 0 != m_ti->before( - *(static_cast(rhs).m_ti) - ); -} - -BOOST_SERIALIZATION_DECL bool -extended_type_info_typeid_0::is_equal( - const boost::serialization::extended_type_info & rhs -) const { - return - // note: std::type_info == operator returns an int !!! - // the following permits conversion to bool without a warning. - ! ( - * m_ti - != *(static_cast(rhs).m_ti) - ) - ; -} - -BOOST_SERIALIZATION_DECL -extended_type_info_typeid_0::extended_type_info_typeid_0( - const char * key -) : - extended_type_info(EXTENDED_TYPE_INFO_TYPE_KEY, key), - m_ti(NULL) -{} - -BOOST_SERIALIZATION_DECL -extended_type_info_typeid_0::~extended_type_info_typeid_0() -{} - -BOOST_SERIALIZATION_DECL void -extended_type_info_typeid_0::type_register(const std::type_info & ti){ - m_ti = & ti; - singleton::get_mutable_instance().insert(this); -} - -BOOST_SERIALIZATION_DECL void -extended_type_info_typeid_0::type_unregister() -{ - if(NULL != m_ti){ - // note: previously this conditional was a runtime assertion with - // BOOST_ASSERT. We've changed it because we've discovered that at - // least one platform is not guaranteed to destroy singletons in - // reverse order of distruction. - // BOOST_ASSERT(! singleton::is_destroyed()); - if(! singleton::is_destroyed()){ - tkmap & x = singleton::get_mutable_instance(); - - // remove all entries in map which corresponds to this type - // make sure that we don't use any invalidated iterators - for(;;){ - const tkmap::iterator & it = x.find(this); - if(it == x.end()) - break; - x.erase(it); - }; - } - } - m_ti = NULL; -} - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -// this derivation is used for creating search arguments -class extended_type_info_typeid_arg : - public extended_type_info_typeid_0 -{ - virtual void * construct(unsigned int /*count*/, ...) const{ - BOOST_ASSERT(false); - return NULL; - } - virtual void destroy(void const * const /*p*/) const { - BOOST_ASSERT(false); - } -public: - extended_type_info_typeid_arg(const std::type_info & ti) : - extended_type_info_typeid_0(NULL) - { - // note absense of self register and key as this is used only as - // search argument given a type_info reference and is not to - // be added to the map. - m_ti = & ti; - } - ~extended_type_info_typeid_arg(){ - m_ti = NULL; - } -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -BOOST_SERIALIZATION_DECL const extended_type_info * -extended_type_info_typeid_0::get_extended_type_info( - const std::type_info & ti -) const { - typeid_system::extended_type_info_typeid_arg etia(ti); - const tkmap & t = singleton::get_const_instance(); - const tkmap::const_iterator it = t.find(& etia); - if(t.end() == it) - return NULL; - return *(it); -} - -} // namespace detail -} // namespace serialization -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/utf8_codecvt_facet.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/utf8_codecvt_facet.cpp deleted file mode 100644 index f6550d07de..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/utf8_codecvt_facet.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright Vladimir Prus 2004. -// 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) - -#include - -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#endif - -// include boost implementation of utf8 codecvt facet -# define BOOST_ARCHIVE_SOURCE -#include -#define BOOST_UTF8_BEGIN_NAMESPACE \ - namespace boost { namespace archive { namespace detail { -#define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL -#define BOOST_UTF8_END_NAMESPACE }}} -#include -#undef BOOST_UTF8_END_NAMESPACE -#undef BOOST_UTF8_DECL -#undef BOOST_UTF8_BEGIN_NAMESPACE diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/variant.hpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/variant.hpp deleted file mode 100644 index f508f01c35..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/variant.hpp +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VARIANT_HPP -#define BOOST_SERIALIZATION_VARIANT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// variant.hpp - non-intrusive serialization of variant types -// -// copyright (c) 2005 -// troy d. straszheim -// http://www.resophonic.com -// -// Use, modification and distribution is subject to 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) -// -// See http://www.boost.org for updates, documentation, and revision history. -// -// thanks to Robert Ramey, Peter Dimov, and Richard Crossley. -// - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct variant_save_visitor : - boost::static_visitor<> -{ - variant_save_visitor(Archive& ar) : - m_ar(ar) - {} - template - void operator()(T const & value) const - { - m_ar << BOOST_SERIALIZATION_NVP(value); - } -private: - Archive & m_ar; -}; - -template -void save( - Archive & ar, - boost::variant const & v, - unsigned int /*version*/ -){ - int which = v.which(); - ar << BOOST_SERIALIZATION_NVP(which); - variant_save_visitor visitor(ar); - v.apply_visitor(visitor); -} - -template -struct variant_impl { - - struct load_null { - template - static void invoke( - Archive & /*ar*/, - int /*which*/, - V & /*v*/, - const unsigned int /*version*/ - ){} - }; - - struct load_impl { - template - static void invoke( - Archive & ar, - int which, - V & v, - const unsigned int version - ){ - if(which == 0){ - // note: A non-intrusive implementation (such as this one) - // necessary has to copy the value. This wouldn't be necessary - // with an implementation that de-serialized to the address of the - // aligned storage included in the variant. - typedef typename mpl::front::type head_type; - head_type value; - ar >> BOOST_SERIALIZATION_NVP(value); - v = value; - head_type * new_address = & boost::get(v); - ar.reset_object_address(new_address, & value); - return; - } - typedef typename mpl::pop_front::type type; - variant_impl::load(ar, which - 1, v, version); - } - }; - - template - static void load( - Archive & ar, - int which, - V & v, - const unsigned int version - ){ - typedef typename mpl::eval_if, - mpl::identity, - mpl::identity - >::type typex; - typex::invoke(ar, which, v, version); - } - -}; - -template -void load( - Archive & ar, - boost::variant& v, - const unsigned int version -){ - int which; - typedef typename boost::variant::types types; - ar >> BOOST_SERIALIZATION_NVP(which); - if(which >= mpl::size::value) - // this might happen if a type was removed from the list of variant types - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception::unsupported_version - ) - ); - variant_impl::load(ar, which, v, version); -} - -template -inline void serialize( - Archive & ar, - boost::variant & v, - const unsigned int file_version -){ - split_free(ar,v,file_version); -} - -} // namespace serialization -} // namespace boost - -//template - -#include - -namespace boost { - namespace serialization { - -template -struct tracking_level< - variant ->{ - typedef mpl::integral_c_tag tag; - typedef mpl::int_< ::boost::serialization::track_always> type; - BOOST_STATIC_CONSTANT(int, value = type::value); -}; - -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_VARIANT_HPP diff --git a/src/mlpack/bindings/R/mlpack/src/boost/serialization/void_cast.cpp b/src/mlpack/bindings/R/mlpack/src/boost/serialization/void_cast.cpp deleted file mode 100644 index 535988f862..0000000000 --- a/src/mlpack/bindings/R/mlpack/src/boost/serialization/void_cast.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// void_cast.cpp: implementation of run-time casting of void pointers - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to 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) -// - -// See http://www.boost.org for updates, documentation, and revision history. - -#if (defined _MSC_VER) && (_MSC_VER == 1200) -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -// STL -#include -#include -#include -#include // NULL -#ifdef BOOST_SERIALIZATION_LOG -#include -#endif - -// BOOST -#include -#include - -#define BOOST_SERIALIZATION_SOURCE -#include -// it marks our code with proper attributes as being exported when -// we're compiling it while marking it import when just the headers -// is being included. -#include -#include -#include - -namespace boost { -namespace serialization { -namespace void_cast_detail { - -// note that void_casters are keyed on value of -// member extended type info records - NOT their -// addresses. This is necessary in order for the -// void cast operations to work across dll and exe -// module boundries. -bool void_caster::operator<(const void_caster & rhs) const { - // include short cut to save time and eliminate - // problems when when base class aren't virtual - if(m_derived != rhs.m_derived){ - if(*m_derived < *rhs.m_derived) - return true; - if(*rhs.m_derived < *m_derived) - return false; - } - // m_derived == rhs.m_derived - if(m_base != rhs.m_base) - return *m_base < *rhs.m_base; - else - return false; -} - -struct void_caster_compare { - bool operator()(const void_caster * lhs, const void_caster * rhs) const { - return *lhs < *rhs; - } -}; - -typedef std::set set_type; -typedef boost::serialization::singleton void_caster_registry; - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -// implementation of shortcut void caster -class void_caster_shortcut : public void_caster -{ - bool m_includes_virtual_base; - - void const * - vbc_upcast( - void const * const t - ) const; - void const * - vbc_downcast( - void const * const t - ) const; - virtual void const * - upcast(void const * const t) const{ - if(m_includes_virtual_base) - return vbc_upcast(t); - return static_cast ( t ) - m_difference; - } - virtual void const * - downcast(void const * const t) const{ - if(m_includes_virtual_base) - return vbc_downcast(t); - return static_cast ( t ) + m_difference; - } - virtual bool is_shortcut() const { - return true; - } - virtual bool has_virtual_base() const { - return m_includes_virtual_base; - } -public: - void_caster_shortcut( - extended_type_info const * derived, - extended_type_info const * base, - std::ptrdiff_t difference, - bool includes_virtual_base, - void_caster const * const parent - ) : - void_caster(derived, base, difference, parent), - m_includes_virtual_base(includes_virtual_base) - { - recursive_register(includes_virtual_base); - } - virtual ~void_caster_shortcut(){ - recursive_unregister(); - } -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -void const * -void_caster_shortcut::vbc_downcast( - void const * const t -) const { - // try to find a chain that gives us what we want - const void_cast_detail::set_type & s - = void_cast_detail::void_caster_registry::get_const_instance(); - void_cast_detail::set_type::const_iterator it; - for(it = s.begin(); it != s.end(); ++it){ - // if the current candidate casts to the desired target type - if ((*it)->m_derived == m_derived){ - // and if it's not us - if ((*it)->m_base != m_base){ - // try to cast from the candidate base to our base - const void * t_new; - t_new = void_downcast(*(*it)->m_base, *m_base, t); - // if we were successful - if(NULL != t_new){ - // recast to our derived - const void_caster * vc = *it; - return vc->downcast(t_new); - } - } - } - } - return NULL; -} - -void const * -void_caster_shortcut::vbc_upcast( - void const * const t -) const { - // try to find a chain that gives us what we want - const void_cast_detail::set_type & s - = void_cast_detail::void_caster_registry::get_const_instance(); - void_cast_detail::set_type::const_iterator it; - for(it = s.begin(); it != s.end(); ++it){ - // if the current candidate casts from the desired base type - if((*it)->m_base == m_base){ - // and if it's not us - if ((*it)->m_derived != m_derived){ - // try to cast from the candidate derived to our our derived - const void * t_new; - t_new = void_upcast(*m_derived, *(*it)->m_derived, t); - if(NULL != t_new) - return (*it)->upcast(t_new); - } - } - } - return NULL; -} - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -// just used as a search key -class void_caster_argument : public void_caster -{ - virtual void const * - upcast(void const * const /*t*/) const { - BOOST_ASSERT(false); - return NULL; - } - virtual void const * - downcast( void const * const /*t*/) const { - BOOST_ASSERT(false); - return NULL; - } - virtual bool has_virtual_base() const { - BOOST_ASSERT(false); - return false; - } -public: - void_caster_argument( - extended_type_info const * derived, - extended_type_info const * base - ) : - void_caster(derived, base) - {} - virtual ~void_caster_argument(){}; -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -// implementation of void caster base class -BOOST_SERIALIZATION_DECL void -void_caster::recursive_register(bool includes_virtual_base) const { - void_cast_detail::set_type & s - = void_cast_detail::void_caster_registry::get_mutable_instance(); - - #ifdef BOOST_SERIALIZATION_LOG - std::clog << "recursive_register\n"; - std::clog << m_derived->get_debug_info(); - std::clog << "<-"; - std::clog << m_base->get_debug_info(); - std::clog << "\n"; - #endif - - std::pair result; - // comment this out for now. - result = s.insert(this); - //assert(result.second); - - // generate all implied void_casts. - void_cast_detail::set_type::const_iterator it; - for(it = s.begin(); it != s.end(); ++it){ - if(* m_derived == * (*it)->m_base){ - const void_caster_argument vca( - (*it)->m_derived, - m_base - ); - void_cast_detail::set_type::const_iterator i; - i = s.find(& vca); - if(i == s.end()){ - new void_caster_shortcut( - (*it)->m_derived, - m_base, - m_difference + (*it)->m_difference, - (*it)->has_virtual_base() || includes_virtual_base, - this - ); - } - } - if(* (*it)->m_derived == * m_base){ - const void_caster_argument vca( - m_derived, - (*it)->m_base - ); - void_cast_detail::set_type::const_iterator i; - i = s.find(& vca); - if(i == s.end()){ - new void_caster_shortcut( - m_derived, - (*it)->m_base, - m_difference + (*it)->m_difference, - (*it)->has_virtual_base() || includes_virtual_base, - this - ); - } - } - } -} - -BOOST_SERIALIZATION_DECL void -void_caster::recursive_unregister() const { - // note: it's been discovered that at least one platform is not guaranteed - // to destroy singletons reverse order of construction. So we can't - // use a runtime assert here. Leave this in a reminder not to do this! - // BOOST_ASSERT(! void_caster_registry::is_destroyed()); - if(void_caster_registry::is_destroyed()) - return; - - #ifdef BOOST_SERIALIZATION_LOG - std::clog << "recursive_unregister\n"; - std::clog << m_derived->get_debug_info(); - std::clog << "<-"; - std::clog << m_base->get_debug_info(); - std::clog << "\n"; - #endif - - void_cast_detail::set_type & s - = void_caster_registry::get_mutable_instance(); - - // delete all shortcuts which use this primitive - void_cast_detail::set_type::iterator it; - for(it = s.begin(); it != s.end();){ - const void_caster * vc = *it; - if(vc == this){ - s.erase(it++); - } - else - if(vc->m_parent == this){ - s.erase(it); - delete vc; - it = s.begin(); - } - else - it++; - } -} - -} // namespace void_cast_detail - -BOOST_SYMBOL_VISIBLE void const * -void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -); - -// Given a void *, assume that it really points to an instance of one type -// and alter it so that it would point to an instance of a related type. -// Return the altered pointer. If there exists no sequence of casts that -// can transform from_type to to_type, return a NULL. -BOOST_SERIALIZATION_DECL void const * -void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -){ - // same types - trivial case - if (derived == base) - return t; - - // check to see if base/derived pair is found in the registry - const void_cast_detail::set_type & s - = void_cast_detail::void_caster_registry::get_const_instance(); - const void_cast_detail::void_caster_argument ca(& derived, & base); - - void_cast_detail::set_type::const_iterator it; - it = s.find(& ca); - if (s.end() != it) - return (*it)->upcast(t); - - return NULL; -} - -BOOST_SYMBOL_VISIBLE void const * -void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -); - -BOOST_SERIALIZATION_DECL void const * -void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -){ - // same types - trivial case - if (derived == base) - return t; - - // check to see if base/derived pair is found in the registry - const void_cast_detail::set_type & s - = void_cast_detail::void_caster_registry::get_const_instance(); - const void_cast_detail::void_caster_argument ca(& derived, & base); - - void_cast_detail::set_type::const_iterator it; - it = s.find(&ca); - if (s.end() != it) - return(*it)->downcast(t); - - return NULL; -} - -} // namespace serialization -} // namespace boost diff --git a/src/mlpack/bindings/R/mlpack/src/rcpp_mlpack.h b/src/mlpack/bindings/R/mlpack/src/rcpp_mlpack.h index 14d9823ae5..8c285e2193 100644 --- a/src/mlpack/bindings/R/mlpack/src/rcpp_mlpack.h +++ b/src/mlpack/bindings/R/mlpack/src/rcpp_mlpack.h @@ -42,4 +42,8 @@ // To suppress warnings related to core/util/arma_util.hpp. #define MLPACK_CORE_UTIL_ARMA_CONFIG_HPP +// Undefine macro due to macro collision. +#undef Realloc +#undef Free + #endif diff --git a/src/mlpack/bindings/R/r_method.cpp.in b/src/mlpack/bindings/R/r_method.cpp.in index 0d14f4e724..b9612bce06 100644 --- a/src/mlpack/bindings/R/r_method.cpp.in +++ b/src/mlpack/bindings/R/r_method.cpp.in @@ -8,6 +8,9 @@ #define BINDING_TYPE BINDING_TYPE_R #include <${INCLUDE_FILE}> +#define Realloc(p,n,t) (t *) R_chk_realloc( (void *)(p), (R_SIZE_T)((n) * sizeof(t)) ) +#define Free(p) (R_chk_free( (void *)(p) ), (p) = NULL) + // [[Rcpp::export]] void ${PROGRAM_NAME}_mlpackMain() { diff --git a/src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp b/src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp index 6674a32c2e..68244d3864 100644 --- a/src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp +++ b/src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp @@ -1,11 +1,11 @@ #pragma once -// CLI11: Version 1.9.0 +// CLI11: Version 1.9.1 // Originally designed by Henry Schreiner // https://github.com/CLIUtils/CLI11 // // This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts -// from: v1.9.0-49-ga2bf5cd +// from: v1.9.1 // // From LICENSE: // @@ -67,8 +67,8 @@ #define CLI11_VERSION_MAJOR 1 #define CLI11_VERSION_MINOR 9 -#define CLI11_VERSION_PATCH 0 -#define CLI11_VERSION "1.9.0" +#define CLI11_VERSION_PATCH 1 +#define CLI11_VERSION "1.9.1" @@ -334,12 +334,6 @@ inline bool valid_name_string(const std::string &str) { return true; } -/// check if a string is a container segment separator (empty or "%%") -inline bool is_separator(const std::string &str) { - static const std::string sep("%%"); - return (str.empty() || str == sep); -} - /// Verify that str consists of letters only inline bool isalpha(const std::string &str) { return std::all_of(str.begin(), str.end(), [](char c) { return std::isalpha(c, std::locale()); }); @@ -672,26 +666,19 @@ class Success : public ParseError { }; /// -h or --help on command line -class CallForHelp : public Success { - CLI11_ERROR_DEF(Success, CallForHelp) +class CallForHelp : public ParseError { + CLI11_ERROR_DEF(ParseError, CallForHelp) CallForHelp() : CallForHelp("This should be caught in your main function, see examples", ExitCodes::Success) {} }; /// Usually something like --help-all on command line -class CallForAllHelp : public Success { - CLI11_ERROR_DEF(Success, CallForAllHelp) +class CallForAllHelp : public ParseError { + CLI11_ERROR_DEF(ParseError, CallForAllHelp) CallForAllHelp() : CallForAllHelp("This should be caught in your main function, see examples", ExitCodes::Success) {} }; -/// -v or --version on command line -class CallForVersion : public Success { - CLI11_ERROR_DEF(Success, CallForVersion) - CallForVersion() - : CallForVersion("This should be caught in your main function, see examples", ExitCodes::Success) {} -}; - -/// Does not output a diagnostic in CLI11_PARSE, but allows main() to return with a specific error code. +/// Does not output a diagnostic in CLI11_PARSE, but allows to return from main() with a specific error code. class RuntimeError : public ParseError { CLI11_ERROR_DEF(ParseError, RuntimeError) explicit RuntimeError(int exit_code = 1) : RuntimeError("Runtime error", exit_code) {} @@ -893,6 +880,15 @@ template using void_t = typename make_void::type; /// A copy of std::conditional_t from C++14 - same reasoning as enable_if_t, it does not hurt to redefine template using conditional_t = typename std::conditional::type; +/// Check to see if something is a vector (fail check by default) +template struct is_vector : std::false_type {}; + +/// Check to see if something is a vector (true if actually a vector) +template struct is_vector> : std::true_type {}; + +/// Check to see if something is a vector (true if actually a const vector) +template struct is_vector> : std::true_type {}; + /// Check to see if something is bool (fail check by default) template struct is_bool : std::false_type {}; @@ -1034,17 +1030,6 @@ template class is_istreamable { static constexpr bool value = decltype(test(0))::value; }; -/// Check for complex -template class is_complex { - template - static auto test(int) -> decltype(std::declval().real(), std::declval().imag(), std::true_type()); - - template static auto test(...) -> std::false_type; - - public: - static constexpr bool value = decltype(test(0))::value; -}; - /// Templated operation to get a value from a stream template ::value, detail::enabler> = detail::dummy> bool from_stream(const std::string &istring, T &obj) { @@ -1059,49 +1044,12 @@ bool from_stream(const std::string & /*istring*/, T & /*obj*/) { return false; } -// check to see if an object is a mutable container (fail by default) -template struct is_mutable_container : std::false_type {}; - -/// type trait to test if a type is a mutable container meaning it has a value_type, it has an iterator, a clear, and -/// end methods and an insert function. And for our purposes we exclude std::string and types that can be constructed -/// from a std::string -template -struct is_mutable_container< - T, - conditional_t().end()), - decltype(std::declval().clear()), - decltype(std::declval().insert(std::declval().end())>(), - std::declval()))>, - void>> - : public conditional_t::value, std::false_type, std::true_type> {}; - -// check to see if an object is a mutable container (fail by default) -template struct is_readable_container : std::false_type {}; - -/// type trait to test if a type is a container meaning it has a value_type, it has an iterator, a clear, and an end -/// methods and an insert function. And for our purposes we exclude std::string and types that can be constructed from -/// a std::string -template -struct is_readable_container< - T, - conditional_t().end()), decltype(std::declval().begin())>, void>> - : public std::true_type {}; - -// check to see if an object is a wrapper (fail by default) -template struct is_wrapper : std::false_type {}; - -// check if an object is a wrapper (it has a value_type defined) -template -struct is_wrapper, void>> : public std::true_type {}; - // Check for tuple like types, as in classes with a tuple_size type trait template class is_tuple_like { template // static auto test(int) // -> decltype(std::conditional<(std::tuple_size::value > 0), std::true_type, std::false_type>::type()); - static auto test(int) -> decltype(std::tuple_size::type>::value, std::true_type{}); + static auto test(int) -> decltype(std::tuple_size::value, std::true_type{}); template static auto test(...) -> std::false_type; public: @@ -1136,19 +1084,20 @@ std::string to_string(T &&value) { /// If conversion is not supported, return an empty string (streaming is not supported for that type) template ::value && !is_ostreamable::value && - !is_readable_container::type>::value, + !is_vector::type>::type>::value, detail::enabler> = detail::dummy> std::string to_string(T &&) { return std::string{}; } -/// convert a readable container to a string +/// convert a vector to a string template ::value && !is_ostreamable::value && - is_readable_container::value, + is_vector::type>::type>::value, detail::enabler> = detail::dummy> std::string to_string(T &&variable) { std::vector defaults; + defaults.reserve(variable.size()); auto cval = variable.begin(); auto end = variable.end(); while(cval != end) { @@ -1192,142 +1141,25 @@ auto value_string(const T &value) -> decltype(to_string(value)) { return to_string(value); } -/// template to get the underlying value type if it exists or use a default -template struct wrapped_type { using type = def; }; - -/// Type size for regular object types that do not look like a tuple -template struct wrapped_type::value>::type> { - using type = typename T::value_type; -}; - -/// This will only trigger for actual void type -template struct type_count_base { static const int value{0}; }; - -/// Type size for regular object types that do not look like a tuple -template -struct type_count_base::value && !is_mutable_container::value && - !std::is_void::value>::type> { - static constexpr int value{1}; -}; - -/// the base tuple size -template -struct type_count_base::value && !is_mutable_container::value>::type> { - static constexpr int value{std::tuple_size::value}; -}; - -/// Type count base for containers is the type_count_base of the individual element -template struct type_count_base::value>::type> { - static constexpr int value{type_count_base::value}; -}; - -/// Set of overloads to get the type size of an object - -/// forward declare the subtype_count structure -template struct subtype_count; - -/// forward declare the subtype_count_min structure -template struct subtype_count_min; - /// This will only trigger for actual void type template struct type_count { static const int value{0}; }; -/// Type size for regular object types that do not look like a tuple -template -struct type_count::value && !is_tuple_like::value && !is_complex::value && - !std::is_void::value>::type> { - static constexpr int value{1}; -}; - -/// Type size for complex since it sometimes looks like a wrapper -template struct type_count::value>::type> { - static constexpr int value{2}; -}; - -/// Type size of types that are wrappers,except complex and tuples(which can also be wrappers sometimes) -template struct type_count::value>::type> { - static constexpr int value{subtype_count::value}; -}; - -/// Type size of types that are wrappers,except containers complex and tuples(which can also be wrappers sometimes) -template -struct type_count::value && !is_complex::value && !is_tuple_like::value && - !is_mutable_container::value>::type> { - static constexpr int value{type_count::value}; -}; - -/// 0 if the index > tuple size -template -constexpr typename std::enable_if::value, int>::type tuple_type_size() { - return 0; -} - -/// Recursively generate the tuple type name -template - constexpr typename std::enable_if < I::value, int>::type tuple_type_size() { - return subtype_count::type>::value + tuple_type_size(); -} - -/// Get the type size of the sum of type sizes for all the individual tuple types +/// Set of overloads to get the type size of an object template struct type_count::value>::type> { - static constexpr int value{tuple_type_size()}; + static constexpr int value{std::tuple_size::value}; }; - -/// definition of subtype count -template struct subtype_count { - static constexpr int value{is_mutable_container::value ? expected_max_vector_size : type_count::value}; -}; - -/// This will only trigger for actual void type -template struct type_count_min { static const int value{0}; }; - /// Type size for regular object types that do not look like a tuple template -struct type_count_min< +struct type_count< T, - typename std::enable_if::value && !is_tuple_like::value && !is_wrapper::value && - !is_complex::value && !std::is_void::value>::type> { - static constexpr int value{type_count::value}; -}; - -/// Type size for complex since it sometimes looks like a wrapper -template struct type_count_min::value>::type> { + typename std::enable_if::value && !is_tuple_like::value && !std::is_void::value>::type> { static constexpr int value{1}; }; -/// Type size min of types that are wrappers,except complex and tuples(which can also be wrappers sometimes) -template -struct type_count_min< - T, - typename std::enable_if::value && !is_complex::value && !is_tuple_like::value>::type> { - static constexpr int value{subtype_count_min::value}; -}; - -/// 0 if the index > tuple size -template -constexpr typename std::enable_if::value, int>::type tuple_type_size_min() { - return 0; -} - -/// Recursively generate the tuple type name -template - constexpr typename std::enable_if < I::value, int>::type tuple_type_size_min() { - return subtype_count_min::type>::value + tuple_type_size_min(); -} - -/// Get the type size of the sum of type sizes for all the individual tuple types -template struct type_count_min::value>::type> { - static constexpr int value{tuple_type_size_min()}; -}; - -/// definition of subtype count -template struct subtype_count_min { - static constexpr int value{is_mutable_container::value - ? ((type_count::value < expected_max_vector_size) ? type_count::value : 0) - : type_count_min::value}; +/// Type size of types that look like a vector +template struct type_count::value>::type> { + static constexpr int value{is_vector::value ? expected_max_vector_size + : type_count::value}; }; /// This will only trigger for actual void type @@ -1335,22 +1167,14 @@ template struct expected_count { static con /// For most types the number of expected items is 1 template -struct expected_count::value && !is_wrapper::value && - !std::is_void::value>::type> { +struct expected_count::value && !std::is_void::value>::type> { static constexpr int value{1}; }; /// number of expected items in a vector -template struct expected_count::value>::type> { +template struct expected_count::value>::type> { static constexpr int value{expected_max_vector_size}; }; -/// number of expected items in a vector -template -struct expected_count::value && is_wrapper::value>::type> { - static constexpr int value{expected_count::value}; -}; - // Enumeration of the different supported categorizations of objects enum class object_category : int { integral_value = 2, @@ -1361,15 +1185,12 @@ enum class object_category : int { number_constructible = 12, double_constructible = 14, integer_constructible = 16, - // string like types - string_assignable = 23, - string_constructible = 24, - other = 45, - // special wrapper or container types - wrapper_value = 50, - complex_number = 60, - tuple_value = 70, - container_value = 80, + vector_value = 30, + tuple_value = 35, + // string assignable or greater used in a condition so anything string like must come last + string_assignable = 50, + string_constructible = 60, + other = 200, }; @@ -1406,9 +1227,10 @@ template struct classify_object -struct classify_object::value && !std::is_integral::value && - std::is_assignable::value>::type> { +struct classify_object< + T, + typename std::enable_if::value && !std::is_integral::value && + std::is_assignable::value && !is_vector::value>::type> { static constexpr object_category value{object_category::string_assignable}; }; @@ -1417,8 +1239,8 @@ template struct classify_object< T, typename std::enable_if::value && !std::is_integral::value && - !std::is_assignable::value && (type_count::value == 1) && - std::is_constructible::value>::type> { + !std::is_assignable::value && + std::is_constructible::value && !is_vector::value>::type> { static constexpr object_category value{object_category::string_constructible}; }; @@ -1427,35 +1249,23 @@ template struct classify_object struct classify_object::value>::type> { - static constexpr object_category value{object_category::complex_number}; -}; - /// Handy helper to contain a bunch of checks that rule out many common types (integers, string like, floating point, /// vectors, and enumerations template struct uncommon_type { using type = typename std::conditional::value && !std::is_integral::value && !std::is_assignable::value && - !std::is_constructible::value && !is_complex::value && - !is_mutable_container::value && !std::is_enum::value, + !std::is_constructible::value && !is_vector::value && + !std::is_enum::value, std::true_type, std::false_type>::type; static constexpr bool value = type::value; }; -/// wrapper type -template -struct classify_object::value && is_wrapper::value && - !is_tuple_like::value && uncommon_type::value)>::type> { - static constexpr object_category value{object_category::wrapper_value}; -}; - /// Assignable from double or int template struct classify_object::value && type_count::value == 1 && - !is_wrapper::value && is_direct_constructible::value && + is_direct_constructible::value && is_direct_constructible::value>::type> { static constexpr object_category value{object_category::number_constructible}; }; @@ -1464,7 +1274,7 @@ struct classify_object struct classify_object::value && type_count::value == 1 && - !is_wrapper::value && !is_direct_constructible::value && + !is_direct_constructible::value && is_direct_constructible::value>::type> { static constexpr object_category value{object_category::integer_constructible}; }; @@ -1473,30 +1283,24 @@ struct classify_object struct classify_object::value && type_count::value == 1 && - !is_wrapper::value && is_direct_constructible::value && + is_direct_constructible::value && !is_direct_constructible::value>::type> { static constexpr object_category value{object_category::double_constructible}; }; /// Tuple type template -struct classify_object< - T, - typename std::enable_if::value && - ((type_count::value >= 2 && !is_wrapper::value) || - (uncommon_type::value && !is_direct_constructible::value && - !is_direct_constructible::value))>::type> { +struct classify_object::value >= 2 && !is_vector::value) || + (is_tuple_like::value && uncommon_type::value && + !is_direct_constructible::value && + !is_direct_constructible::value)>::type> { static constexpr object_category value{object_category::tuple_value}; - // the condition on this class requires it be like a tuple, but on some compilers (like Xcode) tuples can be - // constructed from just the first element so tuples of can be constructed from a string, which - // could lead to issues so there are two variants of the condition, the first isolates things with a type size >=2 - // mainly to get tuples on Xcode with the exception of wrappers, the second is the main one and just separating out - // those cases that are caught by other object classifications }; -/// container type -template struct classify_object::value>::type> { - static constexpr object_category value{object_category::container_value}; +/// Vector type +template struct classify_object::value>::type> { + static constexpr object_category value{object_category::vector_value}; }; // Type name print @@ -1542,53 +1346,31 @@ constexpr const char *type_name() { return "BOOLEAN"; } -/// Print name for enumeration types -template ::value == object_category::complex_number, detail::enabler> = detail::dummy> -constexpr const char *type_name() { - return "COMPLEX"; -} - /// Print for all other types template ::value >= object_category::string_assignable && - classify_object::value <= object_category::other, - detail::enabler> = detail::dummy> + enable_if_t::value >= object_category::string_assignable, detail::enabler> = detail::dummy> constexpr const char *type_name() { return "TEXT"; } -/// typename for tuple value -template ::value == object_category::tuple_value && type_count_base::value >= 2, - detail::enabler> = detail::dummy> -std::string type_name(); // forward declaration - -/// Generate type name for a wrapper or container value -template ::value == object_category::container_value || - classify_object::value == object_category::wrapper_value, - detail::enabler> = detail::dummy> -std::string type_name(); // forward declaration /// Print name for single element tuple types template ::value == object_category::tuple_value && type_count_base::value == 1, + enable_if_t::value == object_category::tuple_value && type_count::value == 1, detail::enabler> = detail::dummy> inline std::string type_name() { - return type_name::type>::type>(); + return type_name::type>(); } /// Empty string if the index > tuple size template -inline typename std::enable_if::value, std::string>::type tuple_name() { +inline typename std::enable_if::value, std::string>::type tuple_name() { return std::string{}; } /// Recursively generate the tuple type name template -inline typename std::enable_if<(I < type_count_base::value), std::string>::type tuple_name() { - std::string str = std::string(type_name::type>::type>()) + - ',' + tuple_name(); + inline typename std::enable_if < I::value, std::string>::type tuple_name() { + std::string str = std::string(type_name::type>()) + ',' + tuple_name(); if(str.back() == ',') str.pop_back(); return str; @@ -1596,19 +1378,17 @@ inline typename std::enable_if<(I < type_count_base::value), std::string>::ty /// Print type name for tuples with 2 or more elements template ::value == object_category::tuple_value && type_count_base::value >= 2, - detail::enabler>> -inline std::string type_name() { + enable_if_t::value == object_category::tuple_value && type_count::value >= 2, + detail::enabler> = detail::dummy> +std::string type_name() { auto tname = std::string(1, '[') + tuple_name(); tname.push_back(']'); return tname; } -/// get the type name for a type that has a value_type member +/// This one should not be used normally, since vector types print the internal type template ::value == object_category::container_value || - classify_object::value == object_category::wrapper_value, - detail::enabler>> + enable_if_t::value == object_category::vector_value, detail::enabler> = detail::dummy> inline std::string type_name() { return type_name(); } @@ -1726,38 +1506,6 @@ bool lexical_cast(const std::string &input, T &output) { } } -/// complex -template ::value == object_category::complex_number, detail::enabler> = detail::dummy> -bool lexical_cast(const std::string &input, T &output) { - using XC = typename wrapped_type::type; - XC x{0.0}, y{0.0}; - auto str1 = input; - bool worked = false; - auto nloc = str1.find_last_of("+-"); - if(nloc != std::string::npos && nloc > 0) { - worked = detail::lexical_cast(str1.substr(0, nloc), x); - str1 = str1.substr(nloc); - if(str1.back() == 'i' || str1.back() == 'j') - str1.pop_back(); - worked = worked && detail::lexical_cast(str1, y); - } else { - if(str1.back() == 'i' || str1.back() == 'j') { - str1.pop_back(); - worked = detail::lexical_cast(str1, y); - x = XC{0}; - } else { - worked = detail::lexical_cast(str1, x); - y = XC{0}; - } - } - if(worked) { - output = T{x, y}; - return worked; - } - return from_stream(input, output); -} - /// String and similar direct assignment template ::value == object_category::string_assignable, detail::enabler> = detail::dummy> @@ -1788,18 +1536,6 @@ bool lexical_cast(const std::string &input, T &output) { return true; } -/// wrapper types -template ::value == object_category::wrapper_value, detail::enabler> = detail::dummy> -bool lexical_cast(const std::string &input, T &output) { - typename T::value_type val; - if(lexical_cast(input, val)) { - output = T{val}; - return true; - } - return from_stream(input, output); -} - /// Assignable from double or int template < typename T, @@ -1855,40 +1591,38 @@ bool lexical_cast(const std::string &input, T &output) { } /// Assign a value through lexical cast operations -/// Strings can be empty so we need to do a little different -template ::value && - (classify_object::value == object_category::string_assignable || - classify_object::value == object_category::string_constructible), - detail::enabler> = detail::dummy> -bool lexical_assign(const std::string &input, AssignTo &output) { +template < + typename T, + typename XC, + enable_if_t::value && (classify_object::value == object_category::string_assignable || + classify_object::value == object_category::string_constructible), + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, T &output) { return lexical_cast(input, output); } /// Assign a value through lexical cast operations -template ::value && - classify_object::value != object_category::string_assignable && - classify_object::value != object_category::string_constructible, +template ::value && classify_object::value != object_category::string_assignable && + classify_object::value != object_category::string_constructible, detail::enabler> = detail::dummy> -bool lexical_assign(const std::string &input, AssignTo &output) { +bool lexical_assign(const std::string &input, T &output) { if(input.empty()) { - output = AssignTo{}; + output = T{}; return true; } return lexical_cast(input, output); } /// Assign a value converted from a string in lexical cast to the output value directly -template ::value && std::is_assignable::value, - detail::enabler> = detail::dummy> -bool lexical_assign(const std::string &input, AssignTo &output) { - ConvertTo val{}; - bool parse_result = (!input.empty()) ? lexical_cast(input, val) : true; +template < + typename T, + typename XC, + enable_if_t::value && std::is_assignable::value, detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, T &output) { + XC val{}; + bool parse_result = (!input.empty()) ? lexical_cast(input, val) : true; if(parse_result) { output = val; } @@ -1896,242 +1630,84 @@ bool lexical_assign(const std::string &input, AssignTo &output) { } /// Assign a value from a lexical cast through constructing a value and move assigning it -template < - typename AssignTo, - typename ConvertTo, - enable_if_t::value && !std::is_assignable::value && - std::is_move_assignable::value, - detail::enabler> = detail::dummy> -bool lexical_assign(const std::string &input, AssignTo &output) { - ConvertTo val{}; - bool parse_result = input.empty() ? true : lexical_cast(input, val); +template ::value && !std::is_assignable::value && + std::is_move_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, T &output) { + XC val{}; + bool parse_result = input.empty() ? true : lexical_cast(input, val); if(parse_result) { - output = AssignTo(val); // use () form of constructor to allow some implicit conversions + output = T(val); // use () form of constructor to allow some implicit conversions } return parse_result; } - -/// primary lexical conversion operation, 1 string to 1 type of some kind -template ::value <= object_category::other && - classify_object::value <= object_category::wrapper_value, - detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - return lexical_assign(strings[0], output); +/// Lexical conversion if there is only one element +template < + typename T, + typename XC, + enable_if_t::value && !is_tuple_like::value && !is_vector::value && !is_vector::value, + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, T &output) { + return lexical_assign(strings[0], output); } -/// Lexical conversion if there is only one element but the conversion type is for two, then call a two element -/// constructor -template ::value <= 2) && expected_count::value == 1 && - is_tuple_like::value && type_count_base::value == 2, - detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - // the remove const is to handle pair types coming from a container - typename std::remove_const::type>::type v1; - typename std::tuple_element<1, ConvertTo>::type v2; +/// Lexical conversion if there is only one element but the conversion type is for two call a two element constructor +template ::value == 1 && type_count::value == 2, detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, T &output) { + typename std::tuple_element<0, XC>::type v1; + typename std::tuple_element<1, XC>::type v2; bool retval = lexical_assign(strings[0], v1); if(strings.size() > 1) { retval = retval && lexical_assign(strings[1], v2); } if(retval) { - output = AssignTo{v1, v2}; + output = T{v1, v2}; } return retval; } -/// Lexical conversion of a container types of single elements -template ::value && is_mutable_container::value && - type_count::value == 1, +/// Lexical conversion of a vector types +template ::value == expected_max_vector_size && + expected_count::value == expected_max_vector_size && type_count::value == 1, detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - output.erase(output.begin(), output.end()); - for(const auto &elem : strings) { - typename AssignTo::value_type out; - bool retval = lexical_assign(elem, out); - if(!retval) { - return false; - } - output.insert(output.end(), std::move(out)); - } - return (!output.empty()); -} - -/// Lexical conversion for complex types -template ::value, detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - - if(strings.size() >= 2 && !strings[1].empty()) { - using XC2 = typename wrapped_type::type; - XC2 x{0.0}, y{0.0}; - auto str1 = strings[1]; - if(str1.back() == 'i' || str1.back() == 'j') { - str1.pop_back(); - } - auto worked = detail::lexical_cast(strings[0], x) && detail::lexical_cast(str1, y); - if(worked) { - output = ConvertTo{x, y}; - } - return worked; - } else { - return lexical_assign(strings[0], output); - } -} - -/// Conversion to a vector type using a particular single type as the conversion type -template ::value && (expected_count::value == 1) && - (type_count::value == 1), - detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - bool retval = true; +bool lexical_conversion(const std::vector &strings, T &output) { output.clear(); output.reserve(strings.size()); for(const auto &elem : strings) { output.emplace_back(); - retval = retval && lexical_assign(elem, output.back()); - } - return (!output.empty()) && retval; -} - -// forward declaration - -/// Lexical conversion of a container types with conversion type of two elements -template ::value && is_mutable_container::value && - type_count_base::value == 2, - detail::enabler> = detail::dummy> -bool lexical_conversion(std::vector strings, AssignTo &output); - -/// Lexical conversion of a vector types with type_size >2 forward declaration -template ::value && is_mutable_container::value && - type_count_base::value != 2 && - ((type_count::value > 2) || - (type_count::value > type_count_base::value)), - detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output); - -/// Conversion for tuples -template ::value && is_tuple_like::value && - (type_count_base::value != type_count::value || - type_count::value > 2), - detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output); // forward declaration - -/// Conversion for operations where the assigned type is some class but the conversion is a mutable container or large -/// tuple -template ::value && !is_mutable_container::value && - classify_object::value != object_category::wrapper_value && - (is_mutable_container::value || type_count::value > 2), - detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - - if(strings.size() > 1 || (!strings.empty() && !(strings.front().empty()))) { - ConvertTo val; - auto retval = lexical_conversion(strings, val); - output = AssignTo{val}; - return retval; - } - output = AssignTo{}; - return true; -} - -/// function template for converting tuples if the static Index is greater than the tuple size -template -inline typename std::enable_if<(I >= type_count_base::value), bool>::type -tuple_conversion(const std::vector &, AssignTo &) { - return true; -} - -/// Conversion of a tuple element where the type size ==1 and not a mutable container -template -inline typename std::enable_if::value && type_count::value == 1, bool>::type -tuple_type_conversion(std::vector &strings, AssignTo &output) { - auto retval = lexical_assign(strings[0], output); - strings.erase(strings.begin()); - return retval; -} - -/// Conversion of a tuple element where the type size !=1 but the size is fixed and not a mutable container -template -inline typename std::enable_if::value && (type_count::value > 1) && - type_count::value == type_count_min::value, - bool>::type -tuple_type_conversion(std::vector &strings, AssignTo &output) { - auto retval = lexical_conversion(strings, output); - strings.erase(strings.begin(), strings.begin() + type_count::value); - return retval; -} - -/// Conversion of a tuple element where the type is a mutable container or a type with different min and max type sizes -template -inline typename std::enable_if::value || - type_count::value != type_count_min::value, - bool>::type -tuple_type_conversion(std::vector &strings, AssignTo &output) { - - std::size_t index{subtype_count_min::value}; - const std::size_t mx_count{subtype_count::value}; - const std::size_t mx{(std::max)(mx_count, strings.size())}; - - while(index < mx) { - if(is_separator(strings[index])) { - break; + bool retval = lexical_assign(elem, output.back()); + if(!retval) { + return false; } - ++index; } - bool retval = lexical_conversion( - std::vector(strings.begin(), strings.begin() + static_cast(index)), output); - strings.erase(strings.begin(), strings.begin() + static_cast(index) + 1); - return retval; + return (!output.empty()); } -/// Tuple conversion operation -template -inline typename std::enable_if<(I < type_count_base::value), bool>::type -tuple_conversion(std::vector strings, AssignTo &output) { - bool retval = true; - using ConvertToElement = typename std:: - conditional::value, typename std::tuple_element::type, ConvertTo>::type; - if(!strings.empty()) { - retval = retval && tuple_type_conversion::type, ConvertToElement>( - strings, std::get(output)); - } - retval = retval && tuple_conversion(std::move(strings), output); - return retval; -} - -/// Lexical conversion of a container types with tuple elements of size 2 -template ::value && is_mutable_container::value && - type_count_base::value == 2, - detail::enabler>> -bool lexical_conversion(std::vector strings, AssignTo &output) { +/// Lexical conversion of a vector types with type size of two +template ::value == expected_max_vector_size && + expected_count::value == expected_max_vector_size && type_count::value == 2, + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, T &output) { output.clear(); - while(!strings.empty()) { + for(std::size_t ii = 0; ii < strings.size(); ii += 2) { - typename std::remove_const::type>::type v1; - typename std::tuple_element<1, typename ConvertTo::value_type>::type v2; - bool retval = tuple_type_conversion(strings, v1); - if(!strings.empty()) { - retval = retval && tuple_type_conversion(strings, v2); + typename std::tuple_element<0, typename XC::value_type>::type v1; + typename std::tuple_element<1, typename XC::value_type>::type v2; + bool retval = lexical_assign(strings[ii], v1); + if(strings.size() > ii + 1) { + retval = retval && lexical_assign(strings[ii + 1], v2); } if(retval) { - output.insert(output.end(), typename AssignTo::value_type{v1, v2}); + output.emplace_back(v1, v2); } else { return false; } @@ -2139,82 +1715,110 @@ bool lexical_conversion(std::vector strings, AssignTo &output) { return (!output.empty()); } -/// lexical conversion of tuples with type count>2 or tuples of types of some element with a type size>=2 -template ::value && is_tuple_like::value && - (type_count_base::value != type_count::value || - type_count::value > 2), - detail::enabler>> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - static_assert( - !is_tuple_like::value || type_count_base::value == type_count_base::value, - "if the conversion type is defined as a tuple it must be the same size as the type you are converting to"); - return tuple_conversion(strings, output); +/// Conversion to a vector type using a particular single type as the conversion type +template ::value == expected_max_vector_size) && (expected_count::value == 1) && + (type_count::value == 1), + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, T &output) { + bool retval = true; + output.clear(); + output.reserve(strings.size()); + for(const auto &elem : strings) { + + output.emplace_back(); + retval = retval && lexical_assign(elem, output.back()); + } + return (!output.empty()) && retval; +} +// This one is last since it can call other lexical_conversion functions +/// Lexical conversion if there is only one element but the conversion type is a vector +template ::value && !is_vector::value && is_vector::value, detail::enabler> = + detail::dummy> +bool lexical_conversion(const std::vector &strings, T &output) { + + if(strings.size() > 1 || (!strings.empty() && !(strings.front().empty()))) { + XC val; + auto retval = lexical_conversion(strings, val); + output = T{val}; + return retval; + } + output = T{}; + return true; } -/// Lexical conversion of a vector types for everything but tuples of two elements and types of size 1 -template ::value && is_mutable_container::value && - type_count_base::value != 2 && - ((type_count::value > 2) || - (type_count::value > type_count_base::value)), - detail::enabler>> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { +/// function template for converting tuples if the static Index is greater than the tuple size +template +inline typename std::enable_if= type_count::value, bool>::type tuple_conversion(const std::vector &, + T &) { + return true; +} +/// Tuple conversion operation +template + inline typename std::enable_if < + I::value, bool>::type tuple_conversion(const std::vector &strings, T &output) { + bool retval = true; + if(strings.size() > I) { + retval = retval && lexical_assign::type, + typename std::conditional::value, + typename std::tuple_element::type, + XC>::type>(strings[I], std::get(output)); + } + retval = retval && tuple_conversion(strings, output); + return retval; +} + +/// Conversion for tuples +template ::value, detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, T &output) { + static_assert( + !is_tuple_like::value || type_count::value == type_count::value, + "if the conversion type is defined as a tuple it must be the same size as the type you are converting to"); + return tuple_conversion(strings, output); +} + +/// Lexical conversion of a vector types with type_size >2 +template ::value == expected_max_vector_size && + expected_count::value == expected_max_vector_size && (type_count::value > 2), + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, T &output) { bool retval = true; output.clear(); std::vector temp; - std::size_t ii{0}; - std::size_t icount{0}; - std::size_t xcm{type_count::value}; - auto ii_max = strings.size(); - while(ii < ii_max) { + std::size_t ii = 0; + std::size_t icount = 0; + std::size_t xcm = type_count::value; + while(ii < strings.size()) { temp.push_back(strings[ii]); ++ii; ++icount; - if(icount == xcm || is_separator(temp.back()) || ii == ii_max) { - if(static_cast(xcm) > type_count_min::value && is_separator(temp.back())) { + if(icount == xcm || temp.back().empty()) { + if(static_cast(xcm) == expected_max_vector_size) { temp.pop_back(); } - typename AssignTo::value_type temp_out; - retval = retval && - lexical_conversion(temp, temp_out); + output.emplace_back(); + retval = retval && lexical_conversion(temp, output.back()); temp.clear(); if(!retval) { return false; } - output.insert(output.end(), std::move(temp_out)); icount = 0; } } return retval; } - -/// conversion for wrapper types -template < - typename AssignTo, - class ConvertTo, - enable_if_t::value == object_category::wrapper_value, detail::enabler> = detail::dummy> -bool lexical_conversion(const std::vector &strings, AssignTo &output) { - if(strings.empty() || strings.front().empty()) { - output = ConvertTo{}; - return true; - } - typename ConvertTo::value_type val; - if(lexical_conversion(strings, val)) { - output = ConvertTo{val}; - return true; - } - return false; -} - /// Sum a vector of flag representations /// The flag vector produces a series of strings in a vector, simple true is represented by a "1", simple false is /// by /// "-1" an if numbers are passed by some fashion they are captured as well so the function just checks for the most /// common true and false strings then uses stoll to convert the rest for summing -template ::value, detail::enabler> = detail::dummy> +template ::value && std::is_unsigned::value, detail::enabler> = detail::dummy> void sum_flag_vector(const std::vector &flags, T &output) { std::int64_t count{0}; for(auto &flag : flags) { @@ -2228,7 +1832,8 @@ void sum_flag_vector(const std::vector &flags, T &output) { /// by /// "-1" an if numbers are passed by some fashion they are captured as well so the function just checks for the most /// common true and false strings then uses stoll to convert the rest for summing -template ::value, detail::enabler> = detail::dummy> +template ::value && std::is_signed::value, detail::enabler> = detail::dummy> void sum_flag_vector(const std::vector &flags, T &output) { std::int64_t count{0}; for(auto &flag : flags) { @@ -2423,17 +2028,17 @@ class Config { virtual ~Config() = default; }; -/// This converter works with INI/TOML files; to write INI files use ConfigINI +/// This converter works with INI/TOML files; to write proper TOML files use ConfigTOML class ConfigBase : public Config { protected: /// the character used for comments - char commentChar = '#'; + char commentChar = ';'; /// the character used to start an array '\0' is a default to not use - char arrayStart = '['; + char arrayStart = '\0'; /// the character used to end an array '\0' is a default to not use - char arrayEnd = ']'; + char arrayEnd = '\0'; /// the character used to separate elements in an array - char arraySeparator = ','; + char arraySeparator = ' '; /// the character used separate the name from the value char valueDelimiter = '='; @@ -2465,18 +2070,18 @@ class ConfigBase : public Config { } }; -/// the default Config is the TOML file format -using ConfigTOML = ConfigBase; +/// the default Config is the INI file format +using ConfigINI = ConfigBase; -/// ConfigINI generates a "standard" INI compliant output -class ConfigINI : public ConfigTOML { +/// ConfigTOML generates a TOML compliant output +class ConfigTOML : public ConfigINI { public: - ConfigINI() { - commentChar = ';'; - arrayStart = '\0'; - arrayEnd = '\0'; - arraySeparator = ' '; + ConfigTOML() { + commentChar = '#'; + arrayStart = '['; + arrayEnd = ']'; + arraySeparator = ','; valueDelimiter = '='; } }; @@ -4012,7 +3617,7 @@ class Option : public OptionBase