From 70d756ba21178d17355013ac12b9ae2ef0e55fdf Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Sat, 17 May 2025 23:17:51 -0500 Subject: [PATCH] Add support for FUSE passthrough --- DEPENDENCIES | 8 +- Makefile | 1 + libfuse/include/fuse.h | 50 +- libfuse/include/fuse_common.h | 7 +- libfuse/include/fuse_kernel.h | 195 +- libfuse/include/fuse_lowlevel.h | 18 +- libfuse/lib/cpu.cpp | 10 +- libfuse/lib/debug.cpp | 1 + libfuse/lib/fuse.cpp | 202 +- libfuse/lib/fuse_lowlevel.cpp | 46 +- libfuse/lib/ghc/filesystem.hpp | 6049 ---------------- libfuse/lib/node.hpp | 1 - src/boost/assert.hpp | 91 + src/boost/assert/source_location.hpp | 204 + src/boost/config.hpp | 67 + src/boost/config/abi/borland_prefix.hpp | 27 + src/boost/config/abi/borland_suffix.hpp | 12 + src/boost/config/abi/msvc_prefix.hpp | 22 + src/boost/config/abi/msvc_suffix.hpp | 8 + src/boost/config/abi_prefix.hpp | 25 + src/boost/config/abi_suffix.hpp | 25 + src/boost/config/assert_cxx03.hpp | 211 + src/boost/config/assert_cxx11.hpp | 212 + src/boost/config/assert_cxx14.hpp | 47 + src/boost/config/assert_cxx17.hpp | 65 + src/boost/config/assert_cxx20.hpp | 59 + src/boost/config/assert_cxx23.hpp | 41 + src/boost/config/assert_cxx98.hpp | 23 + src/boost/config/auto_link.hpp | 525 ++ src/boost/config/compiler/borland.hpp | 342 + src/boost/config/compiler/clang.hpp | 370 + src/boost/config/compiler/clang_version.hpp | 89 + src/boost/config/compiler/codegear.hpp | 389 ++ src/boost/config/compiler/comeau.hpp | 59 + src/boost/config/compiler/common_edg.hpp | 185 + src/boost/config/compiler/compaq_cxx.hpp | 19 + src/boost/config/compiler/cray.hpp | 446 ++ src/boost/config/compiler/diab.hpp | 26 + src/boost/config/compiler/digitalmars.hpp | 146 + src/boost/config/compiler/gcc.hpp | 386 ++ src/boost/config/compiler/gcc_xml.hpp | 115 + src/boost/config/compiler/greenhills.hpp | 28 + src/boost/config/compiler/hp_acc.hpp | 153 + src/boost/config/compiler/intel.hpp | 577 ++ src/boost/config/compiler/kai.hpp | 33 + src/boost/config/compiler/metrowerks.hpp | 201 + src/boost/config/compiler/mpw.hpp | 143 + src/boost/config/compiler/nvcc.hpp | 64 + src/boost/config/compiler/pathscale.hpp | 141 + src/boost/config/compiler/pgi.hpp | 23 + src/boost/config/compiler/sgi_mipspro.hpp | 29 + src/boost/config/compiler/sunpro_cc.hpp | 225 + src/boost/config/compiler/vacpp.hpp | 189 + src/boost/config/compiler/visualc.hpp | 398 ++ src/boost/config/compiler/xlcpp.hpp | 303 + src/boost/config/compiler/xlcpp_zos.hpp | 174 + src/boost/config/detail/cxx_composite.hpp | 218 + src/boost/config/detail/posix_features.hpp | 95 + .../config/detail/select_compiler_config.hpp | 157 + .../config/detail/select_platform_config.hpp | 147 + .../config/detail/select_stdlib_config.hpp | 121 + src/boost/config/detail/suffix.hpp | 1334 ++++ src/boost/config/header_deprecated.hpp | 26 + src/boost/config/helper_macros.hpp | 37 + src/boost/config/no_tr1/cmath.hpp | 28 + src/boost/config/no_tr1/complex.hpp | 28 + src/boost/config/no_tr1/functional.hpp | 28 + src/boost/config/no_tr1/memory.hpp | 28 + src/boost/config/no_tr1/utility.hpp | 28 + src/boost/config/platform/aix.hpp | 33 + src/boost/config/platform/amigaos.hpp | 15 + src/boost/config/platform/beos.hpp | 26 + src/boost/config/platform/bsd.hpp | 83 + src/boost/config/platform/cloudabi.hpp | 18 + src/boost/config/platform/cray.hpp | 18 + src/boost/config/platform/cygwin.hpp | 71 + src/boost/config/platform/haiku.hpp | 31 + src/boost/config/platform/hpux.hpp | 87 + src/boost/config/platform/irix.hpp | 31 + src/boost/config/platform/linux.hpp | 106 + src/boost/config/platform/macos.hpp | 87 + src/boost/config/platform/qnxnto.hpp | 31 + src/boost/config/platform/solaris.hpp | 31 + src/boost/config/platform/symbian.hpp | 97 + src/boost/config/platform/vms.hpp | 25 + src/boost/config/platform/vxworks.hpp | 422 ++ src/boost/config/platform/wasm.hpp | 23 + src/boost/config/platform/win32.hpp | 90 + src/boost/config/platform/zos.hpp | 32 + src/boost/config/pragma_message.hpp | 31 + src/boost/config/requires_threads.hpp | 92 + src/boost/config/stdlib/dinkumware.hpp | 324 + src/boost/config/stdlib/libcomo.hpp | 93 + src/boost/config/stdlib/libcpp.hpp | 180 + src/boost/config/stdlib/libstdcpp3.hpp | 482 ++ src/boost/config/stdlib/modena.hpp | 79 + src/boost/config/stdlib/msl.hpp | 98 + src/boost/config/stdlib/roguewave.hpp | 208 + src/boost/config/stdlib/sgi.hpp | 168 + src/boost/config/stdlib/stlport.hpp | 258 + src/boost/config/stdlib/vacpp.hpp | 74 + src/boost/config/stdlib/xlcpp_zos.hpp | 61 + src/boost/config/user.hpp | 133 + src/boost/config/warning_disable.hpp | 47 + src/boost/config/workaround.hpp | 305 + .../container_hash/detail/hash_integral.hpp | 146 + src/boost/container_hash/detail/hash_mix.hpp | 113 + .../container_hash/detail/hash_range.hpp | 408 ++ .../container_hash/detail/hash_tuple_like.hpp | 62 + src/boost/container_hash/detail/mulx.hpp | 79 + src/boost/container_hash/hash.hpp | 576 ++ src/boost/container_hash/hash_fwd.hpp | 37 + .../container_hash/is_contiguous_range.hpp | 98 + .../container_hash/is_described_class.hpp | 37 + src/boost/container_hash/is_range.hpp | 41 + src/boost/container_hash/is_tuple_like.hpp | 36 + .../container_hash/is_unordered_range.hpp | 38 + src/boost/core/addressof.hpp | 274 + src/boost/core/allocator_access.hpp | 834 +++ src/boost/core/allocator_traits.hpp | 112 + src/boost/core/bit.hpp | 954 +++ src/boost/core/detail/sp_thread_pause.hpp | 71 + src/boost/core/detail/sp_thread_sleep.hpp | 122 + src/boost/core/detail/sp_thread_yield.hpp | 100 + src/boost/core/detail/sp_win32_sleep.hpp | 54 + src/boost/core/empty_value.hpp | 203 + src/boost/core/ignore_unused.hpp | 100 + src/boost/core/no_exceptions_support.hpp | 56 + src/boost/core/noncopyable.hpp | 63 + src/boost/core/nvp.hpp | 57 + src/boost/core/pointer_traits.hpp | 285 + src/boost/core/serialization.hpp | 131 + src/boost/core/yield_primitives.hpp | 12 + src/boost/cstdint.hpp | 556 ++ src/boost/current_function.hpp | 75 + src/boost/describe/bases.hpp | 50 + src/boost/describe/detail/config.hpp | 40 + src/boost/describe/detail/cx_streq.hpp | 30 + src/boost/describe/detail/void_t.hpp | 32 + src/boost/describe/members.hpp | 161 + src/boost/describe/modifiers.hpp | 33 + src/boost/detail/workaround.hpp | 10 + src/boost/exception/exception.hpp | 569 ++ src/boost/limits.hpp | 146 + src/boost/mp11/algorithm.hpp | 1353 ++++ src/boost/mp11/bind.hpp | 120 + src/boost/mp11/detail/config.hpp | 149 + src/boost/mp11/detail/mp_append.hpp | 321 + src/boost/mp11/detail/mp_copy_if.hpp | 48 + src/boost/mp11/detail/mp_count.hpp | 147 + src/boost/mp11/detail/mp_defer.hpp | 119 + src/boost/mp11/detail/mp_fold.hpp | 166 + src/boost/mp11/detail/mp_front.hpp | 50 + src/boost/mp11/detail/mp_is_list.hpp | 39 + src/boost/mp11/detail/mp_is_value_list.hpp | 41 + src/boost/mp11/detail/mp_list.hpp | 24 + src/boost/mp11/detail/mp_list_v.hpp | 27 + src/boost/mp11/detail/mp_map_find.hpp | 87 + src/boost/mp11/detail/mp_min_element.hpp | 51 + src/boost/mp11/detail/mp_plus.hpp | 84 + src/boost/mp11/detail/mp_remove_if.hpp | 48 + src/boost/mp11/detail/mp_rename.hpp | 54 + src/boost/mp11/detail/mp_value.hpp | 25 + src/boost/mp11/detail/mp_void.hpp | 32 + src/boost/mp11/detail/mp_with_index.hpp | 385 ++ src/boost/mp11/function.hpp | 222 + src/boost/mp11/integer_sequence.hpp | 121 + src/boost/mp11/integral.hpp | 51 + src/boost/mp11/list.hpp | 481 ++ src/boost/mp11/set.hpp | 220 + src/boost/mp11/tuple.hpp | 183 + src/boost/mp11/utility.hpp | 169 + src/boost/mp11/version.hpp | 16 + src/boost/predef.h | 24 + src/boost/predef/architecture.h | 35 + src/boost/predef/architecture/alpha.h | 65 + src/boost/predef/architecture/arm.h | 144 + src/boost/predef/architecture/blackfin.h | 52 + src/boost/predef/architecture/convex.h | 71 + src/boost/predef/architecture/e2k.h | 54 + src/boost/predef/architecture/ia64.h | 55 + src/boost/predef/architecture/loongarch.h | 41 + src/boost/predef/architecture/m68k.h | 88 + src/boost/predef/architecture/mips.h | 84 + src/boost/predef/architecture/parisc.h | 70 + src/boost/predef/architecture/ppc.h | 124 + src/boost/predef/architecture/ptx.h | 50 + src/boost/predef/architecture/pyramid.h | 48 + src/boost/predef/architecture/riscv.h | 48 + src/boost/predef/architecture/rs6k.h | 67 + src/boost/predef/architecture/sparc.h | 67 + src/boost/predef/architecture/superh.h | 81 + src/boost/predef/architecture/sys370.h | 49 + src/boost/predef/architecture/sys390.h | 49 + src/boost/predef/architecture/x86.h | 38 + src/boost/predef/architecture/x86/32.h | 93 + src/boost/predef/architecture/x86/64.h | 56 + src/boost/predef/architecture/z.h | 48 + src/boost/predef/compiler.h | 44 + src/boost/predef/compiler/borland.h | 64 + src/boost/predef/compiler/clang.h | 57 + src/boost/predef/compiler/comeau.h | 62 + src/boost/predef/compiler/compaq.h | 67 + src/boost/predef/compiler/diab.h | 57 + src/boost/predef/compiler/digitalmars.h | 57 + src/boost/predef/compiler/dignus.h | 57 + src/boost/predef/compiler/edg.h | 57 + src/boost/predef/compiler/ekopath.h | 58 + src/boost/predef/compiler/gcc.h | 69 + src/boost/predef/compiler/gcc_xml.h | 54 + src/boost/predef/compiler/greenhills.h | 67 + src/boost/predef/compiler/hp_acc.h | 62 + src/boost/predef/compiler/iar.h | 57 + src/boost/predef/compiler/ibm.h | 73 + src/boost/predef/compiler/intel.h | 80 + src/boost/predef/compiler/kai.h | 57 + src/boost/predef/compiler/llvm.h | 58 + src/boost/predef/compiler/metaware.h | 54 + src/boost/predef/compiler/metrowerks.h | 78 + src/boost/predef/compiler/microtec.h | 54 + src/boost/predef/compiler/mpw.h | 64 + src/boost/predef/compiler/nvcc.h | 74 + src/boost/predef/compiler/palm.h | 57 + src/boost/predef/compiler/pgi.h | 61 + src/boost/predef/compiler/sgi_mipspro.h | 67 + src/boost/predef/compiler/sunpro.h | 77 + src/boost/predef/compiler/tendra.h | 54 + src/boost/predef/compiler/visualc.h | 106 + src/boost/predef/compiler/watcom.h | 57 + src/boost/predef/detail/_cassert.h | 17 + src/boost/predef/detail/_exception.h | 15 + src/boost/predef/detail/comp_detected.h | 10 + src/boost/predef/detail/os_detected.h | 10 + src/boost/predef/detail/platform_detected.h | 10 + src/boost/predef/detail/test.h | 17 + src/boost/predef/hardware.h | 16 + src/boost/predef/hardware/simd.h | 168 + src/boost/predef/hardware/simd/arm.h | 61 + src/boost/predef/hardware/simd/arm/versions.h | 38 + src/boost/predef/hardware/simd/ppc.h | 71 + src/boost/predef/hardware/simd/ppc/versions.h | 57 + src/boost/predef/hardware/simd/x86.h | 125 + src/boost/predef/hardware/simd/x86/versions.h | 135 + src/boost/predef/hardware/simd/x86_amd.h | 89 + .../predef/hardware/simd/x86_amd/versions.h | 56 + src/boost/predef/language.h | 18 + src/boost/predef/language/cuda.h | 53 + src/boost/predef/language/objc.h | 43 + src/boost/predef/language/stdc.h | 54 + src/boost/predef/language/stdcpp.h | 128 + src/boost/predef/library.h | 16 + src/boost/predef/library/c.h | 21 + src/boost/predef/library/c/_prefix.h | 13 + src/boost/predef/library/c/cloudabi.h | 54 + src/boost/predef/library/c/gnu.h | 62 + src/boost/predef/library/c/uc.h | 48 + src/boost/predef/library/c/vms.h | 48 + src/boost/predef/library/c/zos.h | 57 + src/boost/predef/library/std.h | 26 + src/boost/predef/library/std/_prefix.h | 23 + src/boost/predef/library/std/cxx.h | 47 + src/boost/predef/library/std/dinkumware.h | 53 + src/boost/predef/library/std/libcomo.h | 48 + src/boost/predef/library/std/modena.h | 46 + src/boost/predef/library/std/msl.h | 54 + src/boost/predef/library/std/msvc.h | 53 + src/boost/predef/library/std/roguewave.h | 57 + src/boost/predef/library/std/sgi.h | 52 + src/boost/predef/library/std/stdcpp3.h | 54 + src/boost/predef/library/std/stlport.h | 60 + src/boost/predef/library/std/vacpp.h | 45 + src/boost/predef/make.h | 167 + src/boost/predef/os.h | 32 + src/boost/predef/os/aix.h | 67 + src/boost/predef/os/amigaos.h | 47 + src/boost/predef/os/beos.h | 46 + src/boost/predef/os/bsd.h | 102 + src/boost/predef/os/bsd/bsdi.h | 50 + src/boost/predef/os/bsd/dragonfly.h | 52 + src/boost/predef/os/bsd/free.h | 69 + src/boost/predef/os/bsd/net.h | 86 + src/boost/predef/os/bsd/open.h | 253 + src/boost/predef/os/cygwin.h | 51 + src/boost/predef/os/haiku.h | 47 + src/boost/predef/os/hpux.h | 48 + src/boost/predef/os/ios.h | 52 + src/boost/predef/os/irix.h | 47 + src/boost/predef/os/linux.h | 50 + src/boost/predef/os/macos.h | 66 + src/boost/predef/os/os400.h | 46 + src/boost/predef/os/qnxnto.h | 60 + src/boost/predef/os/solaris.h | 47 + src/boost/predef/os/unix.h | 78 + src/boost/predef/os/vms.h | 53 + src/boost/predef/os/windows.h | 52 + src/boost/predef/other.h | 17 + src/boost/predef/other/endian.h | 202 + src/boost/predef/other/wordsize.h | 73 + src/boost/predef/other/workaround.h | 95 + src/boost/predef/platform.h | 28 + src/boost/predef/platform/android.h | 44 + src/boost/predef/platform/cloudabi.h | 44 + src/boost/predef/platform/ios.h | 63 + src/boost/predef/platform/mingw.h | 70 + src/boost/predef/platform/mingw32.h | 64 + src/boost/predef/platform/mingw64.h | 64 + src/boost/predef/platform/windows_desktop.h | 52 + src/boost/predef/platform/windows_phone.h | 49 + src/boost/predef/platform/windows_runtime.h | 54 + src/boost/predef/platform/windows_server.h | 48 + src/boost/predef/platform/windows_store.h | 51 + src/boost/predef/platform/windows_system.h | 48 + src/boost/predef/platform/windows_uwp.h | 61 + src/boost/predef/version.h | 15 + src/boost/predef/version_number.h | 74 + src/boost/static_assert.hpp | 181 + src/boost/throw_exception.hpp | 278 + src/boost/unordered/concurrent_flat_map.hpp | 1055 +++ .../unordered/concurrent_flat_map_fwd.hpp | 66 + .../detail/allocator_constructed.hpp | 59 + .../unordered/detail/archive_constructed.hpp | 71 + .../detail/bad_archive_exception.hpp | 27 + .../detail/concurrent_static_asserts.hpp | 127 + .../unordered/detail/foa/concurrent_table.hpp | 1993 ++++++ src/boost/unordered/detail/foa/core.hpp | 2404 +++++++ .../unordered/detail/foa/cumulative_stats.hpp | 177 + .../unordered/detail/foa/flat_map_types.hpp | 94 + .../unordered/detail/foa/ignore_wshadow.hpp | 35 + .../unordered/detail/foa/reentrancy_check.hpp | 138 + .../unordered/detail/foa/restore_wshadow.hpp | 11 + .../unordered/detail/foa/rw_spinlock.hpp | 179 + .../detail/foa/tuple_rotate_right.hpp | 53 + .../detail/foa/types_constructibility.hpp | 172 + src/boost/unordered/detail/mulx.hpp | 129 + src/boost/unordered/detail/narrow_cast.hpp | 44 + src/boost/unordered/detail/opt_storage.hpp | 30 + .../detail/serialization_version.hpp | 74 + src/boost/unordered/detail/static_assert.hpp | 16 + src/boost/unordered/detail/type_traits.hpp | 237 + src/boost/unordered/hash_traits.hpp | 70 + .../unordered/unordered_flat_map_fwd.hpp | 59 + src/boost/unordered/unordered_printers.hpp | 414 ++ src/boost/version.hpp | 32 + src/config.cpp | 3 + src/config.hpp | 18 +- src/fileinfo.hpp | 7 + src/fs_clonefile.cpp | 2 +- src/fs_copydata_copy_file_range.cpp | 2 +- src/fs_copydata_readwrite.cpp | 2 +- src/fs_devid.hpp | 2 +- src/fs_fchmod.hpp | 2 +- src/fs_fchown.hpp | 2 +- src/fs_file_size.cpp | 2 +- src/fs_findonfs.cpp | 2 +- src/fs_fstat.hpp | 7 +- src/fs_fstatat.hpp | 12 +- src/fs_futimens_generic.hpp | 4 +- src/fs_inode.cpp | 89 +- src/fs_inode.hpp | 26 +- src/fs_openat.hpp | 33 +- src/fs_path.hpp | 4 +- src/fs_utimensat_generic.hpp | 4 +- src/fs_wait_for_mount.cpp | 16 +- src/fs_wait_for_mount.hpp | 3 - src/fuse_chmod.cpp | 27 +- src/fuse_create.cpp | 486 +- src/fuse_fallocate.cpp | 10 +- src/fuse_fallocate.hpp | 8 +- src/fuse_fchmod.cpp | 23 +- src/fuse_fchmod.hpp | 4 +- src/fuse_fchown.cpp | 25 +- src/fuse_fchown.hpp | 6 +- src/fuse_fgetattr.cpp | 63 +- src/fuse_fgetattr.hpp | 6 +- src/fuse_free_hide.cpp | 38 - src/fuse_free_hide.hpp | 28 - src/fuse_fsync.cpp | 6 +- src/fuse_fsync.hpp | 4 +- src/fuse_ftruncate.cpp | 20 +- src/fuse_ftruncate.hpp | 4 +- src/fuse_futimens.cpp | 20 +- src/fuse_futimens.hpp | 4 +- src/fuse_getattr.cpp | 3 + src/fuse_init.cpp | 9 +- src/fuse_link.cpp | 2 +- src/fuse_open.cpp | 566 +- src/fuse_passthrough.hpp | 30 + src/fuse_prepare_hide.cpp | 44 - src/fuse_prepare_hide.hpp | 29 - src/fuse_release.cpp | 96 +- src/fuse_rename.cpp | 95 +- src/ghc/filesystem.hpp | 6072 ----------------- src/mergerfs.cpp | 4 - src/nonstd/expected.hpp | 2537 ------- src/nonstd/string_view.hpp | 1709 ----- src/option_parser.cpp | 10 +- src/state.cpp | 3 + src/state.hpp | 36 + 398 files changed, 43113 insertions(+), 17358 deletions(-) delete mode 100644 libfuse/lib/ghc/filesystem.hpp create mode 100644 src/boost/assert.hpp create mode 100644 src/boost/assert/source_location.hpp create mode 100644 src/boost/config.hpp create mode 100644 src/boost/config/abi/borland_prefix.hpp create mode 100644 src/boost/config/abi/borland_suffix.hpp create mode 100644 src/boost/config/abi/msvc_prefix.hpp create mode 100644 src/boost/config/abi/msvc_suffix.hpp create mode 100644 src/boost/config/abi_prefix.hpp create mode 100644 src/boost/config/abi_suffix.hpp create mode 100644 src/boost/config/assert_cxx03.hpp create mode 100644 src/boost/config/assert_cxx11.hpp create mode 100644 src/boost/config/assert_cxx14.hpp create mode 100644 src/boost/config/assert_cxx17.hpp create mode 100644 src/boost/config/assert_cxx20.hpp create mode 100644 src/boost/config/assert_cxx23.hpp create mode 100644 src/boost/config/assert_cxx98.hpp create mode 100644 src/boost/config/auto_link.hpp create mode 100644 src/boost/config/compiler/borland.hpp create mode 100644 src/boost/config/compiler/clang.hpp create mode 100644 src/boost/config/compiler/clang_version.hpp create mode 100644 src/boost/config/compiler/codegear.hpp create mode 100644 src/boost/config/compiler/comeau.hpp create mode 100644 src/boost/config/compiler/common_edg.hpp create mode 100644 src/boost/config/compiler/compaq_cxx.hpp create mode 100644 src/boost/config/compiler/cray.hpp create mode 100644 src/boost/config/compiler/diab.hpp create mode 100644 src/boost/config/compiler/digitalmars.hpp create mode 100644 src/boost/config/compiler/gcc.hpp create mode 100644 src/boost/config/compiler/gcc_xml.hpp create mode 100644 src/boost/config/compiler/greenhills.hpp create mode 100644 src/boost/config/compiler/hp_acc.hpp create mode 100644 src/boost/config/compiler/intel.hpp create mode 100644 src/boost/config/compiler/kai.hpp create mode 100644 src/boost/config/compiler/metrowerks.hpp create mode 100644 src/boost/config/compiler/mpw.hpp create mode 100644 src/boost/config/compiler/nvcc.hpp create mode 100644 src/boost/config/compiler/pathscale.hpp create mode 100644 src/boost/config/compiler/pgi.hpp create mode 100644 src/boost/config/compiler/sgi_mipspro.hpp create mode 100644 src/boost/config/compiler/sunpro_cc.hpp create mode 100644 src/boost/config/compiler/vacpp.hpp create mode 100644 src/boost/config/compiler/visualc.hpp create mode 100644 src/boost/config/compiler/xlcpp.hpp create mode 100644 src/boost/config/compiler/xlcpp_zos.hpp create mode 100644 src/boost/config/detail/cxx_composite.hpp create mode 100644 src/boost/config/detail/posix_features.hpp create mode 100644 src/boost/config/detail/select_compiler_config.hpp create mode 100644 src/boost/config/detail/select_platform_config.hpp create mode 100644 src/boost/config/detail/select_stdlib_config.hpp create mode 100644 src/boost/config/detail/suffix.hpp create mode 100644 src/boost/config/header_deprecated.hpp create mode 100644 src/boost/config/helper_macros.hpp create mode 100644 src/boost/config/no_tr1/cmath.hpp create mode 100644 src/boost/config/no_tr1/complex.hpp create mode 100644 src/boost/config/no_tr1/functional.hpp create mode 100644 src/boost/config/no_tr1/memory.hpp create mode 100644 src/boost/config/no_tr1/utility.hpp create mode 100644 src/boost/config/platform/aix.hpp create mode 100644 src/boost/config/platform/amigaos.hpp create mode 100644 src/boost/config/platform/beos.hpp create mode 100644 src/boost/config/platform/bsd.hpp create mode 100644 src/boost/config/platform/cloudabi.hpp create mode 100644 src/boost/config/platform/cray.hpp create mode 100644 src/boost/config/platform/cygwin.hpp create mode 100644 src/boost/config/platform/haiku.hpp create mode 100644 src/boost/config/platform/hpux.hpp create mode 100644 src/boost/config/platform/irix.hpp create mode 100644 src/boost/config/platform/linux.hpp create mode 100644 src/boost/config/platform/macos.hpp create mode 100644 src/boost/config/platform/qnxnto.hpp create mode 100644 src/boost/config/platform/solaris.hpp create mode 100644 src/boost/config/platform/symbian.hpp create mode 100644 src/boost/config/platform/vms.hpp create mode 100644 src/boost/config/platform/vxworks.hpp create mode 100644 src/boost/config/platform/wasm.hpp create mode 100644 src/boost/config/platform/win32.hpp create mode 100644 src/boost/config/platform/zos.hpp create mode 100644 src/boost/config/pragma_message.hpp create mode 100644 src/boost/config/requires_threads.hpp create mode 100644 src/boost/config/stdlib/dinkumware.hpp create mode 100644 src/boost/config/stdlib/libcomo.hpp create mode 100644 src/boost/config/stdlib/libcpp.hpp create mode 100644 src/boost/config/stdlib/libstdcpp3.hpp create mode 100644 src/boost/config/stdlib/modena.hpp create mode 100644 src/boost/config/stdlib/msl.hpp create mode 100644 src/boost/config/stdlib/roguewave.hpp create mode 100644 src/boost/config/stdlib/sgi.hpp create mode 100644 src/boost/config/stdlib/stlport.hpp create mode 100644 src/boost/config/stdlib/vacpp.hpp create mode 100644 src/boost/config/stdlib/xlcpp_zos.hpp create mode 100644 src/boost/config/user.hpp create mode 100644 src/boost/config/warning_disable.hpp create mode 100644 src/boost/config/workaround.hpp create mode 100644 src/boost/container_hash/detail/hash_integral.hpp create mode 100644 src/boost/container_hash/detail/hash_mix.hpp create mode 100644 src/boost/container_hash/detail/hash_range.hpp create mode 100644 src/boost/container_hash/detail/hash_tuple_like.hpp create mode 100644 src/boost/container_hash/detail/mulx.hpp create mode 100644 src/boost/container_hash/hash.hpp create mode 100644 src/boost/container_hash/hash_fwd.hpp create mode 100644 src/boost/container_hash/is_contiguous_range.hpp create mode 100644 src/boost/container_hash/is_described_class.hpp create mode 100644 src/boost/container_hash/is_range.hpp create mode 100644 src/boost/container_hash/is_tuple_like.hpp create mode 100644 src/boost/container_hash/is_unordered_range.hpp create mode 100644 src/boost/core/addressof.hpp create mode 100644 src/boost/core/allocator_access.hpp create mode 100644 src/boost/core/allocator_traits.hpp create mode 100644 src/boost/core/bit.hpp create mode 100644 src/boost/core/detail/sp_thread_pause.hpp create mode 100644 src/boost/core/detail/sp_thread_sleep.hpp create mode 100644 src/boost/core/detail/sp_thread_yield.hpp create mode 100644 src/boost/core/detail/sp_win32_sleep.hpp create mode 100644 src/boost/core/empty_value.hpp create mode 100644 src/boost/core/ignore_unused.hpp create mode 100644 src/boost/core/no_exceptions_support.hpp create mode 100644 src/boost/core/noncopyable.hpp create mode 100644 src/boost/core/nvp.hpp create mode 100644 src/boost/core/pointer_traits.hpp create mode 100644 src/boost/core/serialization.hpp create mode 100644 src/boost/core/yield_primitives.hpp create mode 100644 src/boost/cstdint.hpp create mode 100644 src/boost/current_function.hpp create mode 100644 src/boost/describe/bases.hpp create mode 100644 src/boost/describe/detail/config.hpp create mode 100644 src/boost/describe/detail/cx_streq.hpp create mode 100644 src/boost/describe/detail/void_t.hpp create mode 100644 src/boost/describe/members.hpp create mode 100644 src/boost/describe/modifiers.hpp create mode 100644 src/boost/detail/workaround.hpp create mode 100644 src/boost/exception/exception.hpp create mode 100644 src/boost/limits.hpp create mode 100644 src/boost/mp11/algorithm.hpp create mode 100644 src/boost/mp11/bind.hpp create mode 100644 src/boost/mp11/detail/config.hpp create mode 100644 src/boost/mp11/detail/mp_append.hpp create mode 100644 src/boost/mp11/detail/mp_copy_if.hpp create mode 100644 src/boost/mp11/detail/mp_count.hpp create mode 100644 src/boost/mp11/detail/mp_defer.hpp create mode 100644 src/boost/mp11/detail/mp_fold.hpp create mode 100644 src/boost/mp11/detail/mp_front.hpp create mode 100644 src/boost/mp11/detail/mp_is_list.hpp create mode 100644 src/boost/mp11/detail/mp_is_value_list.hpp create mode 100644 src/boost/mp11/detail/mp_list.hpp create mode 100644 src/boost/mp11/detail/mp_list_v.hpp create mode 100644 src/boost/mp11/detail/mp_map_find.hpp create mode 100644 src/boost/mp11/detail/mp_min_element.hpp create mode 100644 src/boost/mp11/detail/mp_plus.hpp create mode 100644 src/boost/mp11/detail/mp_remove_if.hpp create mode 100644 src/boost/mp11/detail/mp_rename.hpp create mode 100644 src/boost/mp11/detail/mp_value.hpp create mode 100644 src/boost/mp11/detail/mp_void.hpp create mode 100644 src/boost/mp11/detail/mp_with_index.hpp create mode 100644 src/boost/mp11/function.hpp create mode 100644 src/boost/mp11/integer_sequence.hpp create mode 100644 src/boost/mp11/integral.hpp create mode 100644 src/boost/mp11/list.hpp create mode 100644 src/boost/mp11/set.hpp create mode 100644 src/boost/mp11/tuple.hpp create mode 100644 src/boost/mp11/utility.hpp create mode 100644 src/boost/mp11/version.hpp create mode 100644 src/boost/predef.h create mode 100644 src/boost/predef/architecture.h create mode 100644 src/boost/predef/architecture/alpha.h create mode 100644 src/boost/predef/architecture/arm.h create mode 100644 src/boost/predef/architecture/blackfin.h create mode 100644 src/boost/predef/architecture/convex.h create mode 100644 src/boost/predef/architecture/e2k.h create mode 100644 src/boost/predef/architecture/ia64.h create mode 100644 src/boost/predef/architecture/loongarch.h create mode 100644 src/boost/predef/architecture/m68k.h create mode 100644 src/boost/predef/architecture/mips.h create mode 100644 src/boost/predef/architecture/parisc.h create mode 100644 src/boost/predef/architecture/ppc.h create mode 100644 src/boost/predef/architecture/ptx.h create mode 100644 src/boost/predef/architecture/pyramid.h create mode 100644 src/boost/predef/architecture/riscv.h create mode 100644 src/boost/predef/architecture/rs6k.h create mode 100644 src/boost/predef/architecture/sparc.h create mode 100644 src/boost/predef/architecture/superh.h create mode 100644 src/boost/predef/architecture/sys370.h create mode 100644 src/boost/predef/architecture/sys390.h create mode 100644 src/boost/predef/architecture/x86.h create mode 100644 src/boost/predef/architecture/x86/32.h create mode 100644 src/boost/predef/architecture/x86/64.h create mode 100644 src/boost/predef/architecture/z.h create mode 100644 src/boost/predef/compiler.h create mode 100644 src/boost/predef/compiler/borland.h create mode 100644 src/boost/predef/compiler/clang.h create mode 100644 src/boost/predef/compiler/comeau.h create mode 100644 src/boost/predef/compiler/compaq.h create mode 100644 src/boost/predef/compiler/diab.h create mode 100644 src/boost/predef/compiler/digitalmars.h create mode 100644 src/boost/predef/compiler/dignus.h create mode 100644 src/boost/predef/compiler/edg.h create mode 100644 src/boost/predef/compiler/ekopath.h create mode 100644 src/boost/predef/compiler/gcc.h create mode 100644 src/boost/predef/compiler/gcc_xml.h create mode 100644 src/boost/predef/compiler/greenhills.h create mode 100644 src/boost/predef/compiler/hp_acc.h create mode 100644 src/boost/predef/compiler/iar.h create mode 100644 src/boost/predef/compiler/ibm.h create mode 100644 src/boost/predef/compiler/intel.h create mode 100644 src/boost/predef/compiler/kai.h create mode 100644 src/boost/predef/compiler/llvm.h create mode 100644 src/boost/predef/compiler/metaware.h create mode 100644 src/boost/predef/compiler/metrowerks.h create mode 100644 src/boost/predef/compiler/microtec.h create mode 100644 src/boost/predef/compiler/mpw.h create mode 100644 src/boost/predef/compiler/nvcc.h create mode 100644 src/boost/predef/compiler/palm.h create mode 100644 src/boost/predef/compiler/pgi.h create mode 100644 src/boost/predef/compiler/sgi_mipspro.h create mode 100644 src/boost/predef/compiler/sunpro.h create mode 100644 src/boost/predef/compiler/tendra.h create mode 100644 src/boost/predef/compiler/visualc.h create mode 100644 src/boost/predef/compiler/watcom.h create mode 100644 src/boost/predef/detail/_cassert.h create mode 100644 src/boost/predef/detail/_exception.h create mode 100644 src/boost/predef/detail/comp_detected.h create mode 100644 src/boost/predef/detail/os_detected.h create mode 100644 src/boost/predef/detail/platform_detected.h create mode 100644 src/boost/predef/detail/test.h create mode 100644 src/boost/predef/hardware.h create mode 100644 src/boost/predef/hardware/simd.h create mode 100644 src/boost/predef/hardware/simd/arm.h create mode 100644 src/boost/predef/hardware/simd/arm/versions.h create mode 100644 src/boost/predef/hardware/simd/ppc.h create mode 100644 src/boost/predef/hardware/simd/ppc/versions.h create mode 100644 src/boost/predef/hardware/simd/x86.h create mode 100644 src/boost/predef/hardware/simd/x86/versions.h create mode 100644 src/boost/predef/hardware/simd/x86_amd.h create mode 100644 src/boost/predef/hardware/simd/x86_amd/versions.h create mode 100644 src/boost/predef/language.h create mode 100644 src/boost/predef/language/cuda.h create mode 100644 src/boost/predef/language/objc.h create mode 100644 src/boost/predef/language/stdc.h create mode 100644 src/boost/predef/language/stdcpp.h create mode 100644 src/boost/predef/library.h create mode 100644 src/boost/predef/library/c.h create mode 100644 src/boost/predef/library/c/_prefix.h create mode 100644 src/boost/predef/library/c/cloudabi.h create mode 100644 src/boost/predef/library/c/gnu.h create mode 100644 src/boost/predef/library/c/uc.h create mode 100644 src/boost/predef/library/c/vms.h create mode 100644 src/boost/predef/library/c/zos.h create mode 100644 src/boost/predef/library/std.h create mode 100644 src/boost/predef/library/std/_prefix.h create mode 100644 src/boost/predef/library/std/cxx.h create mode 100644 src/boost/predef/library/std/dinkumware.h create mode 100644 src/boost/predef/library/std/libcomo.h create mode 100644 src/boost/predef/library/std/modena.h create mode 100644 src/boost/predef/library/std/msl.h create mode 100644 src/boost/predef/library/std/msvc.h create mode 100644 src/boost/predef/library/std/roguewave.h create mode 100644 src/boost/predef/library/std/sgi.h create mode 100644 src/boost/predef/library/std/stdcpp3.h create mode 100644 src/boost/predef/library/std/stlport.h create mode 100644 src/boost/predef/library/std/vacpp.h create mode 100644 src/boost/predef/make.h create mode 100644 src/boost/predef/os.h create mode 100644 src/boost/predef/os/aix.h create mode 100644 src/boost/predef/os/amigaos.h create mode 100644 src/boost/predef/os/beos.h create mode 100644 src/boost/predef/os/bsd.h create mode 100644 src/boost/predef/os/bsd/bsdi.h create mode 100644 src/boost/predef/os/bsd/dragonfly.h create mode 100644 src/boost/predef/os/bsd/free.h create mode 100644 src/boost/predef/os/bsd/net.h create mode 100644 src/boost/predef/os/bsd/open.h create mode 100644 src/boost/predef/os/cygwin.h create mode 100644 src/boost/predef/os/haiku.h create mode 100644 src/boost/predef/os/hpux.h create mode 100644 src/boost/predef/os/ios.h create mode 100644 src/boost/predef/os/irix.h create mode 100644 src/boost/predef/os/linux.h create mode 100644 src/boost/predef/os/macos.h create mode 100644 src/boost/predef/os/os400.h create mode 100644 src/boost/predef/os/qnxnto.h create mode 100644 src/boost/predef/os/solaris.h create mode 100644 src/boost/predef/os/unix.h create mode 100644 src/boost/predef/os/vms.h create mode 100644 src/boost/predef/os/windows.h create mode 100644 src/boost/predef/other.h create mode 100644 src/boost/predef/other/endian.h create mode 100644 src/boost/predef/other/wordsize.h create mode 100644 src/boost/predef/other/workaround.h create mode 100644 src/boost/predef/platform.h create mode 100644 src/boost/predef/platform/android.h create mode 100644 src/boost/predef/platform/cloudabi.h create mode 100644 src/boost/predef/platform/ios.h create mode 100644 src/boost/predef/platform/mingw.h create mode 100644 src/boost/predef/platform/mingw32.h create mode 100644 src/boost/predef/platform/mingw64.h create mode 100644 src/boost/predef/platform/windows_desktop.h create mode 100644 src/boost/predef/platform/windows_phone.h create mode 100644 src/boost/predef/platform/windows_runtime.h create mode 100644 src/boost/predef/platform/windows_server.h create mode 100644 src/boost/predef/platform/windows_store.h create mode 100644 src/boost/predef/platform/windows_system.h create mode 100644 src/boost/predef/platform/windows_uwp.h create mode 100644 src/boost/predef/version.h create mode 100644 src/boost/predef/version_number.h create mode 100644 src/boost/static_assert.hpp create mode 100644 src/boost/throw_exception.hpp create mode 100644 src/boost/unordered/concurrent_flat_map.hpp create mode 100644 src/boost/unordered/concurrent_flat_map_fwd.hpp create mode 100644 src/boost/unordered/detail/allocator_constructed.hpp create mode 100644 src/boost/unordered/detail/archive_constructed.hpp create mode 100644 src/boost/unordered/detail/bad_archive_exception.hpp create mode 100644 src/boost/unordered/detail/concurrent_static_asserts.hpp create mode 100644 src/boost/unordered/detail/foa/concurrent_table.hpp create mode 100644 src/boost/unordered/detail/foa/core.hpp create mode 100644 src/boost/unordered/detail/foa/cumulative_stats.hpp create mode 100644 src/boost/unordered/detail/foa/flat_map_types.hpp create mode 100644 src/boost/unordered/detail/foa/ignore_wshadow.hpp create mode 100644 src/boost/unordered/detail/foa/reentrancy_check.hpp create mode 100644 src/boost/unordered/detail/foa/restore_wshadow.hpp create mode 100644 src/boost/unordered/detail/foa/rw_spinlock.hpp create mode 100644 src/boost/unordered/detail/foa/tuple_rotate_right.hpp create mode 100644 src/boost/unordered/detail/foa/types_constructibility.hpp create mode 100644 src/boost/unordered/detail/mulx.hpp create mode 100644 src/boost/unordered/detail/narrow_cast.hpp create mode 100644 src/boost/unordered/detail/opt_storage.hpp create mode 100644 src/boost/unordered/detail/serialization_version.hpp create mode 100644 src/boost/unordered/detail/static_assert.hpp create mode 100644 src/boost/unordered/detail/type_traits.hpp create mode 100644 src/boost/unordered/hash_traits.hpp create mode 100644 src/boost/unordered/unordered_flat_map_fwd.hpp create mode 100644 src/boost/unordered/unordered_printers.hpp create mode 100644 src/boost/version.hpp delete mode 100644 src/fuse_free_hide.cpp delete mode 100644 src/fuse_free_hide.hpp create mode 100644 src/fuse_passthrough.hpp delete mode 100644 src/fuse_prepare_hide.cpp delete mode 100644 src/fuse_prepare_hide.hpp delete mode 100644 src/ghc/filesystem.hpp delete mode 100644 src/nonstd/expected.hpp delete mode 100644 src/nonstd/string_view.hpp create mode 100644 src/state.cpp create mode 100644 src/state.hpp diff --git a/DEPENDENCIES b/DEPENDENCIES index 3ef8eeff..1319b3b9 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -4,8 +4,12 @@ * libfuse: https://github.com/libfuse/libfuse (heavily modified fork of v2.x) * rapidhash: https://github.com/Nicoshev/rapidhash -* ghc::filesystem: https://github.com/gulrak/filesystem -* nonstd::optional: https://github.com/martinmoene/optional-lite * fmt: https://github.com/fmtlib/fmt * concurrentqueue: https://github.com/cameron314/concurrentqueue * scope_guard: https://github.com/Neargye/scope_guard +* boost + * download boost + * ./bootstrap.sh + * ./b2 tools/bcp + * ./dist/bin/bcp pool/pool.hpp + * ./dist/bin/bcp unordered/concurrent_flat_map.hpp diff --git a/Makefile b/Makefile index df0e489a..3bc8d8e0 100644 --- a/Makefile +++ b/Makefile @@ -76,6 +76,7 @@ CXXFLAGS := \ -std=c++17 \ $(STATIC_FLAGS) \ $(LTO_FLAGS) \ + -Isrc \ -Wall \ -Wno-unused-result \ -MMD diff --git a/libfuse/include/fuse.h b/libfuse/include/fuse.h index 459cbf44..ca48ffc8 100644 --- a/libfuse/include/fuse.h +++ b/libfuse/include/fuse.h @@ -20,6 +20,7 @@ #include #include #include +#include EXTERN_C_BEGIN @@ -94,15 +95,6 @@ struct fuse_operations * */ int (*mkdir) (const char *, mode_t); - /** Hide files unlinked / renamed over - * - * Allows storing of a file handle when a file is unlinked - * while open. Helps manage the fact the kernel usually does - * not send fh with getattr requests. - */ - int (*prepare_hide)(const char *name_, uint64_t *fh_); - int (*free_hide)(const uint64_t fh_); - /** Remove a file */ int (*unlink) (const char *); @@ -120,11 +112,11 @@ struct fuse_operations /** Change the permission bits of a file */ int (*chmod) (const char *, mode_t); - int (*fchmod)(const fuse_file_info_t *, const mode_t); + int (*fchmod)(const uint64_t, const mode_t); /** Change the owner and group of a file */ int (*chown) (const char *, uid_t, gid_t); - int (*fchown)(const fuse_file_info_t *, const uid_t, const gid_t); + int (*fchown)(const uint64_t, const uid_t, const gid_t); /** Change the size of a file */ int (*truncate) (const char *, off_t); @@ -205,7 +197,7 @@ struct fuse_operations * * Changed in version 2.2 */ - int (*fsync) (const fuse_file_info_t *, int); + int (*fsync) (const uint64_t, int); /** Set extended attributes */ int (*setxattr) (const char *, const char *, const char *, size_t, int); @@ -335,7 +327,7 @@ struct fuse_operations * * Introduced in version 2.5 */ - int (*ftruncate) (const fuse_file_info_t *, off_t); + int (*ftruncate) (const uint64_t, off_t); /** * Get attributes from an open file @@ -349,7 +341,7 @@ struct fuse_operations * * Introduced in version 2.5 */ - int (*fgetattr) (const fuse_file_info_t *, struct stat *, fuse_timeouts_t *); + int (*fgetattr) (const uint64_t, struct stat *, fuse_timeouts_t *); /** * Perform POSIX file locking operation @@ -399,7 +391,7 @@ struct fuse_operations * Introduced in version 2.6 */ int (*utimens)(const char *, const struct timespec tv[2]); - int (*futimens)(const fuse_file_info_t *ffi_, const struct timespec tv_[2]); + int (*futimens)(const uint64_t fh, const struct timespec tv[2]); /** * Map block index within file to block index within device @@ -519,7 +511,7 @@ struct fuse_operations * * Introduced in version 2.9.1 */ - int (*fallocate) (const fuse_file_info_t *, int, off_t, off_t); + int (*fallocate) (const uint64_t, int, off_t, off_t); /** * Copy a range of data from one file to another @@ -569,20 +561,14 @@ struct fuse_operations */ struct fuse_context { - /** Pointer to the fuse object */ + uint64_t unique; + uint64_t nodeid; + uint32_t opcode; + uid_t uid; + gid_t gid; + pid_t pid; + mode_t umask; struct fuse *fuse; - - /** User ID of the calling process */ - uid_t uid; - - /** Group ID of the calling process */ - gid_t gid; - - /** Thread ID of the calling process */ - pid_t pid; - - /** Umask of the calling process (introduced in version 2.8) */ - mode_t umask; }; /** @@ -790,6 +776,12 @@ void fuse_gc1(); void fuse_gc(); void fuse_invalidate_all_nodes(); +int fuse_get_dev_fuse_fd(const struct fuse_context *fc); +int fuse_passthrough_open(const struct fuse_context *fc, + const int fd); +int fuse_passthrough_close(const struct fuse_context *fc, + const int backing_id); + EXTERN_C_END #endif /* _FUSE_H_ */ diff --git a/libfuse/include/fuse_common.h b/libfuse/include/fuse_common.h index ef2109ad..573f55d4 100644 --- a/libfuse/include/fuse_common.h +++ b/libfuse/include/fuse_common.h @@ -87,11 +87,14 @@ struct fuse_file_info_t uint32_t parallel_direct_writes:1; uint32_t noflush:1; + uint32_t passthrough:1; /** File handle. May be filled in by filesystem in open(). Available in all other file operations */ uint64_t fh; + int32_t backing_id; + /** Lock owner id. Available in locking operations and flush */ uint64_t lock_owner; }; @@ -127,7 +130,9 @@ struct fuse_file_info_t #define FUSE_CAP_SETXATTR_EXT (1ULL << 22) #define FUSE_CAP_DIRECT_IO_ALLOW_MMAP (1ULL << 23) #define FUSE_CAP_CREATE_SUPP_GROUP (1ULL << 24) - +#define FUSE_CAP_PASSTHROUGH (1ULL << 25) +#define FUSE_CAP_HANDLE_KILLPRIV (1ULL << 26) +#define FUSE_CAP_HANDLE_KILLPRIV_V2 (1ULL << 27) /** * Ioctl flags diff --git a/libfuse/include/fuse_kernel.h b/libfuse/include/fuse_kernel.h index d3c634bc..b4196ca3 100644 --- a/libfuse/include/fuse_kernel.h +++ b/libfuse/include/fuse_kernel.h @@ -211,6 +211,24 @@ * 7.39 * - add FUSE_DIRECT_IO_ALLOW_MMAP * - add FUSE_STATX and related structures + * + * 7.40 + * - add max_stack_depth to fuse_init_out, add FUSE_PASSTHROUGH init flag + * - add backing_id to fuse_open_out, add FOPEN_PASSTHROUGH open flag + * - add FUSE_NO_EXPORT_SUPPORT init flag + * - add FUSE_NOTIFY_RESEND, add FUSE_HAS_RESEND init flag + * + * 7.41 + * - add FUSE_ALLOW_IDMAP + * 7.42 + * - Add FUSE_OVER_IO_URING and all other io-uring related flags and data + * structures: + * - struct fuse_uring_ent_in_out + * - struct fuse_uring_req_header + * - struct fuse_uring_cmd_req + * - FUSE_URING_IN_OUT_HEADER_SZ + * - FUSE_URING_OP_IN_OUT_SZ + * - enum fuse_uring_cmd */ #ifndef _LINUX_FUSE_H @@ -246,7 +264,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 39 +#define FUSE_KERNEL_MINOR_VERSION 42 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -353,6 +371,7 @@ struct fuse_file_lock { * FOPEN_STREAM: the file is stream-like (no file position at all) * FOPEN_NOFLUSH: don't flush data cache on close (unless FUSE_WRITEBACK_CACHE) * FOPEN_PARALLEL_DIRECT_WRITES: Allow concurrent direct writes on the same inode + * FOPEN_PASSTHROUGH: passthrough read/write io for this open file */ #define FOPEN_DIRECT_IO (1 << 0) #define FOPEN_KEEP_CACHE (1 << 1) @@ -361,6 +380,7 @@ struct fuse_file_lock { #define FOPEN_STREAM (1 << 4) #define FOPEN_NOFLUSH (1 << 5) #define FOPEN_PARALLEL_DIRECT_WRITES (1 << 6) +#define FOPEN_PASSTHROUGH (1 << 7) /** * INIT request/reply flags @@ -410,38 +430,43 @@ struct fuse_file_lock { * symlink and mknod (single group that matches parent) * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode. + * FUSE_NO_EXPORT_SUPPORT: explicitly disable export support + * FUSE_HAS_RESEND: kernel supports resending pending requests, and the high bit + * of the request ID indicates resend requests + * FUSE_ALLOW_IDMAP: allow creation of idmapped mounts + * FUSE_OVER_IO_URING: Indicate that client supports io-uring */ -#define FUSE_ASYNC_READ (1 << 0) -#define FUSE_POSIX_LOCKS (1 << 1) -#define FUSE_FILE_OPS (1 << 2) -#define FUSE_ATOMIC_O_TRUNC (1 << 3) -#define FUSE_EXPORT_SUPPORT (1 << 4) -#define FUSE_BIG_WRITES (1 << 5) -#define FUSE_DONT_MASK (1 << 6) -#define FUSE_SPLICE_WRITE (1 << 7) -#define FUSE_SPLICE_MOVE (1 << 8) -#define FUSE_SPLICE_READ (1 << 9) -#define FUSE_FLOCK_LOCKS (1 << 10) -#define FUSE_HAS_IOCTL_DIR (1 << 11) -#define FUSE_AUTO_INVAL_DATA (1 << 12) -#define FUSE_DO_READDIRPLUS (1 << 13) -#define FUSE_READDIRPLUS_AUTO (1 << 14) -#define FUSE_ASYNC_DIO (1 << 15) -#define FUSE_WRITEBACK_CACHE (1 << 16) -#define FUSE_NO_OPEN_SUPPORT (1 << 17) -#define FUSE_PARALLEL_DIROPS (1 << 18) -#define FUSE_HANDLE_KILLPRIV (1 << 19) -#define FUSE_POSIX_ACL (1 << 20) -#define FUSE_ABORT_ERROR (1 << 21) -#define FUSE_MAX_PAGES (1 << 22) -#define FUSE_CACHE_SYMLINKS (1 << 23) -#define FUSE_NO_OPENDIR_SUPPORT (1 << 24) -#define FUSE_EXPLICIT_INVAL_DATA (1 << 25) -#define FUSE_MAP_ALIGNMENT (1 << 26) -#define FUSE_SUBMOUNTS (1 << 27) -#define FUSE_HANDLE_KILLPRIV_V2 (1 << 28) -#define FUSE_SETXATTR_EXT (1 << 29) -#define FUSE_INIT_EXT (1 << 30) +#define FUSE_ASYNC_READ (1ULL << 0) +#define FUSE_POSIX_LOCKS (1ULL << 1) +#define FUSE_FILE_OPS (1ULL << 2) +#define FUSE_ATOMIC_O_TRUNC (1ULL << 3) +#define FUSE_EXPORT_SUPPORT (1ULL << 4) +#define FUSE_BIG_WRITES (1ULL << 5) +#define FUSE_DONT_MASK (1ULL << 6) +#define FUSE_SPLICE_WRITE (1ULL << 7) +#define FUSE_SPLICE_MOVE (1ULL << 8) +#define FUSE_SPLICE_READ (1ULL << 9) +#define FUSE_FLOCK_LOCKS (1ULL << 10) +#define FUSE_HAS_IOCTL_DIR (1ULL << 11) +#define FUSE_AUTO_INVAL_DATA (1ULL << 12) +#define FUSE_DO_READDIRPLUS (1ULL << 13) +#define FUSE_READDIRPLUS_AUTO (1ULL << 14) +#define FUSE_ASYNC_DIO (1ULL << 15) +#define FUSE_WRITEBACK_CACHE (1ULL << 16) +#define FUSE_NO_OPEN_SUPPORT (1ULL << 17) +#define FUSE_PARALLEL_DIROPS (1ULL << 18) +#define FUSE_HANDLE_KILLPRIV (1ULL << 19) +#define FUSE_POSIX_ACL (1ULL << 20) +#define FUSE_ABORT_ERROR (1ULL << 21) +#define FUSE_MAX_PAGES (1ULL << 22) +#define FUSE_CACHE_SYMLINKS (1ULL << 23) +#define FUSE_NO_OPENDIR_SUPPORT (1ULL << 24) +#define FUSE_EXPLICIT_INVAL_DATA (1ULL << 25) +#define FUSE_MAP_ALIGNMENT (1ULL << 26) +#define FUSE_SUBMOUNTS (1ULL << 27) +#define FUSE_HANDLE_KILLPRIV_V2 (1ULL << 28) +#define FUSE_SETXATTR_EXT (1ULL << 29) +#define FUSE_INIT_EXT (1ULL << 30) #define FUSE_INIT_RESERVED (1ULL << 31) /* bits 32..63 get shifted down 32 bits into the flags2 field */ #define FUSE_SECURITY_CTX (1ULL << 32) @@ -449,9 +474,14 @@ struct fuse_file_lock { #define FUSE_CREATE_SUPP_GROUP (1ULL << 34) #define FUSE_HAS_EXPIRE_ONLY (1ULL << 35) #define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36) +#define FUSE_PASSTHROUGH (1ULL << 37) +#define FUSE_NO_EXPORT_SUPPORT (1ULL << 38) +#define FUSE_HAS_RESEND (1ULL << 39) /* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ #define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP +#define FUSE_ALLOW_IDMAP (1ULL << 40) +#define FUSE_OVER_IO_URING (1ULL << 41) /** * CUSE INIT request/reply flags @@ -635,6 +665,7 @@ enum fuse_notify_code { FUSE_NOTIFY_STORE = 4, FUSE_NOTIFY_RETRIEVE = 5, FUSE_NOTIFY_DELETE = 6, + FUSE_NOTIFY_RESEND = 7, FUSE_NOTIFY_CODE_MAX, }; @@ -761,7 +792,7 @@ struct fuse_create_in { struct fuse_open_out { uint64_t fh; uint32_t open_flags; - uint32_t padding; + int32_t backing_id; }; struct fuse_release_in { @@ -877,7 +908,8 @@ struct fuse_init_out { uint16_t max_pages; uint16_t map_alignment; uint32_t flags2; - uint32_t unused[7]; + uint32_t max_stack_depth; + uint32_t unused[6]; }; #define CUSE_INIT_INFO_MAX 4096 @@ -960,6 +992,29 @@ struct fuse_fallocate_in { uint32_t padding; }; +/** + * FUSE request unique ID flag + * + * Indicates whether this is a resend request. The receiver should handle this + * request accordingly. + */ +#define FUSE_UNIQUE_RESEND (1ULL << 63) + +/** + * This value will be set by the kernel to + * (struct fuse_in_header).{uid,gid} fields in + * case when: + * - fuse daemon enabled FUSE_ALLOW_IDMAP + * - idmapping information is not available and uid/gid + * can not be mapped in accordance with an idmapping. + * + * Note: an idmapping information always available + * for inode creation operations like: + * FUSE_MKNOD, FUSE_SYMLINK, FUSE_MKDIR, FUSE_TMPFILE, + * FUSE_CREATE and FUSE_RENAME2 (with RENAME_WHITEOUT). + */ +#define FUSE_INVALID_UIDGID ((uint32_t)(-1)) + struct fuse_in_header { uint32_t len; uint32_t opcode; @@ -1049,9 +1104,18 @@ struct fuse_notify_retrieve_in { uint64_t dummy4; }; +struct fuse_backing_map { + int32_t fd; + uint32_t flags; + uint64_t padding; +}; + /* Device ioctls: */ #define FUSE_DEV_IOC_MAGIC 229 #define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t) +#define FUSE_DEV_IOC_BACKING_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 1, \ + struct fuse_backing_map) +#define FUSE_DEV_IOC_BACKING_CLOSE _IOW(FUSE_DEV_IOC_MAGIC, 2, uint32_t) struct fuse_lseek_in { uint64_t fh; @@ -1153,4 +1217,67 @@ struct fuse_supp_groups { uint32_t groups[]; }; +/** + * Size of the ring buffer header + */ +#define FUSE_URING_IN_OUT_HEADER_SZ 128 +#define FUSE_URING_OP_IN_OUT_SZ 128 + +/* Used as part of the fuse_uring_req_header */ +struct fuse_uring_ent_in_out { + uint64_t flags; + + /* + * commit ID to be used in a reply to a ring request (see also + * struct fuse_uring_cmd_req) + */ + uint64_t commit_id; + + /* size of user payload buffer */ + uint32_t payload_sz; + uint32_t padding; + + uint64_t reserved; +}; + +/** + * Header for all fuse-io-uring requests + */ +struct fuse_uring_req_header { + /* struct fuse_in_header / struct fuse_out_header */ + char in_out[FUSE_URING_IN_OUT_HEADER_SZ]; + + /* per op code header */ + char op_in[FUSE_URING_OP_IN_OUT_SZ]; + + struct fuse_uring_ent_in_out ring_ent_in_out; +}; + +/** + * sqe commands to the kernel + */ +enum fuse_uring_cmd { + FUSE_IO_URING_CMD_INVALID = 0, + + /* register the request buffer and fetch a fuse request */ + FUSE_IO_URING_CMD_REGISTER = 1, + + /* commit fuse request result and fetch next request */ + FUSE_IO_URING_CMD_COMMIT_AND_FETCH = 2, +}; + +/** + * In the 80B command area of the SQE. + */ +struct fuse_uring_cmd_req { + uint64_t flags; + + /* entry identifier for commits */ + uint64_t commit_id; + + /* queue the command is for (queue index) */ + uint16_t qid; + uint8_t padding[6]; +}; + #endif /* _LINUX_FUSE_H */ diff --git a/libfuse/include/fuse_lowlevel.h b/libfuse/include/fuse_lowlevel.h index 613bcc8d..74731edd 100644 --- a/libfuse/include/fuse_lowlevel.h +++ b/libfuse/include/fuse_lowlevel.h @@ -91,17 +91,13 @@ struct fuse_entry_param /** Additional context associated with requests */ struct fuse_ctx { - /** User ID of the calling process */ - uid_t uid; - - /** Group ID of the calling process */ - gid_t gid; - - /** Thread ID of the calling process */ - pid_t pid; - - /** Umask of the calling process (introduced in version 2.8) */ - mode_t umask; + uint64_t unique; + uint64_t nodeid; + uint32_t opcode; + uid_t uid; + gid_t gid; + pid_t pid; + mode_t umask; }; /* ----------------------------------------------------------- * diff --git a/libfuse/lib/cpu.cpp b/libfuse/lib/cpu.cpp index 15c71e46..c8566d0a 100644 --- a/libfuse/lib/cpu.cpp +++ b/libfuse/lib/cpu.cpp @@ -17,12 +17,12 @@ */ #include "cpu.hpp" -#include "ghc/filesystem.hpp" #include "fmt/core.h" #include #include +#include #include @@ -71,10 +71,10 @@ CPU::setaffinity(const pthread_t thread_id_, } static -ghc::filesystem::path +std::filesystem::path generate_cpu_core_id_path(const int cpu_id_) { - const ghc::filesystem::path basepath{"/sys/devices/system/cpu"}; + const std::filesystem::path basepath{"/sys/devices/system/cpu"}; return basepath / fmt::format("cpu{}",cpu_id_) / "topology" / "core_id"; } @@ -123,7 +123,7 @@ CPU::cpu2core() { int core_id; std::ifstream ifs; - ghc::filesystem::path path; + std::filesystem::path path; if(!CPU_ISSET(i,&cpuset)) continue; @@ -156,7 +156,7 @@ CPU::core2cpus() { int core_id; std::ifstream ifs; - ghc::filesystem::path path; + std::filesystem::path path; if(!CPU_ISSET(i,&cpuset)) continue; diff --git a/libfuse/lib/debug.cpp b/libfuse/lib/debug.cpp index 34ccf7c0..f0fa677e 100644 --- a/libfuse/lib/debug.cpp +++ b/libfuse/lib/debug.cpp @@ -201,6 +201,7 @@ fuse_flag_to_str(const uint64_t offset_) FUSE_INIT_FLAG_CASE(CREATE_SUPP_GROUP); FUSE_INIT_FLAG_CASE(HAS_EXPIRE_ONLY); FUSE_INIT_FLAG_CASE(DIRECT_IO_ALLOW_MMAP); + FUSE_INIT_FLAG_CASE(PASSTHROUGH); } return NULL; diff --git a/libfuse/lib/fuse.cpp b/libfuse/lib/fuse.cpp index e527251b..fbda410d 100644 --- a/libfuse/lib/fuse.cpp +++ b/libfuse/lib/fuse.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -364,9 +364,6 @@ free_node(struct fuse *f_, { filename_free(f_,node_->name); - if(node_->hidden_fh) - f_->fs->op.free_hide(node_->hidden_fh); - node_free(node_); } @@ -938,8 +935,8 @@ try_get_path2(struct fuse *f, const char *name2, char **path1, char **path2, - node_t **wnode1, - node_t **wnode2) + node_t **wnode1, + node_t **wnode2) { int err; @@ -1160,7 +1157,7 @@ static void free_path_wrlock(struct fuse *f, uint64_t nodeid, - node_t *wnode, + node_t *wnode, char *path) { mutex_lock(&f->lock); @@ -1408,7 +1405,7 @@ lookup_path(struct fuse *f, rv = ((fi == NULL) ? f->fs->op.getattr(path,&e->attr,&e->timeout) : - f->fs->op.fgetattr(fi,&e->attr,&e->timeout)); + f->fs->op.fgetattr(fi->fh,&e->attr,&e->timeout)); if(rv) return rv; @@ -1487,14 +1484,19 @@ static struct fuse* req_fuse_prepare(fuse_req_t req) { - struct fuse_context_i *c = fuse_get_context_internal(); + struct fuse_context_i *c = fuse_get_context_internal(); const struct fuse_ctx *ctx = fuse_req_ctx(req); - c->req = req; - c->ctx.fuse = req_fuse(req); - c->ctx.uid = ctx->uid; - c->ctx.gid = ctx->gid; - c->ctx.pid = ctx->pid; - c->ctx.umask = ctx->umask; + + c->req = req; + c->ctx.fuse = req_fuse(req); + c->ctx.opcode = ctx->opcode; + c->ctx.unique = ctx->unique; + c->ctx.nodeid = ctx->nodeid; + c->ctx.uid = ctx->uid; + c->ctx.gid = ctx->gid; + c->ctx.pid = ctx->pid; + c->ctx.umask = ctx->umask; + return c->ctx.fuse; } @@ -1672,41 +1674,36 @@ fuse_lib_getattr(fuse_req_t req, { int err; char *path; + uint64_t fh; struct fuse *f; struct stat buf; node_t *node; fuse_timeouts_t timeout; - fuse_file_info_t ffi = {0}; const struct fuse_getattr_in *arg; arg = (fuse_getattr_in*)fuse_hdr_arg(hdr_); f = req_fuse_prepare(req); + fh = 0; if(arg->getattr_flags & FUSE_GETATTR_FH) - { - ffi.fh = arg->fh; - } - else - { - mutex_lock(&f->lock); - node = get_node(f,hdr_->nodeid); - if(node->hidden_fh) - ffi.fh = node->hidden_fh; - mutex_unlock(&f->lock); - } + fh = arg->fh; memset(&buf,0,sizeof(buf)); err = 0; path = NULL; - if(ffi.fh == 0) - err = get_path(f,hdr_->nodeid,&path); + if(fh == 0) + { + err = get_path(f,hdr_->nodeid,&path); + if(err == -ESTALE) // unlinked but open + err = 0; + } if(!err) { - err = ((ffi.fh == 0) ? + err = ((path != NULL) ? f->fs->op.getattr(path,&buf,&timeout) : - f->fs->op.fgetattr(&ffi,&buf,&timeout)); + f->fs->op.fgetattr(fh,&buf,&timeout)); free_path(f,hdr_->nodeid,path); } @@ -1738,6 +1735,7 @@ fuse_lib_statx_path(fuse_req_t req_, struct fuse_statx st{}; fuse_timeouts_t timeouts{}; + // TODO: if node unlinked... but FUSE may not send it err = get_path(f_,hdr_->nodeid,&fusepath); if(err) { @@ -1803,63 +1801,51 @@ void fuse_lib_setattr(fuse_req_t req, struct fuse_in_header *hdr_) { + uint64_t fh; struct fuse *f = req_fuse_prepare(req); struct stat stbuf = {0}; char *path; int err; - node_t *node; fuse_timeouts_t timeout; - fuse_file_info_t *fi; - fuse_file_info_t ffi = {0}; struct fuse_setattr_in *arg; arg = (fuse_setattr_in*)fuse_hdr_arg(hdr_); - fi = NULL; + fh = 0; if(arg->valid & FATTR_FH) - { - fi = &ffi; - fi->fh = arg->fh; - } - else - { - mutex_lock(&f->lock); - node = get_node(f,hdr_->nodeid); - if(node->hidden_fh) - { - fi = &ffi; - fi->fh = node->hidden_fh; - } - mutex_unlock(&f->lock); - } + fh = arg->fh; err = 0; path = NULL; - if(fi == NULL) - err = get_path(f,hdr_->nodeid,&path); + if(fh == 0) + { + err = get_path(f,hdr_->nodeid,&path); + if(err == -ESTALE) + err = 0; + } if(!err) { err = 0; if(!err && (arg->valid & FATTR_MODE)) - err = ((fi == NULL) ? + err = ((path != NULL) ? f->fs->op.chmod(path,arg->mode) : - f->fs->op.fchmod(fi,arg->mode)); + f->fs->op.fchmod(fh,arg->mode)); if(!err && (arg->valid & (FATTR_UID | FATTR_GID))) { uid_t uid = ((arg->valid & FATTR_UID) ? arg->uid : (uid_t)-1); gid_t gid = ((arg->valid & FATTR_GID) ? arg->gid : (gid_t)-1); - err = ((fi == NULL) ? + err = ((path != NULL) ? f->fs->op.chown(path,uid,gid) : - f->fs->op.fchown(fi,uid,gid)); + f->fs->op.fchown(fh,uid,gid)); } if(!err && (arg->valid & FATTR_SIZE)) - err = ((fi == NULL) ? + err = ((path != NULL) ? f->fs->op.truncate(path,arg->size) : - f->fs->op.ftruncate(fi,arg->size)); + f->fs->op.ftruncate(fh,arg->size)); #ifdef HAVE_UTIMENSAT if(!err && (arg->valid & (FATTR_ATIME | FATTR_MTIME))) @@ -1881,9 +1867,9 @@ fuse_lib_setattr(fuse_req_t req, else if(arg->valid & FATTR_MTIME) tv[1] = (struct timespec){ static_cast(arg->mtime), arg->mtimensec }; - err = ((fi == NULL) ? + err = ((path != NULL) ? f->fs->op.utimens(path,tv) : - f->fs->op.futimens(fi,tv)); + f->fs->op.futimens(fh,tv)); } else #endif @@ -1894,15 +1880,15 @@ fuse_lib_setattr(fuse_req_t req, tv[0].tv_nsec = arg->atimensec; tv[1].tv_sec = arg->mtime; tv[1].tv_nsec = arg->mtimensec; - err = ((fi == NULL) ? + err = ((path != NULL) ? f->fs->op.utimens(path,tv) : - f->fs->op.futimens(fi,tv)); + f->fs->op.futimens(fh,tv)); } if(!err) - err = ((fi == NULL) ? + err = ((path != NULL) ? f->fs->op.getattr(path,&stbuf,&timeout) : - f->fs->op.fgetattr(fi,&stbuf,&timeout)); + f->fs->op.fgetattr(fh,&stbuf,&timeout)); free_path(f,hdr_->nodeid,path); } @@ -2076,10 +2062,8 @@ fuse_lib_unlink(fuse_req_t req, if(!err) { - mutex_lock(&f->lock); if(node_open(wnode)) - err = f->fs->op.prepare_hide(path,&wnode->hidden_fh); - mutex_unlock(&f->lock); + fuse_get_context()->nodeid = wnode->nodeid; err = f->fs->op.unlink(path); if(!err) @@ -2172,11 +2156,6 @@ fuse_lib_rename(fuse_req_t req, if(!err) { - mutex_lock(&f->lock); - if(node_open(wnode2)) - err = f->fs->op.prepare_hide(newpath,&wnode2->hidden_fh); - mutex_unlock(&f->lock); - err = f->fs->op.rename(oldpath,newpath); if(!err) err = rename_node(f,hdr_->nodeid,oldname,arg->newdir,newname); @@ -2244,11 +2223,8 @@ fuse_do_release(struct fuse *f, uint64_t ino, fuse_file_info_t *fi) { - uint64_t fh; node_t *node; - fh = 0; - f->fs->op.release(fi); mutex_lock(&f->lock); @@ -2256,17 +2232,8 @@ fuse_do_release(struct fuse *f, node = get_node(f,ino); assert(node->open_count > 0); node->open_count--; - - if(node->hidden_fh && (node->open_count == 0)) - { - fh = node->hidden_fh; - node->hidden_fh = 0; - } } mutex_unlock(&f->lock); - - if(fh) - f->fs->op.free_hide(fh); } static @@ -2278,6 +2245,7 @@ fuse_lib_create(fuse_req_t req, char *path; struct fuse *f; const char *name; + uint64_t new_nodeid; fuse_file_info_t ffi = {0}; struct fuse_entry_param e; struct fuse_create_in *arg; @@ -2294,6 +2262,14 @@ fuse_lib_create(fuse_req_t req, f = req_fuse_prepare(req); + // opportunistically allocate a node so we have a new nodeid for + // later in the actual create. Added for use with passthrough. + { + node_t *node = find_node(f,hdr_->nodeid,name); + new_nodeid = node->nodeid; + fuse_get_context()->nodeid = new_nodeid; + } + err = get_path_name(f,hdr_->nodeid,name,&path); if(!err) { @@ -2330,6 +2306,7 @@ fuse_lib_create(fuse_req_t req, } else { + forget_node(f,new_nodeid,1); fuse_reply_err(req,err); } @@ -2355,7 +2332,7 @@ open_auto_cache(struct fuse *f, struct stat stbuf; mutex_unlock(&f->lock); - err = f->fs->op.fgetattr(fi,&stbuf,&timeout); + err = f->fs->op.fgetattr(fi->fh,&stbuf,&timeout); mutex_lock(&f->lock); if(!err) @@ -2494,14 +2471,12 @@ fuse_lib_fsync(fuse_req_t req, int err; struct fuse *f; struct fuse_fsync_in *arg; - fuse_file_info_t ffi = {0}; arg = (fuse_fsync_in*)fuse_hdr_arg(hdr_); - ffi.fh = arg->fh; f = req_fuse_prepare(req); - err = f->fs->op.fsync(&ffi, + err = f->fs->op.fsync(arg->fh, !!(arg->fsync_flags & 1)); fuse_reply_err(req,err); @@ -3569,15 +3544,13 @@ fuse_lib_fallocate(fuse_req_t req, { int err; struct fuse *f; - fuse_file_info_t ffi = {0}; const struct fuse_fallocate_in *arg; arg = (fuse_fallocate_in*)fuse_hdr_arg(hdr_); - ffi.fh = arg->fh; f = req_fuse_prepare(req); - err = f->fs->op.fallocate(&ffi, + err = f->fs->op.fallocate(arg->fh, arg->mode, arg->offset, arg->length); @@ -4218,20 +4191,6 @@ fuse_destroy(struct fuse *f) memset(c,0,sizeof(*c)); c->ctx.fuse = f; - - for(i = 0; i < f->id_table.size; i++) - { - node_t *node; - - for(node = f->id_table.array[i]; node != NULL; node = node->id_next) - { - if(!node->hidden_fh) - continue; - - f->fs->op.free_hide(node->hidden_fh); - node->hidden_fh = 0; - } - } } for(i = 0; i < f->id_table.size; i++) @@ -4266,3 +4225,36 @@ fuse_log_metrics_get(void) { return g_LOG_METRICS; } + +int +fuse_get_dev_fuse_fd(const struct fuse_context *fc_) +{ + return fuse_chan_fd(fc_->fuse->se->ch); +} + +int +fuse_passthrough_open(const struct fuse_context *fc_, + const int fd_) +{ + int rv; + int dev_fuse_fd; + struct fuse_backing_map bm = {0}; + + dev_fuse_fd = fuse_get_dev_fuse_fd(fc_); + bm.fd = fd_; + + rv = ::ioctl(dev_fuse_fd,FUSE_DEV_IOC_BACKING_OPEN,&bm); + + return rv; +} + +int +fuse_passthrough_close(const struct fuse_context *fc_, + const int backing_id_) +{ + int dev_fuse_fd; + + dev_fuse_fd = fuse_get_dev_fuse_fd(fc_); + + return ::ioctl(dev_fuse_fd,FUSE_DEV_IOC_BACKING_CLOSE,&backing_id_); +} diff --git a/libfuse/lib/fuse_lowlevel.cpp b/libfuse/lib/fuse_lowlevel.cpp index 97f92a0a..b686e974 100644 --- a/libfuse/lib/fuse_lowlevel.cpp +++ b/libfuse/lib/fuse_lowlevel.cpp @@ -280,6 +280,11 @@ fill_open(struct fuse_open_out *arg_, arg_->open_flags |= FOPEN_PARALLEL_DIRECT_WRITES; if(ffi_->noflush) arg_->open_flags |= FOPEN_NOFLUSH; + if(ffi_->passthrough) + { + arg_->open_flags |= FOPEN_PASSTHROUGH; + arg_->backing_id = ffi_->backing_id; + } } int @@ -1194,6 +1199,12 @@ do_init(fuse_req_t req, f->conn.capable |= FUSE_CAP_DIRECT_IO_ALLOW_MMAP; if(inargflags & FUSE_CREATE_SUPP_GROUP) f->conn.capable |= FUSE_CAP_CREATE_SUPP_GROUP; + if(inargflags & FUSE_PASSTHROUGH) + f->conn.capable |= FUSE_CAP_PASSTHROUGH; + if(inargflags & FUSE_HANDLE_KILLPRIV) + f->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV; + if(inargflags & FUSE_HANDLE_KILLPRIV_V2) + f->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV_V2; } else { @@ -1267,6 +1278,15 @@ do_init(fuse_req_t req, outargflags |= FUSE_CREATE_SUPP_GROUP; if(f->conn.want & FUSE_CAP_DIRECT_IO_ALLOW_MMAP) outargflags |= FUSE_DIRECT_IO_ALLOW_MMAP; + if(f->conn.want & FUSE_CAP_HANDLE_KILLPRIV) + outargflags |= FUSE_HANDLE_KILLPRIV; + if(f->conn.want & FUSE_CAP_HANDLE_KILLPRIV_V2) + outargflags |= FUSE_HANDLE_KILLPRIV_V2; + if(f->conn.want & FUSE_CAP_PASSTHROUGH) + { + outargflags |= FUSE_PASSTHROUGH; + outarg.max_stack_depth = 2; + } if(inargflags & FUSE_INIT_EXT) { @@ -1943,11 +1963,14 @@ fuse_ll_buf_process_read(struct fuse_session *se_, if(req == NULL) return fuse_send_enomem(se_->f,se_->ch,in->unique); - req->unique = in->unique; - req->ctx.uid = in->uid; - req->ctx.gid = in->gid; - req->ctx.pid = in->pid; - req->ch = se_->ch; + req->unique = in->unique; + req->ctx.opcode = in->opcode; + req->ctx.unique = in->unique; + req->ctx.nodeid = in->nodeid; + req->ctx.uid = in->uid; + req->ctx.gid = in->gid; + req->ctx.pid = in->pid; + req->ch = se_->ch; err = ENOSYS; if(in->opcode >= FUSE_MAXOPS) @@ -1979,11 +2002,14 @@ fuse_ll_buf_process_read_init(struct fuse_session *se_, if(req == NULL) return fuse_send_enomem(se_->f,se_->ch,in->unique); - req->unique = in->unique; - req->ctx.uid = in->uid; - req->ctx.gid = in->gid; - req->ctx.pid = in->pid; - req->ch = se_->ch; + req->unique = in->unique; + req->ctx.opcode = in->opcode; + req->ctx.unique = in->unique; + req->ctx.nodeid = in->nodeid; + req->ctx.uid = in->uid; + req->ctx.gid = in->gid; + req->ctx.pid = in->pid; + req->ch = se_->ch; err = EIO; if(in->opcode != FUSE_INIT) diff --git a/libfuse/lib/ghc/filesystem.hpp b/libfuse/lib/ghc/filesystem.hpp deleted file mode 100644 index 9540b440..00000000 --- a/libfuse/lib/ghc/filesystem.hpp +++ /dev/null @@ -1,6049 +0,0 @@ -//--------------------------------------------------------------------------------------- -// -// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14/C++17/C++20 -// -//--------------------------------------------------------------------------------------- -// -// Copyright (c) 2018, Steffen Schümann -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//--------------------------------------------------------------------------------------- -// -// To dynamically select std::filesystem where available on most platforms, -// you could use: -// -// #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include) -// #if __has_include() && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) -// #define GHC_USE_STD_FS -// #include -// namespace fs = std::filesystem; -// #endif -// #endif -// #ifndef GHC_USE_STD_FS -// #include -// namespace fs = ghc::filesystem; -// #endif -// -//--------------------------------------------------------------------------------------- -#ifndef GHC_FILESYSTEM_H -#define GHC_FILESYSTEM_H - -// #define BSD manifest constant only in -// sys/param.h -#ifndef _WIN32 -#include -#endif - -#ifndef GHC_OS_DETECTED -#if defined(__APPLE__) && defined(__MACH__) -#define GHC_OS_MACOS -#elif defined(__linux__) -#define GHC_OS_LINUX -#if defined(__ANDROID__) -#define GHC_OS_ANDROID -#endif -#elif defined(_WIN64) -#define GHC_OS_WINDOWS -#define GHC_OS_WIN64 -#elif defined(_WIN32) -#define GHC_OS_WINDOWS -#define GHC_OS_WIN32 -#elif defined(__CYGWIN__) -#define GHC_OS_CYGWIN -#elif defined(__sun) && defined(__SVR4) -#define GHC_OS_SOLARIS -#elif defined(__svr4__) -#define GHC_OS_SYS5R4 -#elif defined(BSD) -#define GHC_OS_BSD -#elif defined(__EMSCRIPTEN__) -#define GHC_OS_WEB -#include -#elif defined(__QNX__) -#define GHC_OS_QNX -#else -#error "Operating system currently not supported!" -#endif -#define GHC_OS_DETECTED -#if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -#if _MSVC_LANG == 201703L -#define GHC_FILESYSTEM_RUNNING_CPP17 -#else -#define GHC_FILESYSTEM_RUNNING_CPP20 -#endif -#elif (defined(__cplusplus) && __cplusplus >= 201703L) -#if __cplusplus == 201703L -#define GHC_FILESYSTEM_RUNNING_CPP17 -#else -#define GHC_FILESYSTEM_RUNNING_CPP20 -#endif -#endif -#endif - -#if defined(GHC_FILESYSTEM_IMPLEMENTATION) -#define GHC_EXPAND_IMPL -#define GHC_INLINE -#ifdef GHC_OS_WINDOWS -#ifndef GHC_FS_API -#define GHC_FS_API -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#else -#ifndef GHC_FS_API -#define GHC_FS_API __attribute__((visibility("default"))) -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS __attribute__((visibility("default"))) -#endif -#endif -#elif defined(GHC_FILESYSTEM_FWD) -#define GHC_INLINE -#ifdef GHC_OS_WINDOWS -#ifndef GHC_FS_API -#define GHC_FS_API extern -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#else -#ifndef GHC_FS_API -#define GHC_FS_API extern -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#endif -#else -#define GHC_EXPAND_IMPL -#define GHC_INLINE inline -#ifndef GHC_FS_API -#define GHC_FS_API -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#endif - -#ifdef GHC_EXPAND_IMPL - -#ifdef GHC_OS_WINDOWS -#include -// additional includes -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef GHC_OS_ANDROID -#include -#if __ANDROID_API__ < 12 -#include -#endif -#include -#define statvfs statfs -#else -#include -#endif -#ifdef GHC_OS_CYGWIN -#include -#endif -#if !defined(__ANDROID__) || __ANDROID_API__ >= 26 -#include -#endif -#endif -#ifdef GHC_OS_MACOS -#include -#endif - -#if defined(__cpp_impl_three_way_comparison) && defined(__has_include) -#if __has_include() -#define GHC_HAS_THREEWAY_COMP -#include -#endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#else // GHC_EXPAND_IMPL - -#if defined(__cpp_impl_three_way_comparison) && defined(__has_include) -#if __has_include() -#define GHC_HAS_THREEWAY_COMP -#include -#endif -#endif -#include -#include -#include -#include -#include -#include -#include -#ifdef GHC_OS_WINDOWS -#include -#endif -#endif // GHC_EXPAND_IMPL - -// After standard library includes. -// Standard library support for std::string_view. -#if defined(__cpp_lib_string_view) -#define GHC_HAS_STD_STRING_VIEW -#elif defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 4000) && (__cplusplus >= 201402) -#define GHC_HAS_STD_STRING_VIEW -#elif defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE >= 7) && (__cplusplus >= 201703) -#define GHC_HAS_STD_STRING_VIEW -#elif defined(_MSC_VER) && (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) -#define GHC_HAS_STD_STRING_VIEW -#endif - -// Standard library support for std::experimental::string_view. -#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 3700 && _LIBCPP_VERSION < 7000) && (__cplusplus >= 201402) -#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW -#elif defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)) && (__cplusplus >= 201402) -#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW -#elif defined(__GLIBCXX__) && defined(_GLIBCXX_USE_DUAL_ABI) && (__cplusplus >= 201402) -// macro _GLIBCXX_USE_DUAL_ABI is always defined in libstdc++ from gcc-5 and newer -#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW -#endif - -#if defined(GHC_HAS_STD_STRING_VIEW) -#include -#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) -#include -#endif - -#if !defined(GHC_OS_WINDOWS) && !defined(PATH_MAX) -#define PATH_MAX 4096 -#endif - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Behaviour Switches (see README.md, should match the config in test/filesystem_test.cpp): -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Enforce C++17 API where possible when compiling for C++20, handles the following cases: -// * fs::path::u8string() returns std::string instead of std::u8string -// #define GHC_FILESYSTEM_ENFORCE_CPP17_API -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2682 disables the since then invalid use of the copy option create_symlinks on directories -// configure LWG conformance () -#define LWG_2682_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2395 makes crate_directory/create_directories not emit an error if there is a regular -// file with that name, it is superseded by P1164R1, so only activate if really needed -// #define LWG_2935_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2936 enables new element wise (more expensive) path comparison -// * if this->root_name().native().compare(p.root_name().native()) != 0 return result -// * if this->has_root_directory() and !p.has_root_directory() return -1 -// * if !this->has_root_directory() and p.has_root_directory() return -1 -// * else result of element wise comparison of path iteration where first comparison is != 0 or 0 -// if all comparisons are 0 (on Windows this implementation does case-insensitive root_name() -// comparison) -#define LWG_2936_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2937 enforces that fs::equivalent emits an error, if !fs::exists(p1)||!exists(p2) -#define LWG_2937_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// UTF8-Everywhere is the original behaviour of ghc::filesystem. But since v1.5 the Windows -// version defaults to std::wstring storage backend. Still all std::string will be interpreted -// as UTF-8 encoded. With this define you can enforce the old behavior on Windows, using -// std::string as backend and for fs::path::native() and char for fs::path::c_str(). This -// needs more conversions, so it is (and was before v1.5) slower, bot might help keeping source -// homogeneous in a multi-platform project. -// #define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Raise errors/exceptions when invalid unicode codepoints or UTF-8 sequences are found, -// instead of replacing them with the unicode replacement character (U+FFFD). -// #define GHC_RAISE_UNICODE_ERRORS -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Automatic prefix windows path with "\\?\" if they would break the MAX_PATH length. -// instead of replacing them with the unicode replacement character (U+FFFD). -#ifndef GHC_WIN_DISABLE_AUTO_PREFIXES -#define GHC_WIN_AUTO_PREFIX_LONG_PATH -#endif // GHC_WIN_DISABLE_AUTO_PREFIXES -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch) -#define GHC_FILESYSTEM_VERSION 10512L - -#if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)) -#define GHC_WITH_EXCEPTIONS -#endif -#if !defined(GHC_WITH_EXCEPTIONS) && defined(GHC_RAISE_UNICODE_ERRORS) -#error "Can't raise unicode errors with exception support disabled" -#endif - -namespace ghc { -namespace filesystem { - -#if defined(GHC_HAS_CUSTOM_STRING_VIEW) -#define GHC_WITH_STRING_VIEW -#elif defined(GHC_HAS_STD_STRING_VIEW) -#define GHC_WITH_STRING_VIEW -using std::basic_string_view; -#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) -#define GHC_WITH_STRING_VIEW -using std::experimental::basic_string_view; -#endif - -// temporary existing exception type for yet unimplemented parts -class GHC_FS_API_CLASS not_implemented_exception : public std::logic_error -{ -public: - not_implemented_exception() - : std::logic_error("function not implemented yet.") - { - } -}; - -template -class path_helper_base -{ -public: - using value_type = char_type; -#ifdef GHC_OS_WINDOWS - static constexpr value_type preferred_separator = '\\'; -#else - static constexpr value_type preferred_separator = '/'; -#endif -}; - -#if __cplusplus < 201703L -template -constexpr char_type path_helper_base::preferred_separator; -#endif - -#ifdef GHC_OS_WINDOWS -class path; -namespace detail { -bool has_executable_extension(const path& p); -} -#endif - -// [fs.class.path] class path -class GHC_FS_API_CLASS path -#if defined(GHC_OS_WINDOWS) && !defined(GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) -#define GHC_USE_WCHAR_T -#define GHC_NATIVEWP(p) p.c_str() -#define GHC_PLATFORM_LITERAL(str) L##str - : private path_helper_base -{ -public: - using path_helper_base::value_type; -#else -#define GHC_NATIVEWP(p) p.wstring().c_str() -#define GHC_PLATFORM_LITERAL(str) str - : private path_helper_base -{ -public: - using path_helper_base::value_type; -#endif - using string_type = std::basic_string; - using path_helper_base::preferred_separator; - - // [fs.enum.path.format] enumeration format - /// The path format in which the constructor argument is given. - enum format { - generic_format, ///< The generic format, internally used by - ///< ghc::filesystem::path with slashes - native_format, ///< The format native to the current platform this code - ///< is build for - auto_format, ///< Try to auto-detect the format, fallback to native - }; - - template - struct _is_basic_string : std::false_type - { - }; - template - struct _is_basic_string> : std::true_type - { - }; - template - struct _is_basic_string, std::allocator>> : std::true_type - { - }; -#ifdef GHC_WITH_STRING_VIEW - template - struct _is_basic_string> : std::true_type - { - }; - template - struct _is_basic_string>> : std::true_type - { - }; -#endif - - template - using path_type = typename std::enable_if::value, path>::type; - template -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) - using path_from_string = - typename std::enable_if<_is_basic_string::value || std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value, - path>::type; - template - using path_type_EcharT = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value, path>::type; -#else - using path_from_string = - typename std::enable_if<_is_basic_string::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value, - path>::type; - template - using path_type_EcharT = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value, path>::type; -#endif - // [fs.path.construct] constructors and destructor - path() noexcept; - path(const path& p); - path(path&& p) noexcept; - path(string_type&& source, format fmt = auto_format); - template > - path(const Source& source, format fmt = auto_format); - template - path(InputIterator first, InputIterator last, format fmt = auto_format); -#ifdef GHC_WITH_EXCEPTIONS - template > - path(const Source& source, const std::locale& loc, format fmt = auto_format); - template - path(InputIterator first, InputIterator last, const std::locale& loc, format fmt = auto_format); -#endif - ~path(); - - // [fs.path.assign] assignments - path& operator=(const path& p); - path& operator=(path&& p) noexcept; - path& operator=(string_type&& source); - path& assign(string_type&& source); - template - path& operator=(const Source& source); - template - path& assign(const Source& source); - template - path& assign(InputIterator first, InputIterator last); - - // [fs.path.append] appends - path& operator/=(const path& p); - template - path& operator/=(const Source& source); - template - path& append(const Source& source); - template - path& append(InputIterator first, InputIterator last); - - // [fs.path.concat] concatenation - path& operator+=(const path& x); - path& operator+=(const string_type& x); -#ifdef GHC_WITH_STRING_VIEW - path& operator+=(basic_string_view x); -#endif - path& operator+=(const value_type* x); - path& operator+=(value_type x); - template - path_from_string& operator+=(const Source& x); - template - path_type_EcharT& operator+=(EcharT x); - template - path& concat(const Source& x); - template - path& concat(InputIterator first, InputIterator last); - - // [fs.path.modifiers] modifiers - void clear() noexcept; - path& make_preferred(); - path& remove_filename(); - path& replace_filename(const path& replacement); - path& replace_extension(const path& replacement = path()); - void swap(path& rhs) noexcept; - - // [fs.path.native.obs] native format observers - const string_type& native() const noexcept; - const value_type* c_str() const noexcept; - operator string_type() const; - template , class Allocator = std::allocator> - std::basic_string string(const Allocator& a = Allocator()) const; - std::string string() const; - std::wstring wstring() const; -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) - std::u8string u8string() const; -#else - std::string u8string() const; -#endif - std::u16string u16string() const; - std::u32string u32string() const; - - // [fs.path.generic.obs] generic format observers - template , class Allocator = std::allocator> - std::basic_string generic_string(const Allocator& a = Allocator()) const; - std::string generic_string() const; - std::wstring generic_wstring() const; -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) - std::u8string generic_u8string() const; -#else - std::string generic_u8string() const; -#endif - std::u16string generic_u16string() const; - std::u32string generic_u32string() const; - - // [fs.path.compare] compare - int compare(const path& p) const noexcept; - int compare(const string_type& s) const; -#ifdef GHC_WITH_STRING_VIEW - int compare(basic_string_view s) const; -#endif - int compare(const value_type* s) const; - - // [fs.path.decompose] decomposition - path root_name() const; - path root_directory() const; - path root_path() const; - path relative_path() const; - path parent_path() const; - path filename() const; - path stem() const; - path extension() const; - - // [fs.path.query] query - bool empty() const noexcept; - bool has_root_name() const; - bool has_root_directory() const; - bool has_root_path() const; - bool has_relative_path() const; - bool has_parent_path() const; - bool has_filename() const; - bool has_stem() const; - bool has_extension() const; - bool is_absolute() const; - bool is_relative() const; - - // [fs.path.gen] generation - path lexically_normal() const; - path lexically_relative(const path& base) const; - path lexically_proximate(const path& base) const; - - // [fs.path.itr] iterators - class iterator; - using const_iterator = iterator; - iterator begin() const; - iterator end() const; - -private: - using impl_value_type = value_type; - using impl_string_type = std::basic_string; - friend class directory_iterator; - void append_name(const value_type* name); - static constexpr impl_value_type generic_separator = '/'; - template - class input_iterator_range - { - public: - typedef InputIterator iterator; - typedef InputIterator const_iterator; - typedef typename InputIterator::difference_type difference_type; - - input_iterator_range(const InputIterator& first, const InputIterator& last) - : _first(first) - , _last(last) - { - } - - InputIterator begin() const { return _first; } - InputIterator end() const { return _last; } - - private: - InputIterator _first; - InputIterator _last; - }; - friend void swap(path& lhs, path& rhs) noexcept; - friend size_t hash_value(const path& p) noexcept; - friend path canonical(const path& p, std::error_code& ec); - friend bool create_directories(const path& p, std::error_code& ec) noexcept; - string_type::size_type root_name_length() const noexcept; - void postprocess_path_with_format(format fmt); - void check_long_path(); - impl_string_type _path; -#ifdef GHC_OS_WINDOWS - void handle_prefixes(); - friend bool detail::has_executable_extension(const path& p); -#ifdef GHC_WIN_AUTO_PREFIX_LONG_PATH - string_type::size_type _prefixLength{0}; -#else // GHC_WIN_AUTO_PREFIX_LONG_PATH - static const string_type::size_type _prefixLength{0}; -#endif // GHC_WIN_AUTO_PREFIX_LONG_PATH -#else - static const string_type::size_type _prefixLength{0}; -#endif -}; - -// [fs.path.nonmember] path non-member functions -GHC_FS_API void swap(path& lhs, path& rhs) noexcept; -GHC_FS_API size_t hash_value(const path& p) noexcept; -#ifdef GHC_HAS_THREEWAY_COMP -GHC_FS_API std::strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept; -#endif -GHC_FS_API bool operator==(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator!=(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator<(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator<=(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator>(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator>=(const path& lhs, const path& rhs) noexcept; -GHC_FS_API path operator/(const path& lhs, const path& rhs); - -// [fs.path.io] path inserter and extractor -template -std::basic_ostream& operator<<(std::basic_ostream& os, const path& p); -template -std::basic_istream& operator>>(std::basic_istream& is, path& p); - -// [pfs.path.factory] path factory functions -template > -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -[[deprecated("use ghc::filesystem::path::path() with std::u8string instead")]] -#endif -path u8path(const Source& source); -template -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -[[deprecated("use ghc::filesystem::path::path() with std::u8string instead")]] -#endif -path u8path(InputIterator first, InputIterator last); - -// [fs.class.filesystem_error] class filesystem_error -class GHC_FS_API_CLASS filesystem_error : public std::system_error -{ -public: - filesystem_error(const std::string& what_arg, std::error_code ec); - filesystem_error(const std::string& what_arg, const path& p1, std::error_code ec); - filesystem_error(const std::string& what_arg, const path& p1, const path& p2, std::error_code ec); - const path& path1() const noexcept; - const path& path2() const noexcept; - const char* what() const noexcept override; - -private: - std::string _what_arg; - std::error_code _ec; - path _p1, _p2; -}; - -class GHC_FS_API_CLASS path::iterator -{ -public: - using value_type = const path; - using difference_type = std::ptrdiff_t; - using pointer = const path*; - using reference = const path&; - using iterator_category = std::bidirectional_iterator_tag; - - iterator(); - iterator(const path& p, const impl_string_type::const_iterator& pos); - iterator& operator++(); - iterator operator++(int); - iterator& operator--(); - iterator operator--(int); - bool operator==(const iterator& other) const; - bool operator!=(const iterator& other) const; - reference operator*() const; - pointer operator->() const; - -private: - friend class path; - impl_string_type::const_iterator increment(const impl_string_type::const_iterator& pos) const; - impl_string_type::const_iterator decrement(const impl_string_type::const_iterator& pos) const; - void updateCurrent(); - impl_string_type::const_iterator _first; - impl_string_type::const_iterator _last; - impl_string_type::const_iterator _prefix; - impl_string_type::const_iterator _root; - impl_string_type::const_iterator _iter; - path _current; -}; - -struct space_info -{ - uintmax_t capacity; - uintmax_t free; - uintmax_t available; -}; - -// [fs.enum] enumerations -// [fs.enum.file_type] -enum class file_type { - none, - not_found, - regular, - directory, - symlink, - block, - character, - fifo, - socket, - unknown, -}; - -// [fs.enum.perms] -enum class perms : uint16_t { - none = 0, - - owner_read = 0400, - owner_write = 0200, - owner_exec = 0100, - owner_all = 0700, - - group_read = 040, - group_write = 020, - group_exec = 010, - group_all = 070, - - others_read = 04, - others_write = 02, - others_exec = 01, - others_all = 07, - - all = 0777, - set_uid = 04000, - set_gid = 02000, - sticky_bit = 01000, - - mask = 07777, - unknown = 0xffff -}; - -// [fs.enum.perm.opts] -enum class perm_options : uint16_t { - replace = 3, - add = 1, - remove = 2, - nofollow = 4, -}; - -// [fs.enum.copy.opts] -enum class copy_options : uint16_t { - none = 0, - - skip_existing = 1, - overwrite_existing = 2, - update_existing = 4, - - recursive = 8, - - copy_symlinks = 0x10, - skip_symlinks = 0x20, - - directories_only = 0x40, - create_symlinks = 0x80, -#ifndef GHC_OS_WEB - create_hard_links = 0x100 -#endif -}; - -// [fs.enum.dir.opts] -enum class directory_options : uint16_t { - none = 0, - follow_directory_symlink = 1, - skip_permission_denied = 2, -}; - -// [fs.class.file_status] class file_status -class GHC_FS_API_CLASS file_status -{ -public: - // [fs.file_status.cons] constructors and destructor - file_status() noexcept; - explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; - file_status(const file_status&) noexcept; - file_status(file_status&&) noexcept; - ~file_status(); - // assignments: - file_status& operator=(const file_status&) noexcept; - file_status& operator=(file_status&&) noexcept; - // [fs.file_status.mods] modifiers - void type(file_type ft) noexcept; - void permissions(perms prms) noexcept; - // [fs.file_status.obs] observers - file_type type() const noexcept; - perms permissions() const noexcept; - friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } - -private: - file_type _type; - perms _perms; -}; - -using file_time_type = std::chrono::time_point; - -// [fs.class.directory_entry] Class directory_entry -class GHC_FS_API_CLASS directory_entry -{ -public: - // [fs.dir.entry.cons] constructors and destructor - directory_entry() noexcept = default; - directory_entry(const directory_entry&) = default; - directory_entry(directory_entry&&) noexcept = default; -#ifdef GHC_WITH_EXCEPTIONS - explicit directory_entry(const path& p); -#endif - directory_entry(const path& p, std::error_code& ec); - ~directory_entry(); - - // assignments: - directory_entry& operator=(const directory_entry&) = default; - directory_entry& operator=(directory_entry&&) noexcept = default; - - // [fs.dir.entry.mods] modifiers -#ifdef GHC_WITH_EXCEPTIONS - void assign(const path& p); - void replace_filename(const path& p); - void refresh(); -#endif - void assign(const path& p, std::error_code& ec); - void replace_filename(const path& p, std::error_code& ec); - void refresh(std::error_code& ec) noexcept; - - // [fs.dir.entry.obs] observers - const filesystem::path& path() const noexcept; - operator const filesystem::path&() const noexcept; -#ifdef GHC_WITH_EXCEPTIONS - bool exists() const; - bool is_block_file() const; - bool is_character_file() const; - bool is_directory() const; - bool is_fifo() const; - bool is_other() const; - bool is_regular_file() const; - bool is_socket() const; - bool is_symlink() const; - uintmax_t file_size() const; - file_time_type last_write_time() const; - file_status status() const; - file_status symlink_status() const; -#endif - bool exists(std::error_code& ec) const noexcept; - bool is_block_file(std::error_code& ec) const noexcept; - bool is_character_file(std::error_code& ec) const noexcept; - bool is_directory(std::error_code& ec) const noexcept; - bool is_fifo(std::error_code& ec) const noexcept; - bool is_other(std::error_code& ec) const noexcept; - bool is_regular_file(std::error_code& ec) const noexcept; - bool is_socket(std::error_code& ec) const noexcept; - bool is_symlink(std::error_code& ec) const noexcept; - uintmax_t file_size(std::error_code& ec) const noexcept; - file_time_type last_write_time(std::error_code& ec) const noexcept; - file_status status(std::error_code& ec) const noexcept; - file_status symlink_status(std::error_code& ec) const noexcept; - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS - uintmax_t hard_link_count() const; -#endif - uintmax_t hard_link_count(std::error_code& ec) const noexcept; -#endif - -#ifdef GHC_HAS_THREEWAY_COMP - std::strong_ordering operator<=>(const directory_entry& rhs) const noexcept; -#endif - bool operator<(const directory_entry& rhs) const noexcept; - bool operator==(const directory_entry& rhs) const noexcept; - bool operator!=(const directory_entry& rhs) const noexcept; - bool operator<=(const directory_entry& rhs) const noexcept; - bool operator>(const directory_entry& rhs) const noexcept; - bool operator>=(const directory_entry& rhs) const noexcept; - -private: - friend class directory_iterator; -#ifdef GHC_WITH_EXCEPTIONS - file_type status_file_type() const; -#endif - file_type status_file_type(std::error_code& ec) const noexcept; - filesystem::path _path; - file_status _status; - file_status _symlink_status; - uintmax_t _file_size = static_cast(-1); -#ifndef GHC_OS_WINDOWS - uintmax_t _hard_link_count = static_cast(-1); -#endif - time_t _last_write_time = 0; -}; - -// [fs.class.directory.iterator] Class directory_iterator -class GHC_FS_API_CLASS directory_iterator -{ -public: - class GHC_FS_API_CLASS proxy - { - public: - const directory_entry& operator*() const& noexcept { return _dir_entry; } - directory_entry operator*() && noexcept { return std::move(_dir_entry); } - - private: - explicit proxy(const directory_entry& dir_entry) - : _dir_entry(dir_entry) - { - } - friend class directory_iterator; - friend class recursive_directory_iterator; - directory_entry _dir_entry; - }; - using iterator_category = std::input_iterator_tag; - using value_type = directory_entry; - using difference_type = std::ptrdiff_t; - using pointer = const directory_entry*; - using reference = const directory_entry&; - - // [fs.dir.itr.members] member functions - directory_iterator() noexcept; -#ifdef GHC_WITH_EXCEPTIONS - explicit directory_iterator(const path& p); - directory_iterator(const path& p, directory_options options); -#endif - directory_iterator(const path& p, std::error_code& ec) noexcept; - directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept; - directory_iterator(const directory_iterator& rhs); - directory_iterator(directory_iterator&& rhs) noexcept; - ~directory_iterator(); - directory_iterator& operator=(const directory_iterator& rhs); - directory_iterator& operator=(directory_iterator&& rhs) noexcept; - const directory_entry& operator*() const; - const directory_entry* operator->() const; -#ifdef GHC_WITH_EXCEPTIONS - directory_iterator& operator++(); -#endif - directory_iterator& increment(std::error_code& ec) noexcept; - - // other members as required by [input.iterators] -#ifdef GHC_WITH_EXCEPTIONS - proxy operator++(int) - { - proxy p{**this}; - ++*this; - return p; - } -#endif - bool operator==(const directory_iterator& rhs) const; - bool operator!=(const directory_iterator& rhs) const; - -private: - friend class recursive_directory_iterator; - class impl; - std::shared_ptr _impl; -}; - -// [fs.dir.itr.nonmembers] directory_iterator non-member functions -GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept; -GHC_FS_API directory_iterator end(const directory_iterator&) noexcept; - -// [fs.class.re.dir.itr] class recursive_directory_iterator -class GHC_FS_API_CLASS recursive_directory_iterator -{ -public: - using iterator_category = std::input_iterator_tag; - using value_type = directory_entry; - using difference_type = std::ptrdiff_t; - using pointer = const directory_entry*; - using reference = const directory_entry&; - - // [fs.rec.dir.itr.members] constructors and destructor - recursive_directory_iterator() noexcept; -#ifdef GHC_WITH_EXCEPTIONS - explicit recursive_directory_iterator(const path& p); - recursive_directory_iterator(const path& p, directory_options options); -#endif - recursive_directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept; - recursive_directory_iterator(const path& p, std::error_code& ec) noexcept; - recursive_directory_iterator(const recursive_directory_iterator& rhs); - recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; - ~recursive_directory_iterator(); - - // [fs.rec.dir.itr.members] observers - directory_options options() const; - int depth() const; - bool recursion_pending() const; - - const directory_entry& operator*() const; - const directory_entry* operator->() const; - - // [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& - recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs); - recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept; -#ifdef GHC_WITH_EXCEPTIONS - recursive_directory_iterator& operator++(); -#endif - recursive_directory_iterator& increment(std::error_code& ec) noexcept; - -#ifdef GHC_WITH_EXCEPTIONS - void pop(); -#endif - void pop(std::error_code& ec); - void disable_recursion_pending(); - - // other members as required by [input.iterators] -#ifdef GHC_WITH_EXCEPTIONS - directory_iterator::proxy operator++(int) - { - directory_iterator::proxy proxy{**this}; - ++*this; - return proxy; - } -#endif - bool operator==(const recursive_directory_iterator& rhs) const; - bool operator!=(const recursive_directory_iterator& rhs) const; - -private: - struct recursive_directory_iterator_impl - { - directory_options _options; - bool _recursion_pending; - std::stack _dir_iter_stack; - recursive_directory_iterator_impl(directory_options options, bool recursion_pending) - : _options(options) - , _recursion_pending(recursion_pending) - { - } - }; - std::shared_ptr _impl; -}; - -// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions -GHC_FS_API recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; -GHC_FS_API recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; - -// [fs.op.funcs] filesystem operations -#ifdef GHC_WITH_EXCEPTIONS -GHC_FS_API path absolute(const path& p); -GHC_FS_API path canonical(const path& p); -GHC_FS_API void copy(const path& from, const path& to); -GHC_FS_API void copy(const path& from, const path& to, copy_options options); -GHC_FS_API bool copy_file(const path& from, const path& to); -GHC_FS_API bool copy_file(const path& from, const path& to, copy_options option); -GHC_FS_API void copy_symlink(const path& existing_symlink, const path& new_symlink); -GHC_FS_API bool create_directories(const path& p); -GHC_FS_API bool create_directory(const path& p); -GHC_FS_API bool create_directory(const path& p, const path& attributes); -GHC_FS_API void create_directory_symlink(const path& to, const path& new_symlink); -GHC_FS_API void create_symlink(const path& to, const path& new_symlink); -GHC_FS_API path current_path(); -GHC_FS_API void current_path(const path& p); -GHC_FS_API bool exists(const path& p); -GHC_FS_API bool equivalent(const path& p1, const path& p2); -GHC_FS_API uintmax_t file_size(const path& p); -GHC_FS_API bool is_block_file(const path& p); -GHC_FS_API bool is_character_file(const path& p); -GHC_FS_API bool is_directory(const path& p); -GHC_FS_API bool is_empty(const path& p); -GHC_FS_API bool is_fifo(const path& p); -GHC_FS_API bool is_other(const path& p); -GHC_FS_API bool is_regular_file(const path& p); -GHC_FS_API bool is_socket(const path& p); -GHC_FS_API bool is_symlink(const path& p); -GHC_FS_API file_time_type last_write_time(const path& p); -GHC_FS_API void last_write_time(const path& p, file_time_type new_time); -GHC_FS_API void permissions(const path& p, perms prms, perm_options opts = perm_options::replace); -GHC_FS_API path proximate(const path& p, const path& base = current_path()); -GHC_FS_API path read_symlink(const path& p); -GHC_FS_API path relative(const path& p, const path& base = current_path()); -GHC_FS_API bool remove(const path& p); -GHC_FS_API uintmax_t remove_all(const path& p); -GHC_FS_API void rename(const path& from, const path& to); -GHC_FS_API void resize_file(const path& p, uintmax_t size); -GHC_FS_API space_info space(const path& p); -GHC_FS_API file_status status(const path& p); -GHC_FS_API file_status symlink_status(const path& p); -GHC_FS_API path temp_directory_path(); -GHC_FS_API path weakly_canonical(const path& p); -#endif -GHC_FS_API path absolute(const path& p, std::error_code& ec); -GHC_FS_API path canonical(const path& p, std::error_code& ec); -GHC_FS_API void copy(const path& from, const path& to, std::error_code& ec) noexcept; -GHC_FS_API void copy(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept; -GHC_FS_API bool copy_file(const path& from, const path& to, std::error_code& ec) noexcept; -GHC_FS_API bool copy_file(const path& from, const path& to, copy_options option, std::error_code& ec) noexcept; -GHC_FS_API void copy_symlink(const path& existing_symlink, const path& new_symlink, std::error_code& ec) noexcept; -GHC_FS_API bool create_directories(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool create_directory(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool create_directory(const path& p, const path& attributes, std::error_code& ec) noexcept; -GHC_FS_API void create_directory_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept; -GHC_FS_API void create_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept; -GHC_FS_API path current_path(std::error_code& ec); -GHC_FS_API void current_path(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool exists(file_status s) noexcept; -GHC_FS_API bool exists(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool equivalent(const path& p1, const path& p2, std::error_code& ec) noexcept; -GHC_FS_API uintmax_t file_size(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_block_file(file_status s) noexcept; -GHC_FS_API bool is_block_file(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_character_file(file_status s) noexcept; -GHC_FS_API bool is_character_file(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_directory(file_status s) noexcept; -GHC_FS_API bool is_directory(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_empty(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_fifo(file_status s) noexcept; -GHC_FS_API bool is_fifo(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_other(file_status s) noexcept; -GHC_FS_API bool is_other(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_regular_file(file_status s) noexcept; -GHC_FS_API bool is_regular_file(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_socket(file_status s) noexcept; -GHC_FS_API bool is_socket(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_symlink(file_status s) noexcept; -GHC_FS_API bool is_symlink(const path& p, std::error_code& ec) noexcept; -GHC_FS_API file_time_type last_write_time(const path& p, std::error_code& ec) noexcept; -GHC_FS_API void last_write_time(const path& p, file_time_type new_time, std::error_code& ec) noexcept; -GHC_FS_API void permissions(const path& p, perms prms, std::error_code& ec) noexcept; -GHC_FS_API void permissions(const path& p, perms prms, perm_options opts, std::error_code& ec) noexcept; -GHC_FS_API path proximate(const path& p, std::error_code& ec); -GHC_FS_API path proximate(const path& p, const path& base, std::error_code& ec); -GHC_FS_API path read_symlink(const path& p, std::error_code& ec); -GHC_FS_API path relative(const path& p, std::error_code& ec); -GHC_FS_API path relative(const path& p, const path& base, std::error_code& ec); -GHC_FS_API bool remove(const path& p, std::error_code& ec) noexcept; -GHC_FS_API uintmax_t remove_all(const path& p, std::error_code& ec) noexcept; -GHC_FS_API void rename(const path& from, const path& to, std::error_code& ec) noexcept; -GHC_FS_API void resize_file(const path& p, uintmax_t size, std::error_code& ec) noexcept; -GHC_FS_API space_info space(const path& p, std::error_code& ec) noexcept; -GHC_FS_API file_status status(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool status_known(file_status s) noexcept; -GHC_FS_API file_status symlink_status(const path& p, std::error_code& ec) noexcept; -GHC_FS_API path temp_directory_path(std::error_code& ec) noexcept; -GHC_FS_API path weakly_canonical(const path& p, std::error_code& ec) noexcept; - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_FS_API void create_hard_link(const path& to, const path& new_hard_link); -GHC_FS_API uintmax_t hard_link_count(const path& p); -#endif -GHC_FS_API void create_hard_link(const path& to, const path& new_hard_link, std::error_code& ec) noexcept; -GHC_FS_API uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept; -#endif - -// Non-C++17 add-on std::fstream wrappers with path -template > -class basic_filebuf : public std::basic_filebuf -{ -public: - basic_filebuf() {} - ~basic_filebuf() override {} - basic_filebuf(const basic_filebuf&) = delete; - const basic_filebuf& operator=(const basic_filebuf&) = delete; - basic_filebuf* open(const path& p, std::ios_base::openmode mode) - { -#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) - return std::basic_filebuf::open(p.wstring().c_str(), mode) ? this : 0; -#else - return std::basic_filebuf::open(p.string().c_str(), mode) ? this : 0; -#endif - } -}; - -template > -class basic_ifstream : public std::basic_ifstream -{ -public: - basic_ifstream() {} -#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) - explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in) - : std::basic_ifstream(p.wstring().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream::open(p.wstring().c_str(), mode); } -#else - explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in) - : std::basic_ifstream(p.string().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream::open(p.string().c_str(), mode); } -#endif - basic_ifstream(const basic_ifstream&) = delete; - const basic_ifstream& operator=(const basic_ifstream&) = delete; - ~basic_ifstream() override {} -}; - -template > -class basic_ofstream : public std::basic_ofstream -{ -public: - basic_ofstream() {} -#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) - explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out) - : std::basic_ofstream(p.wstring().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream::open(p.wstring().c_str(), mode); } -#else - explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out) - : std::basic_ofstream(p.string().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream::open(p.string().c_str(), mode); } -#endif - basic_ofstream(const basic_ofstream&) = delete; - const basic_ofstream& operator=(const basic_ofstream&) = delete; - ~basic_ofstream() override {} -}; - -template > -class basic_fstream : public std::basic_fstream -{ -public: - basic_fstream() {} -#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) - explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) - : std::basic_fstream(p.wstring().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream::open(p.wstring().c_str(), mode); } -#else - explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) - : std::basic_fstream(p.string().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream::open(p.string().c_str(), mode); } -#endif - basic_fstream(const basic_fstream&) = delete; - const basic_fstream& operator=(const basic_fstream&) = delete; - ~basic_fstream() override {} -}; - -typedef basic_filebuf filebuf; -typedef basic_filebuf wfilebuf; -typedef basic_ifstream ifstream; -typedef basic_ifstream wifstream; -typedef basic_ofstream ofstream; -typedef basic_ofstream wofstream; -typedef basic_fstream fstream; -typedef basic_fstream wfstream; - -class GHC_FS_API_CLASS u8arguments -{ -public: - u8arguments(int& argc, char**& argv); - ~u8arguments() - { - _refargc = _argc; - _refargv = _argv; - } - - bool valid() const { return _isvalid; } - -private: - int _argc; - char** _argv; - int& _refargc; - char**& _refargv; - bool _isvalid; -#ifdef GHC_OS_WINDOWS - std::vector _args; - std::vector _argp; -#endif -}; - -//------------------------------------------------------------------------------------------------- -// Implementation -//------------------------------------------------------------------------------------------------- - -namespace detail { -enum utf8_states_t { S_STRT = 0, S_RJCT = 8 }; -GHC_FS_API void appendUTF8(std::string& str, uint32_t unicode); -GHC_FS_API bool is_surrogate(uint32_t c); -GHC_FS_API bool is_high_surrogate(uint32_t c); -GHC_FS_API bool is_low_surrogate(uint32_t c); -GHC_FS_API unsigned consumeUtf8Fragment(const unsigned state, const uint8_t fragment, uint32_t& codepoint); -enum class portable_error { - none = 0, - exists, - not_found, - not_supported, - not_implemented, - invalid_argument, - is_a_directory, -}; -GHC_FS_API std::error_code make_error_code(portable_error err); -#ifdef GHC_OS_WINDOWS -GHC_FS_API std::error_code make_system_error(uint32_t err = 0); -#else -GHC_FS_API std::error_code make_system_error(int err = 0); - -template -struct has_d_type : std::false_type{}; - -template -struct has_d_type : std::true_type {}; - -template -GHC_INLINE file_type file_type_from_dirent_impl(const T&, std::false_type) -{ - return file_type::none; -} - -template -GHC_INLINE file_type file_type_from_dirent_impl(const T& t, std::true_type) -{ - switch (t.d_type) { -#ifdef DT_BLK - case DT_BLK: - return file_type::block; -#endif -#ifdef DT_CHR - case DT_CHR: - return file_type::character; -#endif -#ifdef DT_DIR - case DT_DIR: - return file_type::directory; -#endif -#ifdef DT_FIFO - case DT_FIFO: - return file_type::fifo; -#endif -#ifdef DT_LNK - case DT_LNK: - return file_type::symlink; -#endif -#ifdef DT_REG - case DT_REG: - return file_type::regular; -#endif -#ifdef DT_SOCK - case DT_SOCK: - return file_type::socket; -#endif -#ifdef DT_UNKNOWN - case DT_UNKNOWN: - return file_type::none; -#endif - default: - return file_type::unknown; - } -} - -template -GHC_INLINE file_type file_type_from_dirent(const T& t) -{ - return file_type_from_dirent_impl(t, has_d_type{}); -} -#endif -} // namespace detail - -namespace detail { - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE std::error_code make_error_code(portable_error err) -{ -#ifdef GHC_OS_WINDOWS - switch (err) { - case portable_error::none: - return std::error_code(); - case portable_error::exists: - return std::error_code(ERROR_ALREADY_EXISTS, std::system_category()); - case portable_error::not_found: - return std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()); - case portable_error::not_supported: - return std::error_code(ERROR_NOT_SUPPORTED, std::system_category()); - case portable_error::not_implemented: - return std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category()); - case portable_error::invalid_argument: - return std::error_code(ERROR_INVALID_PARAMETER, std::system_category()); - case portable_error::is_a_directory: -#ifdef ERROR_DIRECTORY_NOT_SUPPORTED - return std::error_code(ERROR_DIRECTORY_NOT_SUPPORTED, std::system_category()); -#else - return std::error_code(ERROR_NOT_SUPPORTED, std::system_category()); -#endif - } -#else - switch (err) { - case portable_error::none: - return std::error_code(); - case portable_error::exists: - return std::error_code(EEXIST, std::system_category()); - case portable_error::not_found: - return std::error_code(ENOENT, std::system_category()); - case portable_error::not_supported: - return std::error_code(ENOTSUP, std::system_category()); - case portable_error::not_implemented: - return std::error_code(ENOSYS, std::system_category()); - case portable_error::invalid_argument: - return std::error_code(EINVAL, std::system_category()); - case portable_error::is_a_directory: - return std::error_code(EISDIR, std::system_category()); - } -#endif - return std::error_code(); -} - -#ifdef GHC_OS_WINDOWS -GHC_INLINE std::error_code make_system_error(uint32_t err) -{ - return std::error_code(err ? static_cast(err) : static_cast(::GetLastError()), std::system_category()); -} -#else -GHC_INLINE std::error_code make_system_error(int err) -{ - return std::error_code(err ? err : errno, std::system_category()); -} -#endif - -#endif // GHC_EXPAND_IMPL - -template -using EnableBitmask = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value, Enum>::type; -} // namespace detail - -template -constexpr detail::EnableBitmask operator&(Enum X, Enum Y) -{ - using underlying = typename std::underlying_type::type; - return static_cast(static_cast(X) & static_cast(Y)); -} - -template -constexpr detail::EnableBitmask operator|(Enum X, Enum Y) -{ - using underlying = typename std::underlying_type::type; - return static_cast(static_cast(X) | static_cast(Y)); -} - -template -constexpr detail::EnableBitmask operator^(Enum X, Enum Y) -{ - using underlying = typename std::underlying_type::type; - return static_cast(static_cast(X) ^ static_cast(Y)); -} - -template -constexpr detail::EnableBitmask operator~(Enum X) -{ - using underlying = typename std::underlying_type::type; - return static_cast(~static_cast(X)); -} - -template -detail::EnableBitmask& operator&=(Enum& X, Enum Y) -{ - X = X & Y; - return X; -} - -template -detail::EnableBitmask& operator|=(Enum& X, Enum Y) -{ - X = X | Y; - return X; -} - -template -detail::EnableBitmask& operator^=(Enum& X, Enum Y) -{ - X = X ^ Y; - return X; -} - -#ifdef GHC_EXPAND_IMPL - -namespace detail { - -GHC_INLINE bool in_range(uint32_t c, uint32_t lo, uint32_t hi) -{ - return (static_cast(c - lo) < (hi - lo + 1)); -} - -GHC_INLINE bool is_surrogate(uint32_t c) -{ - return in_range(c, 0xd800, 0xdfff); -} - -GHC_INLINE bool is_high_surrogate(uint32_t c) -{ - return (c & 0xfffffc00) == 0xd800; -} - -GHC_INLINE bool is_low_surrogate(uint32_t c) -{ - return (c & 0xfffffc00) == 0xdc00; -} - -GHC_INLINE void appendUTF8(std::string& str, uint32_t unicode) -{ - if (unicode <= 0x7f) { - str.push_back(static_cast(unicode)); - } - else if (unicode >= 0x80 && unicode <= 0x7ff) { - str.push_back(static_cast((unicode >> 6) + 192)); - str.push_back(static_cast((unicode & 0x3f) + 128)); - } - else if ((unicode >= 0x800 && unicode <= 0xd7ff) || (unicode >= 0xe000 && unicode <= 0xffff)) { - str.push_back(static_cast((unicode >> 12) + 224)); - str.push_back(static_cast(((unicode & 0xfff) >> 6) + 128)); - str.push_back(static_cast((unicode & 0x3f) + 128)); - } - else if (unicode >= 0x10000 && unicode <= 0x10ffff) { - str.push_back(static_cast((unicode >> 18) + 240)); - str.push_back(static_cast(((unicode & 0x3ffff) >> 12) + 128)); - str.push_back(static_cast(((unicode & 0xfff) >> 6) + 128)); - str.push_back(static_cast((unicode & 0x3f) + 128)); - } - else { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal code point for unicode character.", str, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - appendUTF8(str, 0xfffd); -#endif - } -} - -// Thanks to Bjoern Hoehrmann (https://bjoern.hoehrmann.de/utf-8/decoder/dfa/) -// and Taylor R Campbell for the ideas to this DFA approach of UTF-8 decoding; -// Generating debugging and shrinking my own DFA from scratch was a day of fun! -GHC_INLINE unsigned consumeUtf8Fragment(const unsigned state, const uint8_t fragment, uint32_t& codepoint) -{ - static const uint32_t utf8_state_info[] = { - // encoded states - 0x11111111u, 0x11111111u, 0x77777777u, 0x77777777u, 0x88888888u, 0x88888888u, 0x88888888u, 0x88888888u, 0x22222299u, 0x22222222u, 0x22222222u, 0x22222222u, 0x3333333au, 0x33433333u, 0x9995666bu, 0x99999999u, - 0x88888880u, 0x22818108u, 0x88888881u, 0x88888882u, 0x88888884u, 0x88888887u, 0x88888886u, 0x82218108u, 0x82281108u, 0x88888888u, 0x88888883u, 0x88888885u, 0u, 0u, 0u, 0u, - }; - uint8_t category = fragment < 128 ? 0 : (utf8_state_info[(fragment >> 3) & 0xf] >> ((fragment & 7) << 2)) & 0xf; - codepoint = (state ? (codepoint << 6) | (fragment & 0x3fu) : (0xffu >> category) & fragment); - return state == S_RJCT ? static_cast(S_RJCT) : static_cast((utf8_state_info[category + 16] >> (state << 2)) & 0xf); -} - -GHC_INLINE bool validUtf8(const std::string& utf8String) -{ - std::string::const_iterator iter = utf8String.begin(); - unsigned utf8_state = S_STRT; - std::uint32_t codepoint = 0; - while (iter < utf8String.end()) { - if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_RJCT) { - return false; - } - } - if (utf8_state) { - return false; - } - return true; -} - -} // namespace detail - -#endif - -namespace detail { - -template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 1)>::type* = nullptr> -inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - return StringType(utf8String.begin(), utf8String.end(), alloc); -} - -template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 2)>::type* = nullptr> -inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - StringType result(alloc); - result.reserve(utf8String.length()); - auto iter = utf8String.cbegin(); - unsigned utf8_state = S_STRT; - std::uint32_t codepoint = 0; - while (iter < utf8String.cend()) { - if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_STRT) { - if (codepoint <= 0xffff) { - result += static_cast(codepoint); - } - else { - codepoint -= 0x10000; - result += static_cast((codepoint >> 10) + 0xd800); - result += static_cast((codepoint & 0x3ff) + 0xdc00); - } - codepoint = 0; - } - else if (utf8_state == S_RJCT) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); - utf8_state = S_STRT; - codepoint = 0; -#endif - } - } - if (utf8_state) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); -#endif - } - return result; -} - -template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 4)>::type* = nullptr> -inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - StringType result(alloc); - result.reserve(utf8String.length()); - auto iter = utf8String.cbegin(); - unsigned utf8_state = S_STRT; - std::uint32_t codepoint = 0; - while (iter < utf8String.cend()) { - if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_STRT) { - result += static_cast(codepoint); - codepoint = 0; - } - else if (utf8_state == S_RJCT) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); - utf8_state = S_STRT; - codepoint = 0; -#endif - } - } - if (utf8_state) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); -#endif - } - return result; -} - -template -inline StringType fromUtf8(const charT (&utf8String)[N]) -{ -#ifdef GHC_WITH_STRING_VIEW - return fromUtf8(basic_string_view(utf8String, N - 1)); -#else - return fromUtf8(std::basic_string(utf8String, N - 1)); -#endif -} - -template ::value && (sizeof(typename strT::value_type) == 1), int>::type size = 1> -inline std::string toUtf8(const strT& unicodeString) -{ - return std::string(unicodeString.begin(), unicodeString.end()); -} - -template ::value && (sizeof(typename strT::value_type) == 2), int>::type size = 2> -inline std::string toUtf8(const strT& unicodeString) -{ - std::string result; - for (auto iter = unicodeString.begin(); iter != unicodeString.end(); ++iter) { - char32_t c = *iter; - if (is_surrogate(c)) { - ++iter; - if (iter != unicodeString.end() && is_high_surrogate(c) && is_low_surrogate(*iter)) { - appendUTF8(result, (char32_t(c) << 10) + *iter - 0x35fdc00); - } - else { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal code point for unicode character.", result, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - appendUTF8(result, 0xfffd); - if (iter == unicodeString.end()) { - break; - } -#endif - } - } - else { - appendUTF8(result, c); - } - } - return result; -} - -template ::value && (sizeof(typename strT::value_type) == 4), int>::type size = 4> -inline std::string toUtf8(const strT& unicodeString) -{ - std::string result; - for (auto c : unicodeString) { - appendUTF8(result, static_cast(c)); - } - return result; -} - -template -inline std::string toUtf8(const charT* unicodeString) -{ -#ifdef GHC_WITH_STRING_VIEW - return toUtf8(basic_string_view>(unicodeString)); -#else - return toUtf8(std::basic_string>(unicodeString)); -#endif -} - -#ifdef GHC_USE_WCHAR_T -template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 1), bool>::type = false> -inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - auto temp = toUtf8(wString); - return StringType(temp.begin(), temp.end(), alloc); -} - -template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 2), bool>::type = false> -inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - return StringType(wString.begin(), wString.end(), alloc); -} - -template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 4), bool>::type = false> -inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - auto temp = toUtf8(wString); - return fromUtf8(temp, alloc); -} - -template ::value && (sizeof(typename strT::value_type) == 1), bool>::type = false> -inline std::wstring toWChar(const strT& unicodeString) -{ - return fromUtf8(unicodeString); -} - -template ::value && (sizeof(typename strT::value_type) == 2), bool>::type = false> -inline std::wstring toWChar(const strT& unicodeString) -{ - return std::wstring(unicodeString.begin(), unicodeString.end()); -} - -template ::value && (sizeof(typename strT::value_type) == 4), bool>::type = false> -inline std::wstring toWChar(const strT& unicodeString) -{ - auto temp = toUtf8(unicodeString); - return fromUtf8(temp); -} - -template -inline std::wstring toWChar(const charT* unicodeString) -{ -#ifdef GHC_WITH_STRING_VIEW - return toWChar(basic_string_view>(unicodeString)); -#else - return toWChar(std::basic_string>(unicodeString)); -#endif -} -#endif // GHC_USE_WCHAR_T - -} // namespace detail - -#ifdef GHC_EXPAND_IMPL - -namespace detail { - -template ::value, bool>::type = true> -GHC_INLINE bool startsWith(const strT& what, const strT& with) -{ - return with.length() <= what.length() && equal(with.begin(), with.end(), what.begin()); -} - -template ::value, bool>::type = true> -GHC_INLINE bool endsWith(const strT& what, const strT& with) -{ - return with.length() <= what.length() && what.compare(what.length() - with.length(), with.size(), with) == 0; -} - -} // namespace detail - -GHC_INLINE void path::check_long_path() -{ -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - if (is_absolute() && _path.length() >= MAX_PATH - 12 && !detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\")))) { - postprocess_path_with_format(native_format); - } -#endif -} - -GHC_INLINE void path::postprocess_path_with_format(path::format fmt) -{ -#ifdef GHC_RAISE_UNICODE_ERRORS - if (!detail::validUtf8(_path)) { - path t; - t._path = _path; - throw filesystem_error("Illegal byte sequence for unicode character.", t, std::make_error_code(std::errc::illegal_byte_sequence)); - } -#endif - switch (fmt) { -#ifdef GHC_OS_WINDOWS - case path::native_format: - case path::auto_format: - case path::generic_format: - for (auto& c : _path) { - if (c == generic_separator) { - c = preferred_separator; - } - } -#ifdef GHC_WIN_AUTO_PREFIX_LONG_PATH - if (is_absolute() && _path.length() >= MAX_PATH - 12 && !detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\")))) { - _path = GHC_PLATFORM_LITERAL("\\\\?\\") + _path; - } -#endif - handle_prefixes(); - break; -#else - case path::auto_format: - case path::native_format: - case path::generic_format: - // nothing to do - break; -#endif - } - if (_path.length() > _prefixLength + 2 && _path[_prefixLength] == preferred_separator && _path[_prefixLength + 1] == preferred_separator && _path[_prefixLength + 2] != preferred_separator) { - impl_string_type::iterator new_end = std::unique(_path.begin() + static_cast(_prefixLength) + 2, _path.end(), [](path::value_type lhs, path::value_type rhs) { return lhs == rhs && lhs == preferred_separator; }); - _path.erase(new_end, _path.end()); - } - else { - impl_string_type::iterator new_end = std::unique(_path.begin() + static_cast(_prefixLength), _path.end(), [](path::value_type lhs, path::value_type rhs) { return lhs == rhs && lhs == preferred_separator; }); - _path.erase(new_end, _path.end()); - } -} - -#endif // GHC_EXPAND_IMPL - -template -inline path::path(const Source& source, format fmt) -#ifdef GHC_USE_WCHAR_T - : _path(detail::toWChar(source)) -#else - : _path(detail::toUtf8(source)) -#endif -{ - postprocess_path_with_format(fmt); -} - -template -inline path u8path(const Source& source) -{ - return path(source); -} -template -inline path u8path(InputIterator first, InputIterator last) -{ - return path(first, last); -} - -template -inline path::path(InputIterator first, InputIterator last, format fmt) - : path(std::basic_string::value_type>(first, last), fmt) -{ - // delegated -} - -#ifdef GHC_EXPAND_IMPL - -namespace detail { - -GHC_INLINE bool equals_simple_insensitive(const path::value_type* str1, const path::value_type* str2) -{ -#ifdef GHC_OS_WINDOWS -#ifdef __GNUC__ - while (::tolower((unsigned char)*str1) == ::tolower((unsigned char)*str2++)) { - if (*str1++ == 0) - return true; - } - return false; -#else // __GNUC__ -#ifdef GHC_USE_WCHAR_T - return 0 == ::_wcsicmp(str1, str2); -#else // GHC_USE_WCHAR_T - return 0 == ::_stricmp(str1, str2); -#endif // GHC_USE_WCHAR_T -#endif // __GNUC__ -#else // GHC_OS_WINDOWS - return 0 == ::strcasecmp(str1, str2); -#endif // GHC_OS_WINDOWS -} - -GHC_INLINE int compare_simple_insensitive(const path::value_type* str1, size_t len1, const path::value_type* str2, size_t len2) -{ - while (len1 > 0 && len2 > 0 && ::tolower(static_cast(*str1)) == ::tolower(static_cast(*str2))) { - --len1; - --len2; - ++str1; - ++str2; - } - if (len1 && len2) { - return *str1 < *str2 ? -1 : 1; - } - if (len1 == 0 && len2 == 0) { - return 0; - } - return len1 == 0 ? -1 : 1; -} - -GHC_INLINE const char* strerror_adapter(char* gnu, char*) -{ - return gnu; -} - -GHC_INLINE const char* strerror_adapter(int posix, char* buffer) -{ - if (posix) { - return "Error in strerror_r!"; - } - return buffer; -} - -template -GHC_INLINE std::string systemErrorText(ErrorNumber code = 0) -{ -#if defined(GHC_OS_WINDOWS) - LPVOID msgBuf; - DWORD dw = code ? static_cast(code) : ::GetLastError(); - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&msgBuf, 0, NULL); - std::string msg = toUtf8(std::wstring((LPWSTR)msgBuf)); - LocalFree(msgBuf); - return msg; -#else - char buffer[512]; - return strerror_adapter(strerror_r(code ? code : errno, buffer, sizeof(buffer)), buffer); -#endif -} - -#ifdef GHC_OS_WINDOWS -using CreateSymbolicLinkW_fp = BOOLEAN(WINAPI*)(LPCWSTR, LPCWSTR, DWORD); -using CreateHardLinkW_fp = BOOLEAN(WINAPI*)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); - -GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink, bool to_directory, std::error_code& ec) -{ - std::error_code tec; - auto fs = status(target_name, tec); - if ((fs.type() == file_type::directory && !to_directory) || (fs.type() == file_type::regular && to_directory)) { - ec = detail::make_error_code(detail::portable_error::not_supported); - return; - } -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#endif - static CreateSymbolicLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateSymbolicLinkW")); -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic pop -#endif - if (api_call) { - if (api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 1 : 0) == 0) { - auto result = ::GetLastError(); - if (result == ERROR_PRIVILEGE_NOT_HELD && api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 3 : 2) != 0) { - return; - } - ec = detail::make_system_error(result); - } - } - else { - ec = detail::make_system_error(ERROR_NOT_SUPPORTED); - } -} - -GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlink, std::error_code& ec) -{ -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#endif - static CreateHardLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW")); -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic pop -#endif - if (api_call) { - if (api_call(GHC_NATIVEWP(new_hardlink), GHC_NATIVEWP(target_name), NULL) == 0) { - ec = detail::make_system_error(); - } - } - else { - ec = detail::make_system_error(ERROR_NOT_SUPPORTED); - } -} - -GHC_INLINE path getFullPathName(const wchar_t* p, std::error_code& ec) -{ - ULONG size = ::GetFullPathNameW(p, 0, 0, 0); - if (size) { - std::vector buf(size, 0); - ULONG s2 = GetFullPathNameW(p, size, buf.data(), nullptr); - if (s2 && s2 < size) { - return path(std::wstring(buf.data(), s2)); - } - } - ec = detail::make_system_error(); - return path(); -} - -#else -GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink, bool, std::error_code& ec) -{ - if (::symlink(target_name.c_str(), new_symlink.c_str()) != 0) { - ec = detail::make_system_error(); - } -} - -#ifndef GHC_OS_WEB -GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlink, std::error_code& ec) -{ - if (::link(target_name.c_str(), new_hardlink.c_str()) != 0) { - ec = detail::make_system_error(); - } -} -#endif -#endif - -template -GHC_INLINE file_status file_status_from_st_mode(T mode) -{ -#ifdef GHC_OS_WINDOWS - file_type ft = file_type::unknown; - if ((mode & _S_IFDIR) == _S_IFDIR) { - ft = file_type::directory; - } - else if ((mode & _S_IFREG) == _S_IFREG) { - ft = file_type::regular; - } - else if ((mode & _S_IFCHR) == _S_IFCHR) { - ft = file_type::character; - } - perms prms = static_cast(mode & 0xfff); - return file_status(ft, prms); -#else - file_type ft = file_type::unknown; - if (S_ISDIR(mode)) { - ft = file_type::directory; - } - else if (S_ISREG(mode)) { - ft = file_type::regular; - } - else if (S_ISCHR(mode)) { - ft = file_type::character; - } - else if (S_ISBLK(mode)) { - ft = file_type::block; - } - else if (S_ISFIFO(mode)) { - ft = file_type::fifo; - } - else if (S_ISLNK(mode)) { - ft = file_type::symlink; - } - else if (S_ISSOCK(mode)) { - ft = file_type::socket; - } - perms prms = static_cast(mode & 0xfff); - return file_status(ft, prms); -#endif -} - -#ifdef GHC_OS_WINDOWS - -class unique_handle -{ -public: - typedef HANDLE element_type; - - unique_handle() noexcept - : _handle(INVALID_HANDLE_VALUE) - { - } - explicit unique_handle(element_type h) noexcept - : _handle(h) - { - } - unique_handle(unique_handle&& u) noexcept - : _handle(u.release()) - { - } - ~unique_handle() { reset(); } - unique_handle& operator=(unique_handle&& u) noexcept - { - reset(u.release()); - return *this; - } - element_type get() const noexcept { return _handle; } - explicit operator bool() const noexcept { return _handle != INVALID_HANDLE_VALUE; } - element_type release() noexcept - { - element_type tmp = _handle; - _handle = INVALID_HANDLE_VALUE; - return tmp; - } - void reset(element_type h = INVALID_HANDLE_VALUE) noexcept - { - element_type tmp = _handle; - _handle = h; - if (tmp != INVALID_HANDLE_VALUE) { - CloseHandle(tmp); - } - } - void swap(unique_handle& u) noexcept { std::swap(_handle, u._handle); } - -private: - element_type _handle; -}; - -#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE -typedef struct _REPARSE_DATA_BUFFER -{ - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union - { - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct - { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; -} REPARSE_DATA_BUFFER; -#ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE -#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024) -#endif -#endif - -template -struct free_deleter -{ - void operator()(T* p) const { std::free(p); } -}; - -GHC_INLINE std::unique_ptr> getReparseData(const path& p, std::error_code& ec) -{ - unique_handle file(CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0)); - if (!file) { - ec = detail::make_system_error(); - return nullptr; - } - - std::unique_ptr> reparseData(reinterpret_cast(std::calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE))); - ULONG bufferUsed; - if (DeviceIoControl(file.get(), FSCTL_GET_REPARSE_POINT, 0, 0, reparseData.get(), MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bufferUsed, 0)) { - return reparseData; - } - else { - ec = detail::make_system_error(); - } - return nullptr; -} -#endif - -GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec) -{ -#ifdef GHC_OS_WINDOWS - path result; - auto reparseData = detail::getReparseData(p, ec); - if (!ec) { - if (reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag)) { - switch (reparseData->ReparseTag) { - case IO_REPARSE_TAG_SYMLINK: { - auto printName = std::wstring(&reparseData->SymbolicLinkReparseBuffer.PathBuffer[reparseData->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], reparseData->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR)); - auto substituteName = - std::wstring(&reparseData->SymbolicLinkReparseBuffer.PathBuffer[reparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], reparseData->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); - if (detail::endsWith(substituteName, printName) && detail::startsWith(substituteName, std::wstring(L"\\??\\"))) { - result = printName; - } - else { - result = substituteName; - } - if (reparseData->SymbolicLinkReparseBuffer.Flags & 0x1 /*SYMLINK_FLAG_RELATIVE*/) { - result = p.parent_path() / result; - } - break; - } - case IO_REPARSE_TAG_MOUNT_POINT: - result = detail::getFullPathName(GHC_NATIVEWP(p), ec); - // result = std::wstring(&reparseData->MountPointReparseBuffer.PathBuffer[reparseData->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], reparseData->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); - break; - default: - break; - } - } - } - return result; -#else - size_t bufferSize = 256; - while (true) { - std::vector buffer(bufferSize, static_cast(0)); - auto rc = ::readlink(p.c_str(), buffer.data(), buffer.size()); - if (rc < 0) { - ec = detail::make_system_error(); - return path(); - } - else if (rc < static_cast(bufferSize)) { - return path(std::string(buffer.data(), static_cast(rc))); - } - bufferSize *= 2; - } - return path(); -#endif -} - -#ifdef GHC_OS_WINDOWS -GHC_INLINE time_t timeFromFILETIME(const FILETIME& ft) -{ - ULARGE_INTEGER ull; - ull.LowPart = ft.dwLowDateTime; - ull.HighPart = ft.dwHighDateTime; - return static_cast(ull.QuadPart / 10000000ULL - 11644473600ULL); -} - -GHC_INLINE void timeToFILETIME(time_t t, FILETIME& ft) -{ - LONGLONG ll; - ll = Int32x32To64(t, 10000000) + 116444736000000000; - ft.dwLowDateTime = static_cast(ll); - ft.dwHighDateTime = static_cast(ll >> 32); -} - -template -GHC_INLINE uintmax_t hard_links_from_INFO(const INFO* info) -{ - return static_cast(-1); -} - -template <> -GHC_INLINE uintmax_t hard_links_from_INFO(const BY_HANDLE_FILE_INFORMATION* info) -{ - return info->nNumberOfLinks; -} - -template -GHC_INLINE DWORD reparse_tag_from_INFO(const INFO*) -{ - return 0; -} - -template <> -GHC_INLINE DWORD reparse_tag_from_INFO(const WIN32_FIND_DATAW* info) -{ - return info->dwReserved0; -} - -template -GHC_INLINE file_status status_from_INFO(const path& p, const INFO* info, std::error_code& ec, uintmax_t* sz = nullptr, time_t* lwt = nullptr) -{ - file_type ft = file_type::unknown; - if (sizeof(INFO) == sizeof(WIN32_FIND_DATAW)) { - if (detail::reparse_tag_from_INFO(info) == IO_REPARSE_TAG_SYMLINK) { - ft = file_type::symlink; - } - } - else { - if ((info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - auto reparseData = detail::getReparseData(p, ec); - if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - ft = file_type::symlink; - } - } - } - if (ft == file_type::unknown) { - if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - ft = file_type::directory; - } - else { - ft = file_type::regular; - } - } - perms prms = perms::owner_read | perms::group_read | perms::others_read; - if (!(info->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { - prms = prms | perms::owner_write | perms::group_write | perms::others_write; - } - if (has_executable_extension(p)) { - prms = prms | perms::owner_exec | perms::group_exec | perms::others_exec; - } - if (sz) { - *sz = static_cast(info->nFileSizeHigh) << (sizeof(info->nFileSizeHigh) * 8) | info->nFileSizeLow; - } - if (lwt) { - *lwt = detail::timeFromFILETIME(info->ftLastWriteTime); - } - return file_status(ft, prms); -} - -#endif - -GHC_INLINE bool is_not_found_error(std::error_code& ec) -{ -#ifdef GHC_OS_WINDOWS - return ec.value() == ERROR_FILE_NOT_FOUND || ec.value() == ERROR_PATH_NOT_FOUND || ec.value() == ERROR_INVALID_NAME; -#else - return ec.value() == ENOENT || ec.value() == ENOTDIR; -#endif -} - -GHC_INLINE file_status symlink_status_ex(const path& p, std::error_code& ec, uintmax_t* sz = nullptr, uintmax_t* nhl = nullptr, time_t* lwt = nullptr) noexcept -{ -#ifdef GHC_OS_WINDOWS - file_status fs; - WIN32_FILE_ATTRIBUTE_DATA attr; - if (!GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { - ec = detail::make_system_error(); - } - else { - ec.clear(); - fs = detail::status_from_INFO(p, &attr, ec, sz, lwt); - if (nhl) { - *nhl = 0; - } - } - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found); - } - return ec ? file_status(file_type::none) : fs; -#else - (void)sz; - (void)nhl; - (void)lwt; - struct ::stat fs; - auto result = ::lstat(p.c_str(), &fs); - if (result == 0) { - ec.clear(); - file_status f_s = detail::file_status_from_st_mode(fs.st_mode); - return f_s; - } - ec = detail::make_system_error(); - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found, perms::unknown); - } - return file_status(file_type::none); -#endif -} - -GHC_INLINE file_status status_ex(const path& p, std::error_code& ec, file_status* sls = nullptr, uintmax_t* sz = nullptr, uintmax_t* nhl = nullptr, time_t* lwt = nullptr, int recurse_count = 0) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (recurse_count > 16) { - ec = detail::make_system_error(0x2A9 /*ERROR_STOPPED_ON_SYMLINK*/); - return file_status(file_type::unknown); - } - WIN32_FILE_ATTRIBUTE_DATA attr; - if (!::GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { - ec = detail::make_system_error(); - } - else if (attr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - auto reparseData = detail::getReparseData(p, ec); - if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - path target = resolveSymlink(p, ec); - file_status result; - if (!ec && !target.empty()) { - if (sls) { - *sls = status_from_INFO(p, &attr, ec); - } - return detail::status_ex(target, ec, nullptr, sz, nhl, lwt, recurse_count + 1); - } - return file_status(file_type::unknown); - } - } - if (ec) { - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found); - } - return file_status(file_type::none); - } - if (nhl) { - *nhl = 0; - } - return detail::status_from_INFO(p, &attr, ec, sz, lwt); -#else - (void)recurse_count; - struct ::stat st; - auto result = ::lstat(p.c_str(), &st); - if (result == 0) { - ec.clear(); - file_status fs = detail::file_status_from_st_mode(st.st_mode); - if (sls) { - *sls = fs; - } - if (fs.type() == file_type::symlink) { - result = ::stat(p.c_str(), &st); - if (result == 0) { - fs = detail::file_status_from_st_mode(st.st_mode); - } - else { - ec = detail::make_system_error(); - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found, perms::unknown); - } - return file_status(file_type::none); - } - } - if (sz) { - *sz = static_cast(st.st_size); - } - if (nhl) { - *nhl = st.st_nlink; - } - if (lwt) { - *lwt = st.st_mtime; - } - return fs; - } - else { - ec = detail::make_system_error(); - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found, perms::unknown); - } - return file_status(file_type::none); - } -#endif -} - -} // namespace detail - -GHC_INLINE u8arguments::u8arguments(int& argc, char**& argv) - : _argc(argc) - , _argv(argv) - , _refargc(argc) - , _refargv(argv) - , _isvalid(false) -{ -#ifdef GHC_OS_WINDOWS - LPWSTR* p; - p = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - _args.reserve(static_cast(argc)); - _argp.reserve(static_cast(argc)); - for (size_t i = 0; i < static_cast(argc); ++i) { - _args.push_back(detail::toUtf8(std::wstring(p[i]))); - _argp.push_back((char*)_args[i].data()); - } - argv = _argp.data(); - ::LocalFree(p); - _isvalid = true; -#else - std::setlocale(LC_ALL, ""); -#if defined(__ANDROID__) && __ANDROID_API__ < 26 - _isvalid = true; -#else - if (detail::equals_simple_insensitive(::nl_langinfo(CODESET), "UTF-8")) { - _isvalid = true; - } -#endif -#endif -} - -//----------------------------------------------------------------------------- -// [fs.path.construct] constructors and destructor - -GHC_INLINE path::path() noexcept {} - -GHC_INLINE path::path(const path& p) - : _path(p._path) -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - , _prefixLength(p._prefixLength) -#endif -{ -} - -GHC_INLINE path::path(path&& p) noexcept - : _path(std::move(p._path)) -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - , _prefixLength(p._prefixLength) -#endif -{ -} - -GHC_INLINE path::path(string_type&& source, format fmt) - : _path(std::move(source)) -{ - postprocess_path_with_format(fmt); -} - -#endif // GHC_EXPAND_IMPL - -#ifdef GHC_WITH_EXCEPTIONS -template -inline path::path(const Source& source, const std::locale& loc, format fmt) - : path(source, fmt) -{ - std::string locName = loc.name(); - if (!(locName.length() >= 5 && (locName.substr(locName.length() - 5) == "UTF-8" || locName.substr(locName.length() - 5) == "utf-8"))) { - throw filesystem_error("This implementation only supports UTF-8 locales!", path(_path), detail::make_error_code(detail::portable_error::not_supported)); - } -} - -template -inline path::path(InputIterator first, InputIterator last, const std::locale& loc, format fmt) - : path(std::basic_string::value_type>(first, last), fmt) -{ - std::string locName = loc.name(); - if (!(locName.length() >= 5 && (locName.substr(locName.length() - 5) == "UTF-8" || locName.substr(locName.length() - 5) == "utf-8"))) { - throw filesystem_error("This implementation only supports UTF-8 locales!", path(_path), detail::make_error_code(detail::portable_error::not_supported)); - } -} -#endif - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE path::~path() {} - -//----------------------------------------------------------------------------- -// [fs.path.assign] assignments - -GHC_INLINE path& path::operator=(const path& p) -{ - _path = p._path; -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = p._prefixLength; -#endif - return *this; -} - -GHC_INLINE path& path::operator=(path&& p) noexcept -{ - _path = std::move(p._path); -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = p._prefixLength; -#endif - return *this; -} - -GHC_INLINE path& path::operator=(path::string_type&& source) -{ - return assign(source); -} - -GHC_INLINE path& path::assign(path::string_type&& source) -{ - _path = std::move(source); - postprocess_path_with_format(native_format); - return *this; -} - -#endif // GHC_EXPAND_IMPL - -template -inline path& path::operator=(const Source& source) -{ - return assign(source); -} - -template -inline path& path::assign(const Source& source) -{ -#ifdef GHC_USE_WCHAR_T - _path.assign(detail::toWChar(source)); -#else - _path.assign(detail::toUtf8(source)); -#endif - postprocess_path_with_format(native_format); - return *this; -} - -template <> -inline path& path::assign(const path& source) -{ - _path = source._path; -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = source._prefixLength; -#endif - return *this; -} - -template -inline path& path::assign(InputIterator first, InputIterator last) -{ - _path.assign(first, last); - postprocess_path_with_format(native_format); - return *this; -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.append] appends - -GHC_INLINE path& path::operator/=(const path& p) -{ - if (p.empty()) { - // was: if ((!has_root_directory() && is_absolute()) || has_filename()) - if (!_path.empty() && _path[_path.length() - 1] != preferred_separator && _path[_path.length() - 1] != ':') { - _path += preferred_separator; - } - return *this; - } - if ((p.is_absolute() && (_path != root_name()._path || p._path != "/")) || (p.has_root_name() && p.root_name() != root_name())) { - assign(p); - return *this; - } - if (p.has_root_directory()) { - assign(root_name()); - } - else if ((!has_root_directory() && is_absolute()) || has_filename()) { - _path += preferred_separator; - } - auto iter = p.begin(); - bool first = true; - if (p.has_root_name()) { - ++iter; - } - while (iter != p.end()) { - if (!first && !(!_path.empty() && _path[_path.length() - 1] == preferred_separator)) { - _path += preferred_separator; - } - first = false; - _path += (*iter++).native(); - } - check_long_path(); - return *this; -} - -GHC_INLINE void path::append_name(const value_type* name) -{ - if (_path.empty()) { - this->operator/=(path(name)); - } - else { - if (_path.back() != path::preferred_separator) { - _path.push_back(path::preferred_separator); - } - _path += name; - check_long_path(); - } -} - -#endif // GHC_EXPAND_IMPL - -template -inline path& path::operator/=(const Source& source) -{ - return append(source); -} - -template -inline path& path::append(const Source& source) -{ - return this->operator/=(path(source)); -} - -template <> -inline path& path::append(const path& p) -{ - return this->operator/=(p); -} - -template -inline path& path::append(InputIterator first, InputIterator last) -{ - std::basic_string::value_type> part(first, last); - return append(part); -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.concat] concatenation - -GHC_INLINE path& path::operator+=(const path& x) -{ - return concat(x._path); -} - -GHC_INLINE path& path::operator+=(const string_type& x) -{ - return concat(x); -} - -#ifdef GHC_WITH_STRING_VIEW -GHC_INLINE path& path::operator+=(basic_string_view x) -{ - return concat(x); -} -#endif - -GHC_INLINE path& path::operator+=(const value_type* x) -{ -#ifdef GHC_WITH_STRING_VIEW - basic_string_view part(x); -#else - string_type part(x); -#endif - return concat(part); -} - -GHC_INLINE path& path::operator+=(value_type x) -{ -#ifdef GHC_OS_WINDOWS - if (x == generic_separator) { - x = preferred_separator; - } -#endif - if (_path.empty() || _path.back() != preferred_separator) { - _path += x; - } - check_long_path(); - return *this; -} - -#endif // GHC_EXPAND_IMPL - -template -inline path::path_from_string& path::operator+=(const Source& x) -{ - return concat(x); -} - -template -inline path::path_type_EcharT& path::operator+=(EcharT x) -{ -#ifdef GHC_WITH_STRING_VIEW - basic_string_view part(&x, 1); -#else - std::basic_string part(1, x); -#endif - concat(part); - return *this; -} - -template -inline path& path::concat(const Source& x) -{ - path p(x); - _path += p._path; - postprocess_path_with_format(native_format); - return *this; -} -template -inline path& path::concat(InputIterator first, InputIterator last) -{ - _path.append(first, last); - postprocess_path_with_format(native_format); - return *this; -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.modifiers] modifiers -GHC_INLINE void path::clear() noexcept -{ - _path.clear(); -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = 0; -#endif -} - -GHC_INLINE path& path::make_preferred() -{ - // as this filesystem implementation only uses generic_format - // internally, this must be a no-op - return *this; -} - -GHC_INLINE path& path::remove_filename() -{ - if (has_filename()) { - _path.erase(_path.size() - filename()._path.size()); - } - return *this; -} - -GHC_INLINE path& path::replace_filename(const path& replacement) -{ - remove_filename(); - return append(replacement); -} - -GHC_INLINE path& path::replace_extension(const path& replacement) -{ - if (has_extension()) { - _path.erase(_path.size() - extension()._path.size()); - } - if (!replacement.empty() && replacement._path[0] != '.') { - _path += '.'; - } - return concat(replacement); -} - -GHC_INLINE void path::swap(path& rhs) noexcept -{ - _path.swap(rhs._path); -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - std::swap(_prefixLength, rhs._prefixLength); -#endif -} - -//----------------------------------------------------------------------------- -// [fs.path.native.obs] native format observers -GHC_INLINE const path::string_type& path::native() const noexcept -{ - return _path; -} - -GHC_INLINE const path::value_type* path::c_str() const noexcept -{ - return native().c_str(); -} - -GHC_INLINE path::operator path::string_type() const -{ - return native(); -} - -#endif // GHC_EXPAND_IMPL - -template -inline std::basic_string path::string(const Allocator& a) const -{ -#ifdef GHC_USE_WCHAR_T - return detail::fromWChar>(_path, a); -#else - return detail::fromUtf8>(_path, a); -#endif -} - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE std::string path::string() const -{ -#ifdef GHC_USE_WCHAR_T - return detail::toUtf8(native()); -#else - return native(); -#endif -} - -GHC_INLINE std::wstring path::wstring() const -{ -#ifdef GHC_USE_WCHAR_T - return native(); -#else - return detail::fromUtf8(native()); -#endif -} - -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -GHC_INLINE std::u8string path::u8string() const -{ -#ifdef GHC_USE_WCHAR_T - return std::u8string(reinterpret_cast(detail::toUtf8(native()).c_str())); -#else - return std::u8string(reinterpret_cast(c_str())); -#endif -} -#else -GHC_INLINE std::string path::u8string() const -{ -#ifdef GHC_USE_WCHAR_T - return detail::toUtf8(native()); -#else - return native(); -#endif -} -#endif - -GHC_INLINE std::u16string path::u16string() const -{ - // TODO: optimize - return detail::fromUtf8(string()); -} - -GHC_INLINE std::u32string path::u32string() const -{ - // TODO: optimize - return detail::fromUtf8(string()); -} - -#endif // GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.generic.obs] generic format observers -template -inline std::basic_string path::generic_string(const Allocator& a) const -{ -#ifdef GHC_OS_WINDOWS -#ifdef GHC_USE_WCHAR_T - auto result = detail::fromWChar, path::string_type>(_path, a); -#else - auto result = detail::fromUtf8>(_path, a); -#endif - for (auto& c : result) { - if (c == preferred_separator) { - c = generic_separator; - } - } - return result; -#else - return detail::fromUtf8>(_path, a); -#endif -} - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE std::string path::generic_string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return _path; -#endif -} - -GHC_INLINE std::wstring path::generic_wstring() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return detail::fromUtf8(_path); -#endif -} // namespace filesystem - -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -GHC_INLINE std::u8string path::generic_u8string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return std::u8string(reinterpret_cast(_path.c_str())); -#endif -} -#else -GHC_INLINE std::string path::generic_u8string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return _path; -#endif -} -#endif - -GHC_INLINE std::u16string path::generic_u16string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return detail::fromUtf8(_path); -#endif -} - -GHC_INLINE std::u32string path::generic_u32string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return detail::fromUtf8(_path); -#endif -} - -//----------------------------------------------------------------------------- -// [fs.path.compare] compare -GHC_INLINE int path::compare(const path& p) const noexcept -{ -#ifdef LWG_2936_BEHAVIOUR - auto rnl1 = root_name_length(); - auto rnl2 = p.root_name_length(); -#ifdef GHC_OS_WINDOWS - auto rnc = detail::compare_simple_insensitive(_path.c_str(), rnl1, p._path.c_str(), rnl2); -#else - auto rnc = _path.compare(0, rnl1, p._path, 0, (std::min(rnl1, rnl2))); -#endif - if (rnc) { - return rnc; - } - bool hrd1 = has_root_directory(), hrd2 = p.has_root_directory(); - if (hrd1 != hrd2) { - return hrd1 ? 1 : -1; - } - if (hrd1) { - ++rnl1; - ++rnl2; - } - auto iter1 = _path.begin() + static_cast(rnl1); - auto iter2 = p._path.begin() + static_cast(rnl2); - while (iter1 != _path.end() && iter2 != p._path.end() && *iter1 == *iter2) { - ++iter1; - ++iter2; - } - if (iter1 == _path.end()) { - return iter2 == p._path.end() ? 0 : -1; - } - if (iter2 == p._path.end()) { - return 1; - } - if (*iter1 == preferred_separator) { - return -1; - } - if (*iter2 == preferred_separator) { - return 1; - } - return *iter1 < *iter2 ? -1 : 1; -#else // LWG_2936_BEHAVIOUR -#ifdef GHC_OS_WINDOWS - auto rnl1 = root_name_length(); - auto rnl2 = p.root_name_length(); - auto rnc = detail::compare_simple_insensitive(_path.c_str(), rnl1, p._path.c_str(), rnl2); - if (rnc) { - return rnc; - } - return _path.compare(rnl1, std::string::npos, p._path, rnl2, std::string::npos); -#else - return _path.compare(p._path); -#endif -#endif -} - -GHC_INLINE int path::compare(const string_type& s) const -{ - return compare(path(s)); -} - -#ifdef GHC_WITH_STRING_VIEW -GHC_INLINE int path::compare(basic_string_view s) const -{ - return compare(path(s)); -} -#endif - -GHC_INLINE int path::compare(const value_type* s) const -{ - return compare(path(s)); -} - -//----------------------------------------------------------------------------- -// [fs.path.decompose] decomposition -#ifdef GHC_OS_WINDOWS -GHC_INLINE void path::handle_prefixes() -{ -#if defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = 0; - if (_path.length() >= 6 && _path[2] == '?' && std::toupper(static_cast(_path[4])) >= 'A' && std::toupper(static_cast(_path[4])) <= 'Z' && _path[5] == ':') { - if (detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\"))) || detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\??\\")))) { - _prefixLength = 4; - } - } -#endif // GHC_WIN_AUTO_PREFIX_LONG_PATH -} -#endif - -GHC_INLINE path::string_type::size_type path::root_name_length() const noexcept -{ -#ifdef GHC_OS_WINDOWS - if (_path.length() >= _prefixLength + 2 && std::toupper(static_cast(_path[_prefixLength])) >= 'A' && std::toupper(static_cast(_path[_prefixLength])) <= 'Z' && _path[_prefixLength + 1] == ':') { - return 2; - } -#endif - if (_path.length() > _prefixLength + 2 && _path[_prefixLength] == preferred_separator && _path[_prefixLength + 1] == preferred_separator && _path[_prefixLength + 2] != preferred_separator && std::isprint(_path[_prefixLength + 2])) { - impl_string_type::size_type pos = _path.find(preferred_separator, _prefixLength + 3); - if (pos == impl_string_type::npos) { - return _path.length(); - } - else { - return pos; - } - } - return 0; -} - -GHC_INLINE path path::root_name() const -{ - return path(_path.substr(_prefixLength, root_name_length()), native_format); -} - -GHC_INLINE path path::root_directory() const -{ - if (has_root_directory()) { - static const path _root_dir(std::string(1, preferred_separator), native_format); - return _root_dir; - } - return path(); -} - -GHC_INLINE path path::root_path() const -{ - return path(root_name().string() + root_directory().string(), native_format); -} - -GHC_INLINE path path::relative_path() const -{ - auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); - return path(_path.substr((std::min)(rootPathLen, _path.length())), generic_format); -} - -GHC_INLINE path path::parent_path() const -{ - auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); - if (rootPathLen < _path.length()) { - if (empty()) { - return path(); - } - else { - auto piter = end(); - auto iter = piter.decrement(_path.end()); - if (iter > _path.begin() + static_cast(rootPathLen) && *iter != preferred_separator) { - --iter; - } - return path(_path.begin(), iter, native_format); - } - } - else { - return *this; - } -} - -GHC_INLINE path path::filename() const -{ - return !has_relative_path() ? path() : path(*--end()); -} - -GHC_INLINE path path::stem() const -{ - impl_string_type fn = filename().native(); - if (fn != "." && fn != "..") { - impl_string_type::size_type pos = fn.rfind('.'); - if (pos != impl_string_type::npos && pos > 0) { - return path{fn.substr(0, pos), native_format}; - } - } - return path{fn, native_format}; -} - -GHC_INLINE path path::extension() const -{ - if (has_relative_path()) { - auto iter = end(); - const auto& fn = *--iter; - impl_string_type::size_type pos = fn._path.rfind('.'); - if (pos != std::string::npos && pos > 0) { - return path(fn._path.substr(pos), native_format); - } - } - return path(); -} - -#ifdef GHC_OS_WINDOWS -namespace detail { -GHC_INLINE bool has_executable_extension(const path& p) -{ - if (p.has_relative_path()) { - auto iter = p.end(); - const auto& fn = *--iter; - auto pos = fn._path.find_last_of('.'); - if (pos == std::string::npos || pos == 0 || fn._path.length() - pos != 3) { - return false; - } - const path::value_type* ext = fn._path.c_str() + pos + 1; - if (detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("exe")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("cmd")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("bat")) || - detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("com"))) { - return true; - } - } - return false; -} -} // namespace detail -#endif - -//----------------------------------------------------------------------------- -// [fs.path.query] query -GHC_INLINE bool path::empty() const noexcept -{ - return _path.empty(); -} - -GHC_INLINE bool path::has_root_name() const -{ - return root_name_length() > 0; -} - -GHC_INLINE bool path::has_root_directory() const -{ - auto rootLen = _prefixLength + root_name_length(); - return (_path.length() > rootLen && _path[rootLen] == preferred_separator); -} - -GHC_INLINE bool path::has_root_path() const -{ - return has_root_name() || has_root_directory(); -} - -GHC_INLINE bool path::has_relative_path() const -{ - auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); - return rootPathLen < _path.length(); -} - -GHC_INLINE bool path::has_parent_path() const -{ - return !parent_path().empty(); -} - -GHC_INLINE bool path::has_filename() const -{ - return has_relative_path() && !filename().empty(); -} - -GHC_INLINE bool path::has_stem() const -{ - return !stem().empty(); -} - -GHC_INLINE bool path::has_extension() const -{ - return !extension().empty(); -} - -GHC_INLINE bool path::is_absolute() const -{ -#ifdef GHC_OS_WINDOWS - return has_root_name() && has_root_directory(); -#else - return has_root_directory(); -#endif -} - -GHC_INLINE bool path::is_relative() const -{ - return !is_absolute(); -} - -//----------------------------------------------------------------------------- -// [fs.path.gen] generation -GHC_INLINE path path::lexically_normal() const -{ - path dest; - bool lastDotDot = false; - for (string_type s : *this) { - if (s == ".") { - dest /= ""; - continue; - } - else if (s == ".." && !dest.empty()) { - auto root = root_path(); - if (dest == root) { - continue; - } - else if (*(--dest.end()) != "..") { - if (dest._path.back() == preferred_separator) { - dest._path.pop_back(); - } - dest.remove_filename(); - continue; - } - } - if (!(s.empty() && lastDotDot)) { - dest /= s; - } - lastDotDot = s == ".."; - } - if (dest.empty()) { - dest = "."; - } - return dest; -} - -GHC_INLINE path path::lexically_relative(const path& base) const -{ - if (root_name() != base.root_name() || is_absolute() != base.is_absolute() || (!has_root_directory() && base.has_root_directory())) { - return path(); - } - const_iterator a = begin(), b = base.begin(); - while (a != end() && b != base.end() && *a == *b) { - ++a; - ++b; - } - if (a == end() && b == base.end()) { - return path("."); - } - int count = 0; - for (const auto& element : input_iterator_range(b, base.end())) { - if (element != "." && element != "" && element != "..") { - ++count; - } - else if (element == "..") { - --count; - } - } - if (count < 0) { - return path(); - } - path result; - for (int i = 0; i < count; ++i) { - result /= ".."; - } - for (const auto& element : input_iterator_range(a, end())) { - result /= element; - } - return result; -} - -GHC_INLINE path path::lexically_proximate(const path& base) const -{ - path result = lexically_relative(base); - return result.empty() ? *this : result; -} - -//----------------------------------------------------------------------------- -// [fs.path.itr] iterators -GHC_INLINE path::iterator::iterator() {} - -GHC_INLINE path::iterator::iterator(const path& p, const impl_string_type::const_iterator& pos) - : _first(p._path.begin()) - , _last(p._path.end()) - , _prefix(_first + static_cast(p._prefixLength)) - , _root(p.has_root_directory() ? _first + static_cast(p._prefixLength + p.root_name_length()) : _last) - , _iter(pos) -{ - if (pos != _last) { - updateCurrent(); - } -} - -GHC_INLINE path::impl_string_type::const_iterator path::iterator::increment(const path::impl_string_type::const_iterator& pos) const -{ - path::impl_string_type::const_iterator i = pos; - bool fromStart = i == _first || i == _prefix; - if (i != _last) { - if (fromStart && i == _first && _prefix > _first) { - i = _prefix; - } - else if (*i++ == preferred_separator) { - // we can only sit on a slash if it is a network name or a root - if (i != _last && *i == preferred_separator) { - if (fromStart && !(i + 1 != _last && *(i + 1) == preferred_separator)) { - // leadind double slashes detected, treat this and the - // following until a slash as one unit - i = std::find(++i, _last, preferred_separator); - } - else { - // skip redundant slashes - while (i != _last && *i == preferred_separator) { - ++i; - } - } - } - } - else { - if (fromStart && i != _last && *i == ':') { - ++i; - } - else { - i = std::find(i, _last, preferred_separator); - } - } - } - return i; -} - -GHC_INLINE path::impl_string_type::const_iterator path::iterator::decrement(const path::impl_string_type::const_iterator& pos) const -{ - path::impl_string_type::const_iterator i = pos; - if (i != _first) { - --i; - // if this is now the root slash or the trailing slash, we are done, - // else check for network name - if (i != _root && (pos != _last || *i != preferred_separator)) { -#ifdef GHC_OS_WINDOWS - static const impl_string_type seps = GHC_PLATFORM_LITERAL("\\:"); - i = std::find_first_of(std::reverse_iterator(i), std::reverse_iterator(_first), seps.begin(), seps.end()).base(); - if (i > _first && *i == ':') { - i++; - } -#else - i = std::find(std::reverse_iterator(i), std::reverse_iterator(_first), preferred_separator).base(); -#endif - // Now we have to check if this is a network name - if (i - _first == 2 && *_first == preferred_separator && *(_first + 1) == preferred_separator) { - i -= 2; - } - } - } - return i; -} - -GHC_INLINE void path::iterator::updateCurrent() -{ - if ((_iter == _last) || (_iter != _first && _iter != _last && (*_iter == preferred_separator && _iter != _root) && (_iter + 1 == _last))) { - _current.clear(); - } - else { - _current.assign(_iter, increment(_iter)); - } -} - -GHC_INLINE path::iterator& path::iterator::operator++() -{ - _iter = increment(_iter); - while (_iter != _last && // we didn't reach the end - _iter != _root && // this is not a root position - *_iter == preferred_separator && // we are on a separator - (_iter + 1) != _last // the slash is not the last char - ) { - ++_iter; - } - updateCurrent(); - return *this; -} - -GHC_INLINE path::iterator path::iterator::operator++(int) -{ - path::iterator i{*this}; - ++(*this); - return i; -} - -GHC_INLINE path::iterator& path::iterator::operator--() -{ - _iter = decrement(_iter); - updateCurrent(); - return *this; -} - -GHC_INLINE path::iterator path::iterator::operator--(int) -{ - auto i = *this; - --(*this); - return i; -} - -GHC_INLINE bool path::iterator::operator==(const path::iterator& other) const -{ - return _iter == other._iter; -} - -GHC_INLINE bool path::iterator::operator!=(const path::iterator& other) const -{ - return _iter != other._iter; -} - -GHC_INLINE path::iterator::reference path::iterator::operator*() const -{ - return _current; -} - -GHC_INLINE path::iterator::pointer path::iterator::operator->() const -{ - return &_current; -} - -GHC_INLINE path::iterator path::begin() const -{ - return iterator(*this, _path.begin()); -} - -GHC_INLINE path::iterator path::end() const -{ - return iterator(*this, _path.end()); -} - -//----------------------------------------------------------------------------- -// [fs.path.nonmember] path non-member functions -GHC_INLINE void swap(path& lhs, path& rhs) noexcept -{ - swap(lhs._path, rhs._path); -} - -GHC_INLINE size_t hash_value(const path& p) noexcept -{ - return std::hash()(p.generic_string()); -} - -#ifdef GHC_HAS_THREEWAY_COMP -GHC_INLINE std::strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) <=> 0; -} -#endif - -GHC_INLINE bool operator==(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) == 0; -} - -GHC_INLINE bool operator!=(const path& lhs, const path& rhs) noexcept -{ - return !(lhs == rhs); -} - -GHC_INLINE bool operator<(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) < 0; -} - -GHC_INLINE bool operator<=(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) <= 0; -} - -GHC_INLINE bool operator>(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) > 0; -} - -GHC_INLINE bool operator>=(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) >= 0; -} - -GHC_INLINE path operator/(const path& lhs, const path& rhs) -{ - path result(lhs); - result /= rhs; - return result; -} - -#endif // GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.io] path inserter and extractor -template -inline std::basic_ostream& operator<<(std::basic_ostream& os, const path& p) -{ - os << "\""; - auto ps = p.string(); - for (auto c : ps) { - if (c == '"' || c == '\\') { - os << '\\'; - } - os << c; - } - os << "\""; - return os; -} - -template -inline std::basic_istream& operator>>(std::basic_istream& is, path& p) -{ - std::basic_string tmp; - charT c; - is >> c; - if (c == '"') { - auto sf = is.flags(); - is >> std::noskipws; - while (is) { - auto c2 = is.get(); - if (is) { - if (c2 == '\\') { - c2 = is.get(); - if (is) { - tmp += static_cast(c2); - } - } - else if (c2 == '"') { - break; - } - else { - tmp += static_cast(c2); - } - } - } - if ((sf & std::ios_base::skipws) == std::ios_base::skipws) { - is >> std::skipws; - } - p = path(tmp); - } - else { - is >> tmp; - p = path(static_cast(c) + tmp); - } - return is; -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.class.filesystem_error] Class filesystem_error -GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, std::error_code ec) - : std::system_error(ec, what_arg) - , _what_arg(what_arg) - , _ec(ec) -{ -} - -GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, const path& p1, std::error_code ec) - : std::system_error(ec, what_arg) - , _what_arg(what_arg) - , _ec(ec) - , _p1(p1) -{ - if (!_p1.empty()) { - _what_arg += ": '" + _p1.string() + "'"; - } -} - -GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, const path& p1, const path& p2, std::error_code ec) - : std::system_error(ec, what_arg) - , _what_arg(what_arg) - , _ec(ec) - , _p1(p1) - , _p2(p2) -{ - if (!_p1.empty()) { - _what_arg += ": '" + _p1.string() + "'"; - } - if (!_p2.empty()) { - _what_arg += ", '" + _p2.string() + "'"; - } -} - -GHC_INLINE const path& filesystem_error::path1() const noexcept -{ - return _p1; -} - -GHC_INLINE const path& filesystem_error::path2() const noexcept -{ - return _p2; -} - -GHC_INLINE const char* filesystem_error::what() const noexcept -{ - return _what_arg.c_str(); -} - -//----------------------------------------------------------------------------- -// [fs.op.funcs] filesystem operations -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path absolute(const path& p) -{ - std::error_code ec; - path result = absolute(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path absolute(const path& p, std::error_code& ec) -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (p.empty()) { - return absolute(current_path(ec), ec) / ""; - } - ULONG size = ::GetFullPathNameW(GHC_NATIVEWP(p), 0, 0, 0); - if (size) { - std::vector buf(size, 0); - ULONG s2 = GetFullPathNameW(GHC_NATIVEWP(p), size, buf.data(), nullptr); - if (s2 && s2 < size) { - path result = path(std::wstring(buf.data(), s2)); - if (p.filename() == ".") { - result /= "."; - } - return result; - } - } - ec = detail::make_system_error(); - return path(); -#else - path base = current_path(ec); - if (!ec) { - if (p.empty()) { - return base / p; - } - if (p.has_root_name()) { - if (p.has_root_directory()) { - return p; - } - else { - return p.root_name() / base.root_directory() / base.relative_path() / p.relative_path(); - } - } - else { - if (p.has_root_directory()) { - return base.root_name() / p; - } - else { - return base / p; - } - } - } - ec = detail::make_system_error(); - return path(); -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path canonical(const path& p) -{ - std::error_code ec; - auto result = canonical(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path canonical(const path& p, std::error_code& ec) -{ - if (p.empty()) { - ec = detail::make_error_code(detail::portable_error::not_found); - return path(); - } - path work = p.is_absolute() ? p : absolute(p, ec); - path result; - - auto fs = status(work, ec); - if (ec) { - return path(); - } - if (fs.type() == file_type::not_found) { - ec = detail::make_error_code(detail::portable_error::not_found); - return path(); - } - bool redo; - do { - auto rootPathLen = work._prefixLength + work.root_name_length() + (work.has_root_directory() ? 1 : 0); - redo = false; - result.clear(); - for (auto pe : work) { - if (pe.empty() || pe == ".") { - continue; - } - else if (pe == "..") { - result = result.parent_path(); - continue; - } - else if ((result / pe).string().length() <= rootPathLen) { - result /= pe; - continue; - } - auto sls = symlink_status(result / pe, ec); - if (ec) { - return path(); - } - if (is_symlink(sls)) { - redo = true; - auto target = read_symlink(result / pe, ec); - if (ec) { - return path(); - } - if (target.is_absolute()) { - result = target; - continue; - } - else { - result /= target; - continue; - } - } - else { - result /= pe; - } - } - work = result; - } while (redo); - ec.clear(); - return result; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void copy(const path& from, const path& to) -{ - copy(from, to, copy_options::none); -} - -GHC_INLINE void copy(const path& from, const path& to, copy_options options) -{ - std::error_code ec; - copy(from, to, options, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); - } -} -#endif - -GHC_INLINE void copy(const path& from, const path& to, std::error_code& ec) noexcept -{ - copy(from, to, copy_options::none, ec); -} - -GHC_INLINE void copy(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept -{ - std::error_code tec; - file_status fs_from, fs_to; - ec.clear(); - if ((options & (copy_options::skip_symlinks | copy_options::copy_symlinks | copy_options::create_symlinks)) != copy_options::none) { - fs_from = symlink_status(from, ec); - } - else { - fs_from = status(from, ec); - } - if (!exists(fs_from)) { - if (!ec) { - ec = detail::make_error_code(detail::portable_error::not_found); - } - return; - } - if ((options & (copy_options::skip_symlinks | copy_options::create_symlinks)) != copy_options::none) { - fs_to = symlink_status(to, tec); - } - else { - fs_to = status(to, tec); - } - if (is_other(fs_from) || is_other(fs_to) || (is_directory(fs_from) && is_regular_file(fs_to)) || (exists(fs_to) && equivalent(from, to, ec))) { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - } - else if (is_symlink(fs_from)) { - if ((options & copy_options::skip_symlinks) == copy_options::none) { - if (!exists(fs_to) && (options & copy_options::copy_symlinks) != copy_options::none) { - copy_symlink(from, to, ec); - } - else { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - } - } - } - else if (is_regular_file(fs_from)) { - if ((options & copy_options::directories_only) == copy_options::none) { - if ((options & copy_options::create_symlinks) != copy_options::none) { - create_symlink(from.is_absolute() ? from : canonical(from, ec), to, ec); - } -#ifndef GHC_OS_WEB - else if ((options & copy_options::create_hard_links) != copy_options::none) { - create_hard_link(from, to, ec); - } -#endif - else if (is_directory(fs_to)) { - copy_file(from, to / from.filename(), options, ec); - } - else { - copy_file(from, to, options, ec); - } - } - } -#ifdef LWG_2682_BEHAVIOUR - else if (is_directory(fs_from) && (options & copy_options::create_symlinks) != copy_options::none) { - ec = detail::make_error_code(detail::portable_error::is_a_directory); - } -#endif - else if (is_directory(fs_from) && (options == copy_options::none || (options & copy_options::recursive) != copy_options::none)) { - if (!exists(fs_to)) { - create_directory(to, from, ec); - if (ec) { - return; - } - } - for (auto iter = directory_iterator(from, ec); iter != directory_iterator(); iter.increment(ec)) { - if (!ec) { - copy(iter->path(), to / iter->path().filename(), options | static_cast(0x8000), ec); - } - if (ec) { - return; - } - } - } - return; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool copy_file(const path& from, const path& to) -{ - return copy_file(from, to, copy_options::none); -} - -GHC_INLINE bool copy_file(const path& from, const path& to, copy_options option) -{ - std::error_code ec; - auto result = copy_file(from, to, option, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); - } - return result; -} -#endif - -GHC_INLINE bool copy_file(const path& from, const path& to, std::error_code& ec) noexcept -{ - return copy_file(from, to, copy_options::none, ec); -} - -GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept -{ - std::error_code tecf, tect; - auto sf = status(from, tecf); - auto st = status(to, tect); - bool overwrite = false; - ec.clear(); - if (!is_regular_file(sf)) { - ec = tecf; - return false; - } - if (exists(st) && (!is_regular_file(st) || equivalent(from, to, ec) || (options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none)) { - ec = tect ? tect : detail::make_error_code(detail::portable_error::exists); - return false; - } - if (exists(st)) { - if ((options & copy_options::update_existing) == copy_options::update_existing) { - auto from_time = last_write_time(from, ec); - if (ec) { - ec = detail::make_system_error(); - return false; - } - auto to_time = last_write_time(to, ec); - if (ec) { - ec = detail::make_system_error(); - return false; - } - if (from_time <= to_time) { - return false; - } - } - overwrite = true; - } -#ifdef GHC_OS_WINDOWS - if (!::CopyFileW(GHC_NATIVEWP(from), GHC_NATIVEWP(to), !overwrite)) { - ec = detail::make_system_error(); - return false; - } - return true; -#else - std::vector buffer(16384, '\0'); - int in = -1, out = -1; - if ((in = ::open(from.c_str(), O_RDONLY)) < 0) { - ec = detail::make_system_error(); - return false; - } - int mode = O_CREAT | O_WRONLY | O_TRUNC; - if (!overwrite) { - mode |= O_EXCL; - } - if ((out = ::open(to.c_str(), mode, static_cast(sf.permissions() & perms::all))) < 0) { - ec = detail::make_system_error(); - ::close(in); - return false; - } - ssize_t br, bw; - while ((br = ::read(in, buffer.data(), buffer.size())) > 0) { - ssize_t offset = 0; - do { - if ((bw = ::write(out, buffer.data() + offset, static_cast(br))) > 0) { - br -= bw; - offset += bw; - } - else if (bw < 0) { - ec = detail::make_system_error(); - ::close(in); - ::close(out); - return false; - } - } while (br); - } - ::close(in); - ::close(out); - return true; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symlink) -{ - std::error_code ec; - copy_symlink(existing_symlink, new_symlink, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), existing_symlink, new_symlink, ec); - } -} -#endif - -GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symlink, std::error_code& ec) noexcept -{ - ec.clear(); - auto to = read_symlink(existing_symlink, ec); - if (!ec) { - if (exists(to, ec) && is_directory(to, ec)) { - create_directory_symlink(to, new_symlink, ec); - } - else { - create_symlink(to, new_symlink, ec); - } - } -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool create_directories(const path& p) -{ - std::error_code ec; - auto result = create_directories(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool create_directories(const path& p, std::error_code& ec) noexcept -{ - path current; - ec.clear(); - bool didCreate = false; - auto rootPathLen = p._prefixLength + p.root_name_length() + (p.has_root_directory() ? 1 : 0); - current = p.native().substr(0, rootPathLen); - path folders(p._path.substr(rootPathLen)); - for (path::string_type part : folders) { - current /= part; - std::error_code tec; - auto fs = status(current, tec); - if (tec && fs.type() != file_type::not_found) { - ec = tec; - return false; - } - if (!exists(fs)) { - create_directory(current, ec); - if (ec) { - std::error_code tmp_ec; - if (is_directory(current, tmp_ec)) { - ec.clear(); - } - else { - return false; - } - } - didCreate = true; - } -#ifndef LWG_2935_BEHAVIOUR - else if (!is_directory(fs)) { - ec = detail::make_error_code(detail::portable_error::exists); - return false; - } -#endif - } - return didCreate; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool create_directory(const path& p) -{ - std::error_code ec; - auto result = create_directory(p, path(), ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool create_directory(const path& p, std::error_code& ec) noexcept -{ - return create_directory(p, path(), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool create_directory(const path& p, const path& attributes) -{ - std::error_code ec; - auto result = create_directory(p, attributes, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool create_directory(const path& p, const path& attributes, std::error_code& ec) noexcept -{ - std::error_code tec; - ec.clear(); - auto fs = status(p, tec); -#ifdef LWG_2935_BEHAVIOUR - if (status_known(fs) && exists(fs)) { - return false; - } -#else - if (status_known(fs) && exists(fs) && is_directory(fs)) { - return false; - } -#endif -#ifdef GHC_OS_WINDOWS - if (!attributes.empty()) { - if (!::CreateDirectoryExW(GHC_NATIVEWP(attributes), GHC_NATIVEWP(p), NULL)) { - ec = detail::make_system_error(); - return false; - } - } - else if (!::CreateDirectoryW(GHC_NATIVEWP(p), NULL)) { - ec = detail::make_system_error(); - return false; - } -#else - ::mode_t attribs = static_cast(perms::all); - if (!attributes.empty()) { - struct ::stat fileStat; - if (::stat(attributes.c_str(), &fileStat) != 0) { - ec = detail::make_system_error(); - return false; - } - attribs = fileStat.st_mode; - } - if (::mkdir(p.c_str(), attribs) != 0) { - ec = detail::make_system_error(); - return false; - } -#endif - return true; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void create_directory_symlink(const path& to, const path& new_symlink) -{ - std::error_code ec; - create_directory_symlink(to, new_symlink, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), to, new_symlink, ec); - } -} -#endif - -GHC_INLINE void create_directory_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept -{ - detail::create_symlink(to, new_symlink, true, ec); -} - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void create_hard_link(const path& to, const path& new_hard_link) -{ - std::error_code ec; - create_hard_link(to, new_hard_link, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), to, new_hard_link, ec); - } -} -#endif - -GHC_INLINE void create_hard_link(const path& to, const path& new_hard_link, std::error_code& ec) noexcept -{ - detail::create_hardlink(to, new_hard_link, ec); -} -#endif - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void create_symlink(const path& to, const path& new_symlink) -{ - std::error_code ec; - create_symlink(to, new_symlink, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), to, new_symlink, ec); - } -} -#endif - -GHC_INLINE void create_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept -{ - detail::create_symlink(to, new_symlink, false, ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path current_path() -{ - std::error_code ec; - auto result = current_path(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), ec); - } - return result; -} -#endif - -GHC_INLINE path current_path(std::error_code& ec) -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - DWORD pathlen = ::GetCurrentDirectoryW(0, 0); - std::unique_ptr buffer(new wchar_t[size_t(pathlen) + 1]); - if (::GetCurrentDirectoryW(pathlen, buffer.get()) == 0) { - ec = detail::make_system_error(); - return path(); - } - return path(std::wstring(buffer.get()), path::native_format); -#else - size_t pathlen = static_cast(std::max(int(::pathconf(".", _PC_PATH_MAX)), int(PATH_MAX))); - std::unique_ptr buffer(new char[pathlen + 1]); - if (::getcwd(buffer.get(), pathlen) == nullptr) { - ec = detail::make_system_error(); - return path(); - } - return path(buffer.get()); -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void current_path(const path& p) -{ - std::error_code ec; - current_path(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void current_path(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (!::SetCurrentDirectoryW(GHC_NATIVEWP(p))) { - ec = detail::make_system_error(); - } -#else - if (::chdir(p.string().c_str()) == -1) { - ec = detail::make_system_error(); - } -#endif -} - -GHC_INLINE bool exists(file_status s) noexcept -{ - return status_known(s) && s.type() != file_type::not_found; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool exists(const path& p) -{ - return exists(status(p)); -} -#endif - -GHC_INLINE bool exists(const path& p, std::error_code& ec) noexcept -{ - file_status s = status(p, ec); - if (status_known(s)) { - ec.clear(); - } - return exists(s); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool equivalent(const path& p1, const path& p2) -{ - std::error_code ec; - bool result = equivalent(p1, p2, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p1, p2, ec); - } - return result; -} -#endif - -GHC_INLINE bool equivalent(const path& p1, const path& p2, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - detail::unique_handle file1(::CreateFileW(GHC_NATIVEWP(p1), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - auto e1 = ::GetLastError(); - detail::unique_handle file2(::CreateFileW(GHC_NATIVEWP(p2), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - if (!file1 || !file2) { -#ifdef LWG_2937_BEHAVIOUR - ec = detail::make_system_error(e1 ? e1 : ::GetLastError()); -#else - if (file1 == file2) { - ec = detail::make_system_error(e1 ? e1 : ::GetLastError()); - } -#endif - return false; - } - BY_HANDLE_FILE_INFORMATION inf1, inf2; - if (!::GetFileInformationByHandle(file1.get(), &inf1)) { - ec = detail::make_system_error(); - return false; - } - if (!::GetFileInformationByHandle(file2.get(), &inf2)) { - ec = detail::make_system_error(); - return false; - } - return inf1.ftLastWriteTime.dwLowDateTime == inf2.ftLastWriteTime.dwLowDateTime && inf1.ftLastWriteTime.dwHighDateTime == inf2.ftLastWriteTime.dwHighDateTime && inf1.nFileIndexHigh == inf2.nFileIndexHigh && inf1.nFileIndexLow == inf2.nFileIndexLow && - inf1.nFileSizeHigh == inf2.nFileSizeHigh && inf1.nFileSizeLow == inf2.nFileSizeLow && inf1.dwVolumeSerialNumber == inf2.dwVolumeSerialNumber; -#else - struct ::stat s1, s2; - auto rc1 = ::stat(p1.c_str(), &s1); - auto e1 = errno; - auto rc2 = ::stat(p2.c_str(), &s2); - if (rc1 || rc2) { -#ifdef LWG_2937_BEHAVIOUR - ec = detail::make_system_error(e1 ? e1 : errno); -#else - if (rc1 && rc2) { - ec = detail::make_system_error(e1 ? e1 : errno); - } -#endif - return false; - } - return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t file_size(const path& p) -{ - std::error_code ec; - auto result = file_size(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE uintmax_t file_size(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - WIN32_FILE_ATTRIBUTE_DATA attr; - if (!GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { - ec = detail::make_system_error(); - return static_cast(-1); - } - return static_cast(attr.nFileSizeHigh) << (sizeof(attr.nFileSizeHigh) * 8) | attr.nFileSizeLow; -#else - struct ::stat fileStat; - if (::stat(p.c_str(), &fileStat) == -1) { - ec = detail::make_system_error(); - return static_cast(-1); - } - return static_cast(fileStat.st_size); -#endif -} - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t hard_link_count(const path& p) -{ - std::error_code ec; - auto result = hard_link_count(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - uintmax_t result = static_cast(-1); - detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - BY_HANDLE_FILE_INFORMATION inf; - if (!file) { - ec = detail::make_system_error(); - } - else { - if (!::GetFileInformationByHandle(file.get(), &inf)) { - ec = detail::make_system_error(); - } - else { - result = inf.nNumberOfLinks; - } - } - return result; -#else - uintmax_t result = 0; - file_status fs = detail::status_ex(p, ec, nullptr, nullptr, &result, nullptr); - if (fs.type() == file_type::not_found) { - ec = detail::make_error_code(detail::portable_error::not_found); - } - return ec ? static_cast(-1) : result; -#endif -} -#endif - -GHC_INLINE bool is_block_file(file_status s) noexcept -{ - return s.type() == file_type::block; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_block_file(const path& p) -{ - return is_block_file(status(p)); -} -#endif - -GHC_INLINE bool is_block_file(const path& p, std::error_code& ec) noexcept -{ - return is_block_file(status(p, ec)); -} - -GHC_INLINE bool is_character_file(file_status s) noexcept -{ - return s.type() == file_type::character; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_character_file(const path& p) -{ - return is_character_file(status(p)); -} -#endif - -GHC_INLINE bool is_character_file(const path& p, std::error_code& ec) noexcept -{ - return is_character_file(status(p, ec)); -} - -GHC_INLINE bool is_directory(file_status s) noexcept -{ - return s.type() == file_type::directory; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_directory(const path& p) -{ - return is_directory(status(p)); -} -#endif - -GHC_INLINE bool is_directory(const path& p, std::error_code& ec) noexcept -{ - return is_directory(status(p, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_empty(const path& p) -{ - if (is_directory(p)) { - return directory_iterator(p) == directory_iterator(); - } - else { - return file_size(p) == 0; - } -} -#endif - -GHC_INLINE bool is_empty(const path& p, std::error_code& ec) noexcept -{ - auto fs = status(p, ec); - if (ec) { - return false; - } - if (is_directory(fs)) { - directory_iterator iter(p, ec); - if (ec) { - return false; - } - return iter == directory_iterator(); - } - else { - auto sz = file_size(p, ec); - if (ec) { - return false; - } - return sz == 0; - } -} - -GHC_INLINE bool is_fifo(file_status s) noexcept -{ - return s.type() == file_type::fifo; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_fifo(const path& p) -{ - return is_fifo(status(p)); -} -#endif - -GHC_INLINE bool is_fifo(const path& p, std::error_code& ec) noexcept -{ - return is_fifo(status(p, ec)); -} - -GHC_INLINE bool is_other(file_status s) noexcept -{ - return exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_other(const path& p) -{ - return is_other(status(p)); -} -#endif - -GHC_INLINE bool is_other(const path& p, std::error_code& ec) noexcept -{ - return is_other(status(p, ec)); -} - -GHC_INLINE bool is_regular_file(file_status s) noexcept -{ - return s.type() == file_type::regular; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_regular_file(const path& p) -{ - return is_regular_file(status(p)); -} -#endif - -GHC_INLINE bool is_regular_file(const path& p, std::error_code& ec) noexcept -{ - return is_regular_file(status(p, ec)); -} - -GHC_INLINE bool is_socket(file_status s) noexcept -{ - return s.type() == file_type::socket; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_socket(const path& p) -{ - return is_socket(status(p)); -} -#endif - -GHC_INLINE bool is_socket(const path& p, std::error_code& ec) noexcept -{ - return is_socket(status(p, ec)); -} - -GHC_INLINE bool is_symlink(file_status s) noexcept -{ - return s.type() == file_type::symlink; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_symlink(const path& p) -{ - return is_symlink(symlink_status(p)); -} -#endif - -GHC_INLINE bool is_symlink(const path& p, std::error_code& ec) noexcept -{ - return is_symlink(symlink_status(p, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_time_type last_write_time(const path& p) -{ - std::error_code ec; - auto result = last_write_time(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE file_time_type last_write_time(const path& p, std::error_code& ec) noexcept -{ - time_t result = 0; - ec.clear(); - file_status fs = detail::status_ex(p, ec, nullptr, nullptr, nullptr, &result); - return ec ? (file_time_type::min)() : std::chrono::system_clock::from_time_t(result); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void last_write_time(const path& p, file_time_type new_time) -{ - std::error_code ec; - last_write_time(p, new_time, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::error_code& ec) noexcept -{ - ec.clear(); - auto d = new_time.time_since_epoch(); -#ifdef GHC_OS_WINDOWS - detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)); - FILETIME ft; - auto tt = std::chrono::duration_cast(d).count() * 10 + 116444736000000000; - ft.dwLowDateTime = static_cast(tt); - ft.dwHighDateTime = static_cast(tt >> 32); - if (!::SetFileTime(file.get(), 0, 0, &ft)) { - ec = detail::make_system_error(); - } -#elif defined(GHC_OS_MACOS) -#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED -#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101300 - struct ::stat fs; - if (::stat(p.c_str(), &fs) == 0) { - struct ::timeval tv[2]; - tv[0].tv_sec = fs.st_atimespec.tv_sec; - tv[0].tv_usec = static_cast(fs.st_atimespec.tv_nsec / 1000); - tv[1].tv_sec = std::chrono::duration_cast(d).count(); - tv[1].tv_usec = static_cast(std::chrono::duration_cast(d).count() % 1000000); - if (::utimes(p.c_str(), tv) == 0) { - return; - } - } - ec = detail::make_system_error(); - return; -#else - struct ::timespec times[2]; - times[0].tv_sec = 0; - times[0].tv_nsec = UTIME_OMIT; - times[1].tv_sec = std::chrono::duration_cast(d).count(); - times[1].tv_nsec = 0; // std::chrono::duration_cast(d).count() % 1000000000; - if (::utimensat(AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { - ec = detail::make_system_error(); - } - return; -#endif -#endif -#else -#ifndef UTIME_OMIT -#define UTIME_OMIT ((1l << 30) - 2l) -#endif - struct ::timespec times[2]; - times[0].tv_sec = 0; - times[0].tv_nsec = UTIME_OMIT; - times[1].tv_sec = static_cast(std::chrono::duration_cast(d).count()); - times[1].tv_nsec = static_cast(std::chrono::duration_cast(d).count() % 1000000000); -#if defined(__ANDROID_API__) && __ANDROID_API__ < 12 - if (syscall(__NR_utimensat, AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { -#else - if (::utimensat((int)AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { -#endif - ec = detail::make_system_error(); - } - return; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void permissions(const path& p, perms prms, perm_options opts) -{ - std::error_code ec; - permissions(p, prms, opts, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void permissions(const path& p, perms prms, std::error_code& ec) noexcept -{ - permissions(p, prms, perm_options::replace, ec); -} - -GHC_INLINE void permissions(const path& p, perms prms, perm_options opts, std::error_code& ec) noexcept -{ - if (static_cast(opts & (perm_options::replace | perm_options::add | perm_options::remove)) == 0) { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - return; - } - auto fs = symlink_status(p, ec); - if ((opts & perm_options::replace) != perm_options::replace) { - if ((opts & perm_options::add) == perm_options::add) { - prms = fs.permissions() | prms; - } - else { - prms = fs.permissions() & ~prms; - } - } -#ifdef GHC_OS_WINDOWS -#ifdef __GNUC__ - auto oldAttr = GetFileAttributesW(GHC_NATIVEWP(p)); - if (oldAttr != INVALID_FILE_ATTRIBUTES) { - DWORD newAttr = ((prms & perms::owner_write) == perms::owner_write) ? oldAttr & ~(static_cast(FILE_ATTRIBUTE_READONLY)) : oldAttr | FILE_ATTRIBUTE_READONLY; - if (oldAttr == newAttr || SetFileAttributesW(GHC_NATIVEWP(p), newAttr)) { - return; - } - } - ec = detail::make_system_error(); -#else - int mode = 0; - if ((prms & perms::owner_read) == perms::owner_read) { - mode |= _S_IREAD; - } - if ((prms & perms::owner_write) == perms::owner_write) { - mode |= _S_IWRITE; - } - if (::_wchmod(p.wstring().c_str(), mode) != 0) { - ec = detail::make_system_error(); - } -#endif -#else - if ((opts & perm_options::nofollow) != perm_options::nofollow) { - if (::chmod(p.c_str(), static_cast(prms)) != 0) { - ec = detail::make_system_error(); - } - } -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path proximate(const path& p, std::error_code& ec) -{ - auto cp = current_path(ec); - if (!ec) { - return proximate(p, cp, ec); - } - return path(); -} -#endif - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path proximate(const path& p, const path& base) -{ - return weakly_canonical(p).lexically_proximate(weakly_canonical(base)); -} -#endif - -GHC_INLINE path proximate(const path& p, const path& base, std::error_code& ec) -{ - return weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path read_symlink(const path& p) -{ - std::error_code ec; - auto result = read_symlink(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path read_symlink(const path& p, std::error_code& ec) -{ - file_status fs = symlink_status(p, ec); - if (fs.type() != file_type::symlink) { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - return path(); - } - auto result = detail::resolveSymlink(p, ec); - return ec ? path() : result; -} - -GHC_INLINE path relative(const path& p, std::error_code& ec) -{ - return relative(p, current_path(ec), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path relative(const path& p, const path& base) -{ - return weakly_canonical(p).lexically_relative(weakly_canonical(base)); -} -#endif - -GHC_INLINE path relative(const path& p, const path& base, std::error_code& ec) -{ - return weakly_canonical(p, ec).lexically_relative(weakly_canonical(base, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool remove(const path& p) -{ - std::error_code ec; - auto result = remove(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool remove(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS -#ifdef GHC_USE_WCHAR_T - auto cstr = p.c_str(); -#else - std::wstring np = detail::fromUtf8(p.u8string()); - auto cstr = np.c_str(); -#endif - DWORD attr = GetFileAttributesW(cstr); - if (attr == INVALID_FILE_ATTRIBUTES) { - auto error = ::GetLastError(); - if (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND) { - return false; - } - ec = detail::make_system_error(error); - } - else if (attr & FILE_ATTRIBUTE_READONLY) { - auto new_attr = attr & ~static_cast(FILE_ATTRIBUTE_READONLY); - if (!SetFileAttributesW(cstr, new_attr)) { - auto error = ::GetLastError(); - ec = detail::make_system_error(error); - } - } - if (!ec) { - if (attr & FILE_ATTRIBUTE_DIRECTORY) { - if (!RemoveDirectoryW(cstr)) { - ec = detail::make_system_error(); - } - } - else { - if (!DeleteFileW(cstr)) { - ec = detail::make_system_error(); - } - } - } -#else - if (::remove(p.c_str()) == -1) { - auto error = errno; - if (error == ENOENT) { - return false; - } - ec = detail::make_system_error(); - } -#endif - return ec ? false : true; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t remove_all(const path& p) -{ - std::error_code ec; - auto result = remove_all(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE uintmax_t remove_all(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); - uintmax_t count = 0; - if (p == "/") { - ec = detail::make_error_code(detail::portable_error::not_supported); - return static_cast(-1); - } - std::error_code tec; - auto fs = symlink_status(p, tec); - if (exists(fs) && is_directory(fs)) { - for (auto iter = directory_iterator(p, ec); iter != directory_iterator(); iter.increment(ec)) { - if (ec && !detail::is_not_found_error(ec)) { - break; - } - bool is_symlink_result = iter->is_symlink(ec); - if (ec) - return static_cast(-1); - if (!is_symlink_result && iter->is_directory(ec)) { - count += remove_all(iter->path(), ec); - if (ec) { - return static_cast(-1); - } - } - else { - if (!ec) { - remove(iter->path(), ec); - } - if (ec) { - return static_cast(-1); - } - ++count; - } - } - } - if (!ec) { - if (remove(p, ec)) { - ++count; - } - } - if (ec) { - return static_cast(-1); - } - return count; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void rename(const path& from, const path& to) -{ - std::error_code ec; - rename(from, to, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); - } -} -#endif - -GHC_INLINE void rename(const path& from, const path& to, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (from != to) { - if (!MoveFileExW(GHC_NATIVEWP(from), GHC_NATIVEWP(to), (DWORD)MOVEFILE_REPLACE_EXISTING)) { - ec = detail::make_system_error(); - } - } -#else - if (from != to) { - if (::rename(from.c_str(), to.c_str()) != 0) { - ec = detail::make_system_error(); - } - } -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void resize_file(const path& p, uintmax_t size) -{ - std::error_code ec; - resize_file(p, size, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void resize_file(const path& p, uintmax_t size, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - LARGE_INTEGER lisize; - lisize.QuadPart = static_cast(size); - if (lisize.QuadPart < 0) { -#ifdef ERROR_FILE_TOO_LARGE - ec = detail::make_system_error(ERROR_FILE_TOO_LARGE); -#else - ec = detail::make_system_error(223); -#endif - return; - } - detail::unique_handle file(CreateFileW(GHC_NATIVEWP(p), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)); - if (!file) { - ec = detail::make_system_error(); - } - else if (SetFilePointerEx(file.get(), lisize, NULL, FILE_BEGIN) == 0 || SetEndOfFile(file.get()) == 0) { - ec = detail::make_system_error(); - } -#else - if (::truncate(p.c_str(), static_cast(size)) != 0) { - ec = detail::make_system_error(); - } -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE space_info space(const path& p) -{ - std::error_code ec; - auto result = space(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE space_info space(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - ULARGE_INTEGER freeBytesAvailableToCaller = {{ 0, 0 }}; - ULARGE_INTEGER totalNumberOfBytes = {{ 0, 0 }}; - ULARGE_INTEGER totalNumberOfFreeBytes = {{ 0, 0 }}; - if (!GetDiskFreeSpaceExW(GHC_NATIVEWP(p), &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes)) { - ec = detail::make_system_error(); - return {static_cast(-1), static_cast(-1), static_cast(-1)}; - } - return {static_cast(totalNumberOfBytes.QuadPart), static_cast(totalNumberOfFreeBytes.QuadPart), static_cast(freeBytesAvailableToCaller.QuadPart)}; -#else - struct ::statvfs sfs; - if (::statvfs(p.c_str(), &sfs) != 0) { - ec = detail::make_system_error(); - return {static_cast(-1), static_cast(-1), static_cast(-1)}; - } - return {static_cast(sfs.f_blocks) * static_cast(sfs.f_frsize), static_cast(sfs.f_bfree) * static_cast(sfs.f_frsize), static_cast(sfs.f_bavail) * static_cast(sfs.f_frsize)}; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status status(const path& p) -{ - std::error_code ec; - auto result = status(p, ec); - if (result.type() == file_type::none) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE file_status status(const path& p, std::error_code& ec) noexcept -{ - return detail::status_ex(p, ec); -} - -GHC_INLINE bool status_known(file_status s) noexcept -{ - return s.type() != file_type::none; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status symlink_status(const path& p) -{ - std::error_code ec; - auto result = symlink_status(p, ec); - if (result.type() == file_type::none) { - throw filesystem_error(detail::systemErrorText(ec.value()), ec); - } - return result; -} -#endif - -GHC_INLINE file_status symlink_status(const path& p, std::error_code& ec) noexcept -{ - return detail::symlink_status_ex(p, ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path temp_directory_path() -{ - std::error_code ec; - path result = temp_directory_path(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), ec); - } - return result; -} -#endif - -GHC_INLINE path temp_directory_path(std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - wchar_t buffer[512]; - auto rc = GetTempPathW(511, buffer); - if (!rc || rc > 511) { - ec = detail::make_system_error(); - return path(); - } - return path(std::wstring(buffer)); -#else - static const char* temp_vars[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR", nullptr}; - const char* temp_path = nullptr; - for (auto temp_name = temp_vars; *temp_name != nullptr; ++temp_name) { - temp_path = std::getenv(*temp_name); - if (temp_path) { - return path(temp_path); - } - } - return path("/tmp"); -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path weakly_canonical(const path& p) -{ - std::error_code ec; - auto result = weakly_canonical(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path weakly_canonical(const path& p, std::error_code& ec) noexcept -{ - path result; - ec.clear(); - bool scan = true; - for (auto pe : p) { - if (scan) { - std::error_code tec; - if (exists(result / pe, tec)) { - result /= pe; - } - else { - if (ec) { - return path(); - } - scan = false; - if (!result.empty()) { - result = canonical(result, ec) / pe; - if (ec) { - break; - } - } - else { - result /= pe; - } - } - } - else { - result /= pe; - } - } - if (scan) { - if (!result.empty()) { - result = canonical(result, ec); - } - } - return ec ? path() : result.lexically_normal(); -} - -//----------------------------------------------------------------------------- -// [fs.class.file_status] class file_status -// [fs.file_status.cons] constructors and destructor -GHC_INLINE file_status::file_status() noexcept - : file_status(file_type::none) -{ -} - -GHC_INLINE file_status::file_status(file_type ft, perms prms) noexcept - : _type(ft) - , _perms(prms) -{ -} - -GHC_INLINE file_status::file_status(const file_status& other) noexcept - : _type(other._type) - , _perms(other._perms) -{ -} - -GHC_INLINE file_status::file_status(file_status&& other) noexcept - : _type(other._type) - , _perms(other._perms) -{ -} - -GHC_INLINE file_status::~file_status() {} - -// assignments: -GHC_INLINE file_status& file_status::operator=(const file_status& rhs) noexcept -{ - _type = rhs._type; - _perms = rhs._perms; - return *this; -} - -GHC_INLINE file_status& file_status::operator=(file_status&& rhs) noexcept -{ - _type = rhs._type; - _perms = rhs._perms; - return *this; -} - -// [fs.file_status.mods] modifiers -GHC_INLINE void file_status::type(file_type ft) noexcept -{ - _type = ft; -} - -GHC_INLINE void file_status::permissions(perms prms) noexcept -{ - _perms = prms; -} - -// [fs.file_status.obs] observers -GHC_INLINE file_type file_status::type() const noexcept -{ - return _type; -} - -GHC_INLINE perms file_status::permissions() const noexcept -{ - return _perms; -} - -//----------------------------------------------------------------------------- -// [fs.class.directory_entry] class directory_entry -// [fs.dir.entry.cons] constructors and destructor -// directory_entry::directory_entry() noexcept = default; -// directory_entry::directory_entry(const directory_entry&) = default; -// directory_entry::directory_entry(directory_entry&&) noexcept = default; -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE directory_entry::directory_entry(const filesystem::path& p) - : _path(p) - , _file_size(static_cast(-1)) -#ifndef GHC_OS_WINDOWS - , _hard_link_count(static_cast(-1)) -#endif - , _last_write_time(0) -{ - refresh(); -} -#endif - -GHC_INLINE directory_entry::directory_entry(const filesystem::path& p, std::error_code& ec) - : _path(p) - , _file_size(static_cast(-1)) -#ifndef GHC_OS_WINDOWS - , _hard_link_count(static_cast(-1)) -#endif - , _last_write_time(0) -{ - refresh(ec); -} - -GHC_INLINE directory_entry::~directory_entry() {} - -// assignments: -// directory_entry& directory_entry::operator=(const directory_entry&) = default; -// directory_entry& directory_entry::operator=(directory_entry&&) noexcept = default; - -// [fs.dir.entry.mods] directory_entry modifiers -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void directory_entry::assign(const filesystem::path& p) -{ - _path = p; - refresh(); -} -#endif - -GHC_INLINE void directory_entry::assign(const filesystem::path& p, std::error_code& ec) -{ - _path = p; - refresh(ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void directory_entry::replace_filename(const filesystem::path& p) -{ - _path.replace_filename(p); - refresh(); -} -#endif - -GHC_INLINE void directory_entry::replace_filename(const filesystem::path& p, std::error_code& ec) -{ - _path.replace_filename(p); - refresh(ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void directory_entry::refresh() -{ - std::error_code ec; - refresh(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), _path, ec); - } -} -#endif - -GHC_INLINE void directory_entry::refresh(std::error_code& ec) noexcept -{ -#ifdef GHC_OS_WINDOWS - _status = detail::status_ex(_path, ec, &_symlink_status, &_file_size, nullptr, &_last_write_time); -#else - _status = detail::status_ex(_path, ec, &_symlink_status, &_file_size, &_hard_link_count, &_last_write_time); -#endif -} - -// [fs.dir.entry.obs] directory_entry observers -GHC_INLINE const filesystem::path& directory_entry::path() const noexcept -{ - return _path; -} - -GHC_INLINE directory_entry::operator const filesystem::path&() const noexcept -{ - return _path; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_type directory_entry::status_file_type() const -{ - return _status.type() != file_type::none ? _status.type() : filesystem::status(path()).type(); -} -#endif - -GHC_INLINE file_type directory_entry::status_file_type(std::error_code& ec) const noexcept -{ - if (_status.type() != file_type::none) { - ec.clear(); - return _status.type(); - } - return filesystem::status(path(), ec).type(); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::exists() const -{ - return status_file_type() != file_type::not_found; -} -#endif - -GHC_INLINE bool directory_entry::exists(std::error_code& ec) const noexcept -{ - return status_file_type(ec) != file_type::not_found; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_block_file() const -{ - return status_file_type() == file_type::block; -} -#endif -GHC_INLINE bool directory_entry::is_block_file(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::block; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_character_file() const -{ - return status_file_type() == file_type::character; -} -#endif - -GHC_INLINE bool directory_entry::is_character_file(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::character; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_directory() const -{ - return status_file_type() == file_type::directory; -} -#endif - -GHC_INLINE bool directory_entry::is_directory(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::directory; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_fifo() const -{ - return status_file_type() == file_type::fifo; -} -#endif - -GHC_INLINE bool directory_entry::is_fifo(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::fifo; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_other() const -{ - auto ft = status_file_type(); - return ft != file_type::none && ft != file_type::not_found && ft != file_type::regular && ft != file_type::directory && !is_symlink(); -} -#endif - -GHC_INLINE bool directory_entry::is_other(std::error_code& ec) const noexcept -{ - auto ft = status_file_type(ec); - bool other = ft != file_type::none && ft != file_type::not_found && ft != file_type::regular && ft != file_type::directory && !is_symlink(ec); - return !ec && other; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_regular_file() const -{ - return status_file_type() == file_type::regular; -} -#endif - -GHC_INLINE bool directory_entry::is_regular_file(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::regular; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_socket() const -{ - return status_file_type() == file_type::socket; -} -#endif - -GHC_INLINE bool directory_entry::is_socket(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::socket; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_symlink() const -{ - return _symlink_status.type() != file_type::none ? _symlink_status.type() == file_type::symlink : filesystem::is_symlink(symlink_status()); -} -#endif - -GHC_INLINE bool directory_entry::is_symlink(std::error_code& ec) const noexcept -{ - if (_symlink_status.type() != file_type::none) { - ec.clear(); - return _symlink_status.type() == file_type::symlink; - } - return filesystem::is_symlink(symlink_status(ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t directory_entry::file_size() const -{ - if (_file_size != static_cast(-1)) { - return _file_size; - } - return filesystem::file_size(path()); -} -#endif - -GHC_INLINE uintmax_t directory_entry::file_size(std::error_code& ec) const noexcept -{ - if (_file_size != static_cast(-1)) { - ec.clear(); - return _file_size; - } - return filesystem::file_size(path(), ec); -} - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t directory_entry::hard_link_count() const -{ -#ifndef GHC_OS_WINDOWS - if (_hard_link_count != static_cast(-1)) { - return _hard_link_count; - } -#endif - return filesystem::hard_link_count(path()); -} -#endif - -GHC_INLINE uintmax_t directory_entry::hard_link_count(std::error_code& ec) const noexcept -{ -#ifndef GHC_OS_WINDOWS - if (_hard_link_count != static_cast(-1)) { - ec.clear(); - return _hard_link_count; - } -#endif - return filesystem::hard_link_count(path(), ec); -} -#endif - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_time_type directory_entry::last_write_time() const -{ - if (_last_write_time != 0) { - return std::chrono::system_clock::from_time_t(_last_write_time); - } - return filesystem::last_write_time(path()); -} -#endif - -GHC_INLINE file_time_type directory_entry::last_write_time(std::error_code& ec) const noexcept -{ - if (_last_write_time != 0) { - ec.clear(); - return std::chrono::system_clock::from_time_t(_last_write_time); - } - return filesystem::last_write_time(path(), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status directory_entry::status() const -{ - if (_status.type() != file_type::none && _status.permissions() != perms::unknown) { - return _status; - } - return filesystem::status(path()); -} -#endif - -GHC_INLINE file_status directory_entry::status(std::error_code& ec) const noexcept -{ - if (_status.type() != file_type::none && _status.permissions() != perms::unknown) { - ec.clear(); - return _status; - } - return filesystem::status(path(), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status directory_entry::symlink_status() const -{ - if (_symlink_status.type() != file_type::none && _symlink_status.permissions() != perms::unknown) { - return _symlink_status; - } - return filesystem::symlink_status(path()); -} -#endif - -GHC_INLINE file_status directory_entry::symlink_status(std::error_code& ec) const noexcept -{ - if (_symlink_status.type() != file_type::none && _symlink_status.permissions() != perms::unknown) { - ec.clear(); - return _symlink_status; - } - return filesystem::symlink_status(path(), ec); -} - -#ifdef GHC_HAS_THREEWAY_COMP -GHC_INLINE std::strong_ordering directory_entry::operator<=>(const directory_entry& rhs) const noexcept -{ - return _path <=> rhs._path; -} -#endif - -GHC_INLINE bool directory_entry::operator<(const directory_entry& rhs) const noexcept -{ - return _path < rhs._path; -} - -GHC_INLINE bool directory_entry::operator==(const directory_entry& rhs) const noexcept -{ - return _path == rhs._path; -} - -GHC_INLINE bool directory_entry::operator!=(const directory_entry& rhs) const noexcept -{ - return _path != rhs._path; -} - -GHC_INLINE bool directory_entry::operator<=(const directory_entry& rhs) const noexcept -{ - return _path <= rhs._path; -} - -GHC_INLINE bool directory_entry::operator>(const directory_entry& rhs) const noexcept -{ - return _path > rhs._path; -} - -GHC_INLINE bool directory_entry::operator>=(const directory_entry& rhs) const noexcept -{ - return _path >= rhs._path; -} - -//----------------------------------------------------------------------------- -// [fs.class.directory_iterator] class directory_iterator - -#ifdef GHC_OS_WINDOWS -class directory_iterator::impl -{ -public: - impl(const path& p, directory_options options) - : _base(p) - , _options(options) - , _dirHandle(INVALID_HANDLE_VALUE) - { - if (!_base.empty()) { - ZeroMemory(&_findData, sizeof(WIN32_FIND_DATAW)); - if ((_dirHandle = FindFirstFileW(GHC_NATIVEWP((_base / "*")), &_findData)) != INVALID_HANDLE_VALUE) { - if (std::wstring(_findData.cFileName) == L"." || std::wstring(_findData.cFileName) == L"..") { - increment(_ec); - } - else { - _dir_entry._path = _base / std::wstring(_findData.cFileName); - copyToDirEntry(_ec); - } - } - else { - auto error = ::GetLastError(); - _base = filesystem::path(); - if (error != ERROR_ACCESS_DENIED || (options & directory_options::skip_permission_denied) == directory_options::none) { - _ec = detail::make_system_error(); - } - } - } - } - impl(const impl& other) = delete; - ~impl() - { - if (_dirHandle != INVALID_HANDLE_VALUE) { - FindClose(_dirHandle); - _dirHandle = INVALID_HANDLE_VALUE; - } - } - void increment(std::error_code& ec) - { - if (_dirHandle != INVALID_HANDLE_VALUE) { - do { - if (FindNextFileW(_dirHandle, &_findData)) { - _dir_entry._path = _base; -#ifdef GHC_USE_WCHAR_T - _dir_entry._path.append_name(_findData.cFileName); -#else -#ifdef GHC_RAISE_UNICODE_ERRORS - try { - _dir_entry._path.append_name(detail::toUtf8(_findData.cFileName).c_str()); - } - catch (filesystem_error& fe) { - ec = fe.code(); - return; - } -#else - _dir_entry._path.append_name(detail::toUtf8(_findData.cFileName).c_str()); -#endif -#endif - copyToDirEntry(ec); - } - else { - auto err = ::GetLastError(); - if (err != ERROR_NO_MORE_FILES) { - _ec = ec = detail::make_system_error(err); - } - FindClose(_dirHandle); - _dirHandle = INVALID_HANDLE_VALUE; - _dir_entry._path.clear(); - break; - } - } while (std::wstring(_findData.cFileName) == L"." || std::wstring(_findData.cFileName) == L".."); - } - else { - ec = _ec; - } - } - void copyToDirEntry(std::error_code& ec) - { - if (_findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - _dir_entry._status = detail::status_ex(_dir_entry._path, ec, &_dir_entry._symlink_status, &_dir_entry._file_size, nullptr, &_dir_entry._last_write_time); - } - else { - _dir_entry._status = detail::status_from_INFO(_dir_entry._path, &_findData, ec, &_dir_entry._file_size, &_dir_entry._last_write_time); - _dir_entry._symlink_status = _dir_entry._status; - } - if (ec) { - if (_dir_entry._status.type() != file_type::none && _dir_entry._symlink_status.type() != file_type::none) { - ec.clear(); - } - else { - _dir_entry._file_size = static_cast(-1); - _dir_entry._last_write_time = 0; - } - } - } - path _base; - directory_options _options; - WIN32_FIND_DATAW _findData; - HANDLE _dirHandle; - directory_entry _dir_entry; - std::error_code _ec; -}; -#else -// POSIX implementation -class directory_iterator::impl -{ -public: - impl(const path& path, directory_options options) - : _base(path) - , _options(options) - , _dir(nullptr) - , _entry(nullptr) - { - if (!path.empty()) { - _dir = ::opendir(path.native().c_str()); - if (!_dir) { - auto error = errno; - _base = filesystem::path(); - if ((error != EACCES && error != EPERM) || (options & directory_options::skip_permission_denied) == directory_options::none) { - _ec = detail::make_system_error(); - } - } - else { - increment(_ec); - } - } - } - impl(const impl& other) = delete; - ~impl() - { - if (_dir) { - ::closedir(_dir); - } - } - void increment(std::error_code& ec) - { - if (_dir) { - bool skip; - do { - skip = false; - errno = 0; - _entry = ::readdir(_dir); - if (_entry) { - _dir_entry._path = _base; - _dir_entry._path.append_name(_entry->d_name); - copyToDirEntry(); - if (ec && (ec.value() == EACCES || ec.value() == EPERM) && (_options & directory_options::skip_permission_denied) == directory_options::skip_permission_denied) { - ec.clear(); - skip = true; - } - } - else { - ::closedir(_dir); - _dir = nullptr; - _dir_entry._path.clear(); - if (errno) { - ec = detail::make_system_error(); - } - break; - } - } while (skip || std::strcmp(_entry->d_name, ".") == 0 || std::strcmp(_entry->d_name, "..") == 0); - } - } - - void copyToDirEntry() - { - _dir_entry._symlink_status.permissions(perms::unknown); - auto ft = detail::file_type_from_dirent(*_entry); - _dir_entry._symlink_status.type(ft); - if (ft != file_type::symlink) { - _dir_entry._status = _dir_entry._symlink_status; - } - else { - _dir_entry._status.type(file_type::none); - _dir_entry._status.permissions(perms::unknown); - } - _dir_entry._file_size = static_cast(-1); - _dir_entry._hard_link_count = static_cast(-1); - _dir_entry._last_write_time = 0; - } - path _base; - directory_options _options; - DIR* _dir; - struct ::dirent* _entry; - directory_entry _dir_entry; - std::error_code _ec; -}; -#endif - -// [fs.dir.itr.members] member functions -GHC_INLINE directory_iterator::directory_iterator() noexcept - : _impl(new impl(path(), directory_options::none)) -{ -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE directory_iterator::directory_iterator(const path& p) - : _impl(new impl(p, directory_options::none)) -{ - if (_impl->_ec) { - throw filesystem_error(detail::systemErrorText(_impl->_ec.value()), p, _impl->_ec); - } - _impl->_ec.clear(); -} - -GHC_INLINE directory_iterator::directory_iterator(const path& p, directory_options options) - : _impl(new impl(p, options)) -{ - if (_impl->_ec) { - throw filesystem_error(detail::systemErrorText(_impl->_ec.value()), p, _impl->_ec); - } -} -#endif - -GHC_INLINE directory_iterator::directory_iterator(const path& p, std::error_code& ec) noexcept - : _impl(new impl(p, directory_options::none)) -{ - if (_impl->_ec) { - ec = _impl->_ec; - } -} - -GHC_INLINE directory_iterator::directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept - : _impl(new impl(p, options)) -{ - if (_impl->_ec) { - ec = _impl->_ec; - } -} - -GHC_INLINE directory_iterator::directory_iterator(const directory_iterator& rhs) - : _impl(rhs._impl) -{ -} - -GHC_INLINE directory_iterator::directory_iterator(directory_iterator&& rhs) noexcept - : _impl(std::move(rhs._impl)) -{ -} - -GHC_INLINE directory_iterator::~directory_iterator() {} - -GHC_INLINE directory_iterator& directory_iterator::operator=(const directory_iterator& rhs) -{ - _impl = rhs._impl; - return *this; -} - -GHC_INLINE directory_iterator& directory_iterator::operator=(directory_iterator&& rhs) noexcept -{ - _impl = std::move(rhs._impl); - return *this; -} - -GHC_INLINE const directory_entry& directory_iterator::operator*() const -{ - return _impl->_dir_entry; -} - -GHC_INLINE const directory_entry* directory_iterator::operator->() const -{ - return &_impl->_dir_entry; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE directory_iterator& directory_iterator::operator++() -{ - std::error_code ec; - _impl->increment(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_entry._path, ec); - } - return *this; -} -#endif - -GHC_INLINE directory_iterator& directory_iterator::increment(std::error_code& ec) noexcept -{ - _impl->increment(ec); - return *this; -} - -GHC_INLINE bool directory_iterator::operator==(const directory_iterator& rhs) const -{ - return _impl->_dir_entry._path == rhs._impl->_dir_entry._path; -} - -GHC_INLINE bool directory_iterator::operator!=(const directory_iterator& rhs) const -{ - return _impl->_dir_entry._path != rhs._impl->_dir_entry._path; -} - -// [fs.dir.itr.nonmembers] directory_iterator non-member functions - -GHC_INLINE directory_iterator begin(directory_iterator iter) noexcept -{ - return iter; -} - -GHC_INLINE directory_iterator end(const directory_iterator&) noexcept -{ - return directory_iterator(); -} - -//----------------------------------------------------------------------------- -// [fs.class.rec.dir.itr] class recursive_directory_iterator - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator() noexcept - : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator()); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p) - : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p)); -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, directory_options options) - : _impl(new recursive_directory_iterator_impl(options, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p, options)); -} -#endif - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept - : _impl(new recursive_directory_iterator_impl(options, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p, options, ec)); -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, std::error_code& ec) noexcept - : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p, ec)); -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const recursive_directory_iterator& rhs) - : _impl(rhs._impl) -{ -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept - : _impl(std::move(rhs._impl)) -{ -} - -GHC_INLINE recursive_directory_iterator::~recursive_directory_iterator() {} - -// [fs.rec.dir.itr.members] observers -GHC_INLINE directory_options recursive_directory_iterator::options() const -{ - return _impl->_options; -} - -GHC_INLINE int recursive_directory_iterator::depth() const -{ - return static_cast(_impl->_dir_iter_stack.size() - 1); -} - -GHC_INLINE bool recursive_directory_iterator::recursion_pending() const -{ - return _impl->_recursion_pending; -} - -GHC_INLINE const directory_entry& recursive_directory_iterator::operator*() const -{ - return *(_impl->_dir_iter_stack.top()); -} - -GHC_INLINE const directory_entry* recursive_directory_iterator::operator->() const -{ - return &(*(_impl->_dir_iter_stack.top())); -} - -// [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=(const recursive_directory_iterator& rhs) -{ - _impl = rhs._impl; - return *this; -} - -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=(recursive_directory_iterator&& rhs) noexcept -{ - _impl = std::move(rhs._impl); - return *this; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator++() -{ - std::error_code ec; - increment(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_iter_stack.empty() ? path() : _impl->_dir_iter_stack.top()->path(), ec); - } - return *this; -} -#endif - -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::increment(std::error_code& ec) noexcept -{ - bool isSymLink = (*this)->is_symlink(ec); - bool isDir = !ec && (*this)->is_directory(ec); - if (isSymLink && detail::is_not_found_error(ec)) { - ec.clear(); - } - if (!ec) { - if (recursion_pending() && isDir && (!isSymLink || (options() & directory_options::follow_directory_symlink) != directory_options::none)) { - _impl->_dir_iter_stack.push(directory_iterator((*this)->path(), _impl->_options, ec)); - } - else { - _impl->_dir_iter_stack.top().increment(ec); - } - if (!ec) { - while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()) { - _impl->_dir_iter_stack.pop(); - _impl->_dir_iter_stack.top().increment(ec); - } - } - else if (!_impl->_dir_iter_stack.empty()) { - _impl->_dir_iter_stack.pop(); - } - _impl->_recursion_pending = true; - } - return *this; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void recursive_directory_iterator::pop() -{ - std::error_code ec; - pop(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_iter_stack.empty() ? path() : _impl->_dir_iter_stack.top()->path(), ec); - } -} -#endif - -GHC_INLINE void recursive_directory_iterator::pop(std::error_code& ec) -{ - if (depth() == 0) { - *this = recursive_directory_iterator(); - } - else { - do { - _impl->_dir_iter_stack.pop(); - _impl->_dir_iter_stack.top().increment(ec); - } while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()); - } -} - -GHC_INLINE void recursive_directory_iterator::disable_recursion_pending() -{ - _impl->_recursion_pending = false; -} - -// other members as required by [input.iterators] -GHC_INLINE bool recursive_directory_iterator::operator==(const recursive_directory_iterator& rhs) const -{ - return _impl->_dir_iter_stack.top() == rhs._impl->_dir_iter_stack.top(); -} - -GHC_INLINE bool recursive_directory_iterator::operator!=(const recursive_directory_iterator& rhs) const -{ - return _impl->_dir_iter_stack.top() != rhs._impl->_dir_iter_stack.top(); -} - -// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions -GHC_INLINE recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept -{ - return iter; -} - -GHC_INLINE recursive_directory_iterator end(const recursive_directory_iterator&) noexcept -{ - return recursive_directory_iterator(); -} - -#endif // GHC_EXPAND_IMPL - -} // namespace filesystem -} // namespace ghc - -// cleanup some macros -#undef GHC_INLINE -#undef GHC_EXPAND_IMPL - -#endif // GHC_FILESYSTEM_H diff --git a/libfuse/lib/node.hpp b/libfuse/lib/node.hpp index 6449bbea..73d7cb97 100644 --- a/libfuse/lib/node.hpp +++ b/libfuse/lib/node.hpp @@ -16,7 +16,6 @@ struct node_s uint64_t nlookup; uint32_t refctr; uint32_t open_count; - uint64_t hidden_fh; int32_t treelock; lock_t *locks; diff --git a/src/boost/assert.hpp b/src/boost/assert.hpp new file mode 100644 index 00000000..48c9bccc --- /dev/null +++ b/src/boost/assert.hpp @@ -0,0 +1,91 @@ +// +// boost/assert.hpp - BOOST_ASSERT(expr) +// BOOST_ASSERT_MSG(expr, msg) +// BOOST_VERIFY(expr) +// BOOST_VERIFY_MSG(expr, msg) +// BOOST_ASSERT_IS_VOID +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007, 2014 Peter Dimov +// Copyright (c) Beman Dawes 2011 +// Copyright (c) 2015 Ion Gaztanaga +// +// 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 +// +// Note: There are no include guards. This is intentional. +// +// See http://www.boost.org/libs/assert/assert.html for documentation. +// + +// +// Stop inspect complaining about use of 'assert': +// +// boostinspect:naassert_macro +// + +// +// BOOST_ASSERT, BOOST_ASSERT_MSG, BOOST_ASSERT_IS_VOID +// + +#undef BOOST_ASSERT +#undef BOOST_ASSERT_MSG +#undef BOOST_ASSERT_IS_VOID + +#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ) + +# define BOOST_ASSERT(expr) ((void)0) +# define BOOST_ASSERT_MSG(expr, msg) ((void)0) +# define BOOST_ASSERT_IS_VOID + +#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) ) + +#include // for BOOST_LIKELY +#include + +namespace boost +{ +#if defined(BOOST_ASSERT_HANDLER_IS_NORETURN) + BOOST_NORETURN +#endif + void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined +#if defined(BOOST_ASSERT_HANDLER_IS_NORETURN) + BOOST_NORETURN +#endif + void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined +} // namespace boost + +#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) +#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) + +#else + +# include // .h to support old libraries w/o - effect is the same + +# define BOOST_ASSERT(expr) assert(expr) +# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) +#if defined(NDEBUG) +# define BOOST_ASSERT_IS_VOID +#endif + +#endif + +// +// BOOST_VERIFY, BOOST_VERIFY_MSG +// + +#undef BOOST_VERIFY +#undef BOOST_VERIFY_MSG + +#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) + +# define BOOST_VERIFY(expr) ((void)(expr)) +# define BOOST_VERIFY_MSG(expr, msg) ((void)(expr)) + +#else + +# define BOOST_VERIFY(expr) BOOST_ASSERT(expr) +# define BOOST_VERIFY_MSG(expr, msg) BOOST_ASSERT_MSG(expr,msg) + +#endif diff --git a/src/boost/assert/source_location.hpp b/src/boost/assert/source_location.hpp new file mode 100644 index 00000000..3c2d60e6 --- /dev/null +++ b/src/boost/assert/source_location.hpp @@ -0,0 +1,204 @@ +#ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED +#define BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED + +// http://www.boost.org/libs/assert +// +// Copyright 2019, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_IOSTREAM) +#include +#endif + +#if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L +# include +#endif + +namespace boost +{ + +struct source_location +{ +private: + + char const * file_; + char const * function_; + boost::uint_least32_t line_; + boost::uint_least32_t column_; + +public: + + BOOST_CONSTEXPR source_location() BOOST_NOEXCEPT: file_( "" ), function_( "" ), line_( 0 ), column_( 0 ) + { + } + + BOOST_CONSTEXPR source_location( char const * file, boost::uint_least32_t ln, char const * function, boost::uint_least32_t col = 0 ) BOOST_NOEXCEPT: file_( file ), function_( function ), line_( ln ), column_( col ) + { + } + +#if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L + + BOOST_CONSTEXPR source_location( std::source_location const& loc ) BOOST_NOEXCEPT: file_( loc.file_name() ), function_( loc.function_name() ), line_( loc.line() ), column_( loc.column() ) + { + } + +#endif + + BOOST_CONSTEXPR char const * file_name() const BOOST_NOEXCEPT + { + return file_; + } + + BOOST_CONSTEXPR char const * function_name() const BOOST_NOEXCEPT + { + return function_; + } + + BOOST_CONSTEXPR boost::uint_least32_t line() const BOOST_NOEXCEPT + { + return line_; + } + + BOOST_CONSTEXPR boost::uint_least32_t column() const BOOST_NOEXCEPT + { + return column_; + } + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable: 4996 ) +#endif + +#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) ) +# define BOOST_ASSERT_SNPRINTF(buffer, format, arg) std::sprintf(buffer, format, arg) +#else +# define BOOST_ASSERT_SNPRINTF(buffer, format, arg) std::snprintf(buffer, sizeof(buffer)/sizeof(buffer[0]), format, arg) +#endif + + std::string to_string() const + { + unsigned long ln = line(); + + if( ln == 0 ) + { + return "(unknown source location)"; + } + + std::string r = file_name(); + + char buffer[ 16 ]; + + BOOST_ASSERT_SNPRINTF( buffer, ":%lu", ln ); + r += buffer; + + unsigned long co = column(); + + if( co ) + { + BOOST_ASSERT_SNPRINTF( buffer, ":%lu", co ); + r += buffer; + } + + char const* fn = function_name(); + + if( *fn != 0 ) + { + r += " in function '"; + r += fn; + r += '\''; + } + + return r; + } + +#undef BOOST_ASSERT_SNPRINTF + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif + + inline friend bool operator==( source_location const& s1, source_location const& s2 ) BOOST_NOEXCEPT + { + return std::strcmp( s1.file_, s2.file_ ) == 0 && std::strcmp( s1.function_, s2.function_ ) == 0 && s1.line_ == s2.line_ && s1.column_ == s2.column_; + } + + inline friend bool operator!=( source_location const& s1, source_location const& s2 ) BOOST_NOEXCEPT + { + return !( s1 == s2 ); + } +}; + +#if !defined(BOOST_NO_IOSTREAM) + +template std::basic_ostream & operator<<( std::basic_ostream & os, source_location const & loc ) +{ + os << loc.to_string(); + return os; +} + +#endif + +} // namespace boost + +#if defined(BOOST_DISABLE_CURRENT_LOCATION) + +# define BOOST_CURRENT_LOCATION ::boost::source_location() + +#elif defined(BOOST_MSVC) && BOOST_MSVC >= 1935 + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCSIG(), __builtin_COLUMN()) + +#elif defined(BOOST_MSVC) && BOOST_MSVC >= 1926 + +// std::source_location::current() is available in -std:c++20, but fails with consteval errors before 19.31, and doesn't produce +// the correct result under 19.31, so prefer the built-ins +# define BOOST_CURRENT_LOCATION ::boost::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION(), __builtin_COLUMN()) + +#elif defined(BOOST_MSVC) + +// __LINE__ is not a constant expression under /ZI (edit and continue) for 1925 and before + +# define BOOST_CURRENT_LOCATION_IMPL_1(x) BOOST_CURRENT_LOCATION_IMPL_2(x) +# define BOOST_CURRENT_LOCATION_IMPL_2(x) (x##0 / 10) + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, BOOST_CURRENT_LOCATION_IMPL_1(__LINE__), "") + +#elif defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L && !defined(__NVCC__) + +// Under nvcc, __builtin_source_location is not constexpr +// https://github.com/boostorg/assert/issues/32 + +# define BOOST_CURRENT_LOCATION ::boost::source_location(::std::source_location::current()) + +#elif defined(BOOST_CLANG) && BOOST_CLANG_VERSION >= 90000 + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION(), __builtin_COLUMN()) + +#elif defined(BOOST_GCC) && BOOST_GCC >= 80000 + +// The built-ins are available in 4.8+, but are not constant expressions until 7 +// In addition, reproducible builds require -ffile-prefix-map, which is GCC 8 +// https://github.com/boostorg/assert/issues/38 + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION()) + +#elif defined(BOOST_GCC) && BOOST_GCC >= 50000 + +// __PRETTY_FUNCTION__ is allowed outside functions under GCC, but 4.x suffers from codegen bugs +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, __PRETTY_FUNCTION__) + +#else + +// __func__ macros aren't allowed outside functions, but BOOST_CURRENT_LOCATION is +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, "") + +#endif + +#endif // #ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED diff --git a/src/boost/config.hpp b/src/boost/config.hpp new file mode 100644 index 00000000..f00a9805 --- /dev/null +++ b/src/boost/config.hpp @@ -0,0 +1,67 @@ +// Boost config.hpp configuration header file ------------------------------// + +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are 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/libs/config for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config +// +// CAUTION: This file is intended to be completely stable - +// DO NOT MODIFY THIS FILE! +// + +#ifndef BOOST_CONFIG_HPP +#define BOOST_CONFIG_HPP + +// if we don't have a user config, then use the default location: +#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) +# define BOOST_USER_CONFIG +#if 0 +// For dependency trackers: +# include +#endif +#endif +// include it first: +#ifdef BOOST_USER_CONFIG +# include BOOST_USER_CONFIG +#endif + +// if we don't have a compiler config set, try and find one: +#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a compiler config, include it now: +#ifdef BOOST_COMPILER_CONFIG +# include BOOST_COMPILER_CONFIG +#endif + +// if we don't have a std library config set, try and find one: +#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) && defined(__cplusplus) +# include +#endif +// if we have a std library config, include it now: +#ifdef BOOST_STDLIB_CONFIG +# include BOOST_STDLIB_CONFIG +#endif + +// if we don't have a platform config set, try and find one: +#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a platform config, include it now: +#ifdef BOOST_PLATFORM_CONFIG +# include BOOST_PLATFORM_CONFIG +#endif + +// get config suffix code: +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_CONFIG_HPP diff --git a/src/boost/config/abi/borland_prefix.hpp b/src/boost/config/abi/borland_prefix.hpp new file mode 100644 index 00000000..3a0e5ae2 --- /dev/null +++ b/src/boost/config/abi/borland_prefix.hpp @@ -0,0 +1,27 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are 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) + +// for C++ Builder the following options effect the ABI: +// +// -b (on or off - effect emum sizes) +// -Vx (on or off - empty members) +// -Ve (on or off - empty base classes) +// -aX (alignment - 5 options). +// -pX (Calling convention - 4 options) +// -VmX (member pointer size and layout - 5 options) +// -VC (on or off, changes name mangling) +// -Vl (on or off, changes struct layout). + +// In addition the following warnings are sufficiently annoying (and +// unfixable) to have them turned off by default: +// +// 8027 - functions containing [for|while] loops are not expanded inline +// 8026 - functions taking class by value arguments are not expanded inline + +#pragma nopushoptwarn +# pragma option push -a8 -Vx- -Ve- -b- -pc -Vmv -VC- -Vl- -w-8027 -w-8026 + + + diff --git a/src/boost/config/abi/borland_suffix.hpp b/src/boost/config/abi/borland_suffix.hpp new file mode 100644 index 00000000..940535f3 --- /dev/null +++ b/src/boost/config/abi/borland_suffix.hpp @@ -0,0 +1,12 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are 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) + +# pragma option pop +#pragma nopushoptwarn + + + + + diff --git a/src/boost/config/abi/msvc_prefix.hpp b/src/boost/config/abi/msvc_prefix.hpp new file mode 100644 index 00000000..97f06cdc --- /dev/null +++ b/src/boost/config/abi/msvc_prefix.hpp @@ -0,0 +1,22 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are 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) + +// +// Boost binaries are built with the compiler's default ABI settings, +// if the user changes their default alignment in the VS IDE then their +// code will no longer be binary compatible with the bjam built binaries +// unless this header is included to force Boost code into a consistent ABI. +// +// Note that inclusion of this header is only necessary for libraries with +// separate source, header only libraries DO NOT need this as long as all +// translation units are built with the same options. +// +#if defined(_M_X64) +# pragma pack(push,16) +#else +# pragma pack(push,8) +#endif + + diff --git a/src/boost/config/abi/msvc_suffix.hpp b/src/boost/config/abi/msvc_suffix.hpp new file mode 100644 index 00000000..a64d783e --- /dev/null +++ b/src/boost/config/abi/msvc_suffix.hpp @@ -0,0 +1,8 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are 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) + +#pragma pack(pop) + + diff --git a/src/boost/config/abi_prefix.hpp b/src/boost/config/abi_prefix.hpp new file mode 100644 index 00000000..bcdc26d9 --- /dev/null +++ b/src/boost/config/abi_prefix.hpp @@ -0,0 +1,25 @@ +// abi_prefix header -------------------------------------------------------// + +// (c) Copyright John Maddock 2003 + +// Use, modification and distribution are 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). + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# define BOOST_CONFIG_ABI_PREFIX_HPP +#else +# error double inclusion of header boost/config/abi_prefix.hpp is an error +#endif + +#include + +// this must occur after all other includes and before any code appears: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +#if defined( BOOST_BORLANDC ) +#pragma nopushoptwarn +#endif + diff --git a/src/boost/config/abi_suffix.hpp b/src/boost/config/abi_suffix.hpp new file mode 100644 index 00000000..a1eb78db --- /dev/null +++ b/src/boost/config/abi_suffix.hpp @@ -0,0 +1,25 @@ +// abi_sufffix header -------------------------------------------------------// + +// (c) Copyright John Maddock 2003 + +// Use, modification and distribution are 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). + +// This header should be #included AFTER code that was preceded by a #include +// . + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# error Header boost/config/abi_suffix.hpp must only be used after boost/config/abi_prefix.hpp +#else +# undef BOOST_CONFIG_ABI_PREFIX_HPP +#endif + +// the suffix header occurs after all of our code: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#if defined( BOOST_BORLANDC ) +#pragma nopushoptwarn +#endif diff --git a/src/boost/config/assert_cxx03.hpp b/src/boost/config/assert_cxx03.hpp new file mode 100644 index 00000000..c914aa86 --- /dev/null +++ b/src/boost/config/assert_cxx03.hpp @@ -0,0 +1,211 @@ +// This file was automatically generated on Fri Oct 13 19:09:38 2023 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#include + +#ifdef BOOST_NO_ADL_BARRIER +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_ADL_BARRIER." +#endif +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP." +#endif +#ifdef BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_COMPLETE_VALUE_INITIALIZATION." +#endif +#ifdef BOOST_NO_CTYPE_FUNCTIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CTYPE_FUNCTIONS." +#endif +#ifdef BOOST_NO_CV_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CV_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_CV_VOID_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CV_VOID_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_CWCHAR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CWCHAR." +#endif +#ifdef BOOST_NO_CWCTYPE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_CWCTYPE." +#endif +#ifdef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_DEPENDENT_NESTED_DERIVATIONS." +#endif +#ifdef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS." +#endif +#ifdef BOOST_NO_EXCEPTIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_EXCEPTIONS." +#endif +#ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_EXCEPTION_STD_NAMESPACE." +#endif +#ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS." +#endif +#ifdef BOOST_NO_FENV_H +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_FENV_H." +#endif +#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_FUNCTION_TEMPLATE_ORDERING." +#endif +#ifdef BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_INCLASS_MEMBER_INITIALIZATION." +#endif +#ifdef BOOST_NO_INTEGRAL_INT64_T +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_INTEGRAL_INT64_T." +#endif +#ifdef BOOST_NO_INTRINSIC_WCHAR_T +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_INTRINSIC_WCHAR_T." +#endif +#ifdef BOOST_NO_IOSFWD +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_IOSFWD." +#endif +#ifdef BOOST_NO_IOSTREAM +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_IOSTREAM." +#endif +#ifdef BOOST_NO_IS_ABSTRACT +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_IS_ABSTRACT." +#endif +#ifdef BOOST_NO_LIMITS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LIMITS." +#endif +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS." +#endif +#ifdef BOOST_NO_LONG_LONG +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LONG_LONG." +#endif +#ifdef BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_LONG_LONG_NUMERIC_LIMITS." +#endif +#ifdef BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS." +#endif +#ifdef BOOST_NO_MEMBER_TEMPLATES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_TEMPLATES." +#endif +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_TEMPLATE_FRIENDS." +#endif +#ifdef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_MEMBER_TEMPLATE_KEYWORD." +#endif +#ifdef BOOST_NO_NESTED_FRIENDSHIP +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_NESTED_FRIENDSHIP." +#endif +#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_OPERATORS_IN_NAMESPACE." +#endif +#ifdef BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS." +#endif +#ifdef BOOST_NO_POINTER_TO_MEMBER_CONST +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_POINTER_TO_MEMBER_CONST." +#endif +#ifdef BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS." +#endif +#ifdef BOOST_NO_PRIVATE_IN_AGGREGATE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_PRIVATE_IN_AGGREGATE." +#endif +#ifdef BOOST_NO_RESTRICT_REFERENCES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_RESTRICT_REFERENCES." +#endif +#ifdef BOOST_NO_RTTI +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_RTTI." +#endif +#ifdef BOOST_NO_SFINAE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_SFINAE." +#endif +#ifdef BOOST_NO_SFINAE_EXPR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_SFINAE_EXPR." +#endif +#ifdef BOOST_NO_STDC_NAMESPACE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STDC_NAMESPACE." +#endif +#ifdef BOOST_NO_STD_ALLOCATOR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_ALLOCATOR." +#endif +#ifdef BOOST_NO_STD_DISTANCE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_DISTANCE." +#endif +#ifdef BOOST_NO_STD_ITERATOR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_ITERATOR." +#endif +#ifdef BOOST_NO_STD_ITERATOR_TRAITS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_ITERATOR_TRAITS." +#endif +#ifdef BOOST_NO_STD_LOCALE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_LOCALE." +#endif +#ifdef BOOST_NO_STD_MESSAGES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_MESSAGES." +#endif +#ifdef BOOST_NO_STD_MIN_MAX +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_MIN_MAX." +#endif +#ifdef BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN." +#endif +#ifdef BOOST_NO_STD_TYPEINFO +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_TYPEINFO." +#endif +#ifdef BOOST_NO_STD_USE_FACET +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_USE_FACET." +#endif +#ifdef BOOST_NO_STD_WSTREAMBUF +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_WSTREAMBUF." +#endif +#ifdef BOOST_NO_STD_WSTRING +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STD_WSTRING." +#endif +#ifdef BOOST_NO_STRINGSTREAM +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_STRINGSTREAM." +#endif +#ifdef BOOST_NO_TEMPLATED_IOSTREAMS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATED_IOSTREAMS." +#endif +#ifdef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS." +#endif +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION." +#endif +#ifdef BOOST_NO_TEMPLATE_TEMPLATES +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TEMPLATE_TEMPLATES." +#endif +#ifdef BOOST_NO_TWO_PHASE_NAME_LOOKUP +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TWO_PHASE_NAME_LOOKUP." +#endif +#ifdef BOOST_NO_TYPEID +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TYPEID." +#endif +#ifdef BOOST_NO_TYPENAME_WITH_CTOR +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_TYPENAME_WITH_CTOR." +#endif +#ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_UNREACHABLE_RETURN_DETECTION." +#endif +#ifdef BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE." +#endif +#ifdef BOOST_NO_USING_TEMPLATE +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_USING_TEMPLATE." +#endif +#ifdef BOOST_NO_VOID_RETURNS +# error "Your compiler appears not to be fully C++03 compliant. Detected via defect macro BOOST_NO_VOID_RETURNS." +#endif diff --git a/src/boost/config/assert_cxx11.hpp b/src/boost/config/assert_cxx11.hpp new file mode 100644 index 00000000..addd06ad --- /dev/null +++ b/src/boost/config/assert_cxx11.hpp @@ -0,0 +1,212 @@ +// This file was automatically generated on Fri Oct 13 19:09:38 2023 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#include +#include + +#ifdef BOOST_NO_CXX11_ADDRESSOF +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_ADDRESSOF." +#endif +#ifdef BOOST_NO_CXX11_ALIGNAS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_ALIGNAS." +#endif +#ifdef BOOST_NO_CXX11_ALIGNOF +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_ALIGNOF." +#endif +#ifdef BOOST_NO_CXX11_ALLOCATOR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_ALLOCATOR." +#endif +#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_AUTO_DECLARATIONS." +#endif +#ifdef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS." +#endif +#ifdef BOOST_NO_CXX11_CHAR16_T +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_CHAR16_T." +#endif +#ifdef BOOST_NO_CXX11_CHAR32_T +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_CHAR32_T." +#endif +#ifdef BOOST_NO_CXX11_CONSTEXPR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_CONSTEXPR." +#endif +#ifdef BOOST_NO_CXX11_DECLTYPE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DECLTYPE." +#endif +#ifdef BOOST_NO_CXX11_DECLTYPE_N3276 +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DECLTYPE_N3276." +#endif +#ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DEFAULTED_FUNCTIONS." +#endif +#ifdef BOOST_NO_CXX11_DEFAULTED_MOVES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DEFAULTED_MOVES." +#endif +#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_DELETED_FUNCTIONS." +#endif +#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS." +#endif +#ifdef BOOST_NO_CXX11_EXTERN_TEMPLATE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_EXTERN_TEMPLATE." +#endif +#ifdef BOOST_NO_CXX11_FINAL +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_FINAL." +#endif +#ifdef BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS." +#endif +#ifdef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS." +#endif +#ifdef BOOST_NO_CXX11_HDR_ARRAY +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_ARRAY." +#endif +#ifdef BOOST_NO_CXX11_HDR_ATOMIC +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_ATOMIC." +#endif +#ifdef BOOST_NO_CXX11_HDR_CHRONO +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_CHRONO." +#endif +#ifdef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_CONDITION_VARIABLE." +#endif +#ifdef BOOST_NO_CXX11_HDR_EXCEPTION +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_EXCEPTION." +#endif +#ifdef BOOST_NO_CXX11_HDR_FORWARD_LIST +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_FORWARD_LIST." +#endif +#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_FUNCTIONAL." +#endif +#ifdef BOOST_NO_CXX11_HDR_FUTURE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_FUTURE." +#endif +#ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_INITIALIZER_LIST." +#endif +#ifdef BOOST_NO_CXX11_HDR_MUTEX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_MUTEX." +#endif +#ifdef BOOST_NO_CXX11_HDR_RANDOM +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_RANDOM." +#endif +#ifdef BOOST_NO_CXX11_HDR_RATIO +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_RATIO." +#endif +#ifdef BOOST_NO_CXX11_HDR_REGEX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_REGEX." +#endif +#ifdef BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_SYSTEM_ERROR." +#endif +#ifdef BOOST_NO_CXX11_HDR_THREAD +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_THREAD." +#endif +#ifdef BOOST_NO_CXX11_HDR_TUPLE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_TUPLE." +#endif +#ifdef BOOST_NO_CXX11_HDR_TYPEINDEX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_TYPEINDEX." +#endif +#ifdef BOOST_NO_CXX11_HDR_TYPE_TRAITS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_TYPE_TRAITS." +#endif +#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_UNORDERED_MAP." +#endif +#ifdef BOOST_NO_CXX11_HDR_UNORDERED_SET +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_HDR_UNORDERED_SET." +#endif +#ifdef BOOST_NO_CXX11_INLINE_NAMESPACES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_INLINE_NAMESPACES." +#endif +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_LAMBDAS." +#endif +#ifdef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS." +#endif +#ifdef BOOST_NO_CXX11_NOEXCEPT +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NOEXCEPT." +#endif +#ifdef BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS." +#endif +#ifdef BOOST_NO_CXX11_NULLPTR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NULLPTR." +#endif +#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_NUMERIC_LIMITS." +#endif +#ifdef BOOST_NO_CXX11_OVERRIDE +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_OVERRIDE." +#endif +#ifdef BOOST_NO_CXX11_POINTER_TRAITS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_POINTER_TRAITS." +#endif +#ifdef BOOST_NO_CXX11_RANGE_BASED_FOR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_RANGE_BASED_FOR." +#endif +#ifdef BOOST_NO_CXX11_RAW_LITERALS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_RAW_LITERALS." +#endif +#ifdef BOOST_NO_CXX11_REF_QUALIFIERS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_REF_QUALIFIERS." +#endif +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_RVALUE_REFERENCES." +#endif +#ifdef BOOST_NO_CXX11_SCOPED_ENUMS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_SCOPED_ENUMS." +#endif +#ifdef BOOST_NO_CXX11_SFINAE_EXPR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_SFINAE_EXPR." +#endif +#ifdef BOOST_NO_CXX11_SMART_PTR +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_SMART_PTR." +#endif +#ifdef BOOST_NO_CXX11_STATIC_ASSERT +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_STATIC_ASSERT." +#endif +#ifdef BOOST_NO_CXX11_STD_ALIGN +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_STD_ALIGN." +#endif +#ifdef BOOST_NO_CXX11_TEMPLATE_ALIASES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_TEMPLATE_ALIASES." +#endif +#ifdef BOOST_NO_CXX11_THREAD_LOCAL +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_THREAD_LOCAL." +#endif +#ifdef BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_TRAILING_RESULT_TYPES." +#endif +#ifdef BOOST_NO_CXX11_UNICODE_LITERALS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_UNICODE_LITERALS." +#endif +#ifdef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX." +#endif +#ifdef BOOST_NO_CXX11_UNRESTRICTED_UNION +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_UNRESTRICTED_UNION." +#endif +#ifdef BOOST_NO_CXX11_USER_DEFINED_LITERALS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_USER_DEFINED_LITERALS." +#endif +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_VARIADIC_MACROS." +#endif +#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES +# error "Your compiler appears not to be fully C++11 compliant. Detected via defect macro BOOST_NO_CXX11_VARIADIC_TEMPLATES." +#endif diff --git a/src/boost/config/assert_cxx14.hpp b/src/boost/config/assert_cxx14.hpp new file mode 100644 index 00000000..061aba3f --- /dev/null +++ b/src/boost/config/assert_cxx14.hpp @@ -0,0 +1,47 @@ +// This file was automatically generated on Fri Oct 13 19:09:38 2023 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#include +#include + +#ifdef BOOST_NO_CXX14_AGGREGATE_NSDMI +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_AGGREGATE_NSDMI." +#endif +#ifdef BOOST_NO_CXX14_BINARY_LITERALS +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_BINARY_LITERALS." +#endif +#ifdef BOOST_NO_CXX14_CONSTEXPR +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_CONSTEXPR." +#endif +#ifdef BOOST_NO_CXX14_DECLTYPE_AUTO +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_DECLTYPE_AUTO." +#endif +#ifdef BOOST_NO_CXX14_DIGIT_SEPARATORS +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_DIGIT_SEPARATORS." +#endif +#ifdef BOOST_NO_CXX14_GENERIC_LAMBDAS +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_GENERIC_LAMBDAS." +#endif +#ifdef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_HDR_SHARED_MUTEX." +#endif +#ifdef BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES." +#endif +#ifdef BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION." +#endif +#ifdef BOOST_NO_CXX14_STD_EXCHANGE +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_STD_EXCHANGE." +#endif +#ifdef BOOST_NO_CXX14_VARIABLE_TEMPLATES +# error "Your compiler appears not to be fully C++14 compliant. Detected via defect macro BOOST_NO_CXX14_VARIABLE_TEMPLATES." +#endif diff --git a/src/boost/config/assert_cxx17.hpp b/src/boost/config/assert_cxx17.hpp new file mode 100644 index 00000000..e2402515 --- /dev/null +++ b/src/boost/config/assert_cxx17.hpp @@ -0,0 +1,65 @@ +// This file was automatically generated on Fri Oct 13 19:09:38 2023 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#include +#include + +#ifdef BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS." +#endif +#ifdef BOOST_NO_CXX17_DEDUCTION_GUIDES +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_DEDUCTION_GUIDES." +#endif +#ifdef BOOST_NO_CXX17_FOLD_EXPRESSIONS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_FOLD_EXPRESSIONS." +#endif +#ifdef BOOST_NO_CXX17_HDR_ANY +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_ANY." +#endif +#ifdef BOOST_NO_CXX17_HDR_CHARCONV +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_CHARCONV." +#endif +#ifdef BOOST_NO_CXX17_HDR_EXECUTION +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_EXECUTION." +#endif +#ifdef BOOST_NO_CXX17_HDR_FILESYSTEM +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_FILESYSTEM." +#endif +#ifdef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_MEMORY_RESOURCE." +#endif +#ifdef BOOST_NO_CXX17_HDR_OPTIONAL +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_OPTIONAL." +#endif +#ifdef BOOST_NO_CXX17_HDR_STRING_VIEW +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_STRING_VIEW." +#endif +#ifdef BOOST_NO_CXX17_HDR_VARIANT +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_HDR_VARIANT." +#endif +#ifdef BOOST_NO_CXX17_IF_CONSTEXPR +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_IF_CONSTEXPR." +#endif +#ifdef BOOST_NO_CXX17_INLINE_VARIABLES +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_INLINE_VARIABLES." +#endif +#ifdef BOOST_NO_CXX17_ITERATOR_TRAITS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_ITERATOR_TRAITS." +#endif +#ifdef BOOST_NO_CXX17_STD_APPLY +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_STD_APPLY." +#endif +#ifdef BOOST_NO_CXX17_STD_INVOKE +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_STD_INVOKE." +#endif +#ifdef BOOST_NO_CXX17_STRUCTURED_BINDINGS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_STRUCTURED_BINDINGS." +#endif diff --git a/src/boost/config/assert_cxx20.hpp b/src/boost/config/assert_cxx20.hpp new file mode 100644 index 00000000..71a74154 --- /dev/null +++ b/src/boost/config/assert_cxx20.hpp @@ -0,0 +1,59 @@ +// This file was automatically generated on Fri Oct 13 19:09:38 2023 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#include +#include + +#ifdef BOOST_NO_CXX20_HDR_BARRIER +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_BARRIER." +#endif +#ifdef BOOST_NO_CXX20_HDR_BIT +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_BIT." +#endif +#ifdef BOOST_NO_CXX20_HDR_COMPARE +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_COMPARE." +#endif +#ifdef BOOST_NO_CXX20_HDR_CONCEPTS +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_CONCEPTS." +#endif +#ifdef BOOST_NO_CXX20_HDR_COROUTINE +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_COROUTINE." +#endif +#ifdef BOOST_NO_CXX20_HDR_FORMAT +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_FORMAT." +#endif +#ifdef BOOST_NO_CXX20_HDR_LATCH +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_LATCH." +#endif +#ifdef BOOST_NO_CXX20_HDR_NUMBERS +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_NUMBERS." +#endif +#ifdef BOOST_NO_CXX20_HDR_RANGES +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_RANGES." +#endif +#ifdef BOOST_NO_CXX20_HDR_SEMAPHORE +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SEMAPHORE." +#endif +#ifdef BOOST_NO_CXX20_HDR_SOURCE_LOCATION +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SOURCE_LOCATION." +#endif +#ifdef BOOST_NO_CXX20_HDR_SPAN +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SPAN." +#endif +#ifdef BOOST_NO_CXX20_HDR_STOP_TOKEN +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_STOP_TOKEN." +#endif +#ifdef BOOST_NO_CXX20_HDR_SYNCSTREAM +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_SYNCSTREAM." +#endif +#ifdef BOOST_NO_CXX20_HDR_VERSION +# error "Your compiler appears not to be fully C++20 compliant. Detected via defect macro BOOST_NO_CXX20_HDR_VERSION." +#endif diff --git a/src/boost/config/assert_cxx23.hpp b/src/boost/config/assert_cxx23.hpp new file mode 100644 index 00000000..feb44573 --- /dev/null +++ b/src/boost/config/assert_cxx23.hpp @@ -0,0 +1,41 @@ +// This file was automatically generated on Fri Oct 13 19:09:38 2023 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#include +#include + +#ifdef BOOST_NO_CXX23_HDR_EXPECTED +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_EXPECTED." +#endif +#ifdef BOOST_NO_CXX23_HDR_FLAT_MAP +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_FLAT_MAP." +#endif +#ifdef BOOST_NO_CXX23_HDR_FLAT_SET +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_FLAT_SET." +#endif +#ifdef BOOST_NO_CXX23_HDR_GENERATOR +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_GENERATOR." +#endif +#ifdef BOOST_NO_CXX23_HDR_MDSPAN +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_MDSPAN." +#endif +#ifdef BOOST_NO_CXX23_HDR_PRINT +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_PRINT." +#endif +#ifdef BOOST_NO_CXX23_HDR_SPANSTREAM +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_SPANSTREAM." +#endif +#ifdef BOOST_NO_CXX23_HDR_STACKTRACE +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_STACKTRACE." +#endif +#ifdef BOOST_NO_CXX23_HDR_STDFLOAT +# error "Your compiler appears not to be fully C++23 compliant. Detected via defect macro BOOST_NO_CXX23_HDR_STDFLOAT." +#endif diff --git a/src/boost/config/assert_cxx98.hpp b/src/boost/config/assert_cxx98.hpp new file mode 100644 index 00000000..aa745d43 --- /dev/null +++ b/src/boost/config/assert_cxx98.hpp @@ -0,0 +1,23 @@ +// This file was automatically generated on Wed Mar 3 08:46:11 2021 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-4. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#include +#include + +#ifdef BOOST_NO_CXX98_BINDERS +# error "Your compiler appears not to be fully C++98 compliant. Detected via defect macro BOOST_NO_CXX98_BINDERS." +#endif +#ifdef BOOST_NO_CXX98_FUNCTION_BASE +# error "Your compiler appears not to be fully C++98 compliant. Detected via defect macro BOOST_NO_CXX98_FUNCTION_BASE." +#endif +#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE +# error "Your compiler appears not to be fully C++98 compliant. Detected via defect macro BOOST_NO_CXX98_RANDOM_SHUFFLE." +#endif diff --git a/src/boost/config/auto_link.hpp b/src/boost/config/auto_link.hpp new file mode 100644 index 00000000..64dee1ef --- /dev/null +++ b/src/boost/config/auto_link.hpp @@ -0,0 +1,525 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are 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) + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE auto_link.hpp + * VERSION see + * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. + */ + +/************************************************************************* + +USAGE: +~~~~~~ + +Before including this header you must define one or more of define the following macros: + +BOOST_LIB_NAME: Required: A string containing the basename of the library, + for example boost_regex. +BOOST_LIB_TOOLSET: Optional: the base name of the toolset. +BOOST_DYN_LINK: Optional: when set link to dll rather than static library. +BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name + of the library selected (useful for debugging). +BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, + rather than a mangled-name version. +BOOST_AUTO_LINK_TAGGED: Specifies that we link to libraries built with the --layout=tagged option. + This is essentially the same as the default name-mangled version, but without + the compiler name and version, or the Boost version. Just the build options. +BOOST_AUTO_LINK_SYSTEM: Specifies that we link to libraries built with the --layout=system option. + This is essentially the same as the non-name-mangled version, but with + the prefix to differentiate static and dll builds + +These macros will be undef'ed at the end of the header, further this header +has no include guards - so be sure to include it only once from your library! + +Algorithm: +~~~~~~~~~~ + +Libraries for Borland and Microsoft compilers are automatically +selected here, the name of the lib is selected according to the following +formula: + +BOOST_LIB_PREFIX + + BOOST_LIB_NAME + + "_" + + BOOST_LIB_TOOLSET + + BOOST_LIB_THREAD_OPT + + BOOST_LIB_RT_OPT + + BOOST_LIB_ARCH_AND_MODEL_OPT + "-" + + BOOST_LIB_VERSION + + BOOST_LIB_SUFFIX + +These are defined as: + +BOOST_LIB_PREFIX: "lib" for static libraries otherwise "". + +BOOST_LIB_NAME: The base name of the lib ( for example boost_regex). + +BOOST_LIB_TOOLSET: The compiler toolset name (vc6, vc7, bcb5 etc). + +BOOST_LIB_THREAD_OPT: "-mt" for multithread builds, otherwise nothing. + +BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, + contains one or more of the following letters after + a hyphen: + + s static runtime (dynamic if not present). + g debug/diagnostic runtime (release if not present). + y Python debug/diagnostic runtime (release if not present). + d debug build (release if not present). + p STLport build. + n STLport build without its IOStreams. + +BOOST_LIB_ARCH_AND_MODEL_OPT: The architecture and address model + (-x32 or -x64 for x86/32 and x86/64 respectively) + +BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. + +BOOST_LIB_SUFFIX: Static/import libraries extension (".lib", ".a") for the compiler. + +***************************************************************************/ + +#ifdef __cplusplus +# ifndef BOOST_CONFIG_HPP +# include +# endif +#elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__) +// +// C language compatability (no, honestly) +// +# define BOOST_MSVC _MSC_VER +# define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +# define BOOST_DO_STRINGIZE(X) #X +#endif +// +// Only include what follows for known and supported compilers: +// +#if defined(BOOST_MSVC) \ + || defined(BOOST_EMBTC_WINDOWS) \ + || defined(BOOST_BORLANDC) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \ + || (defined(BOOST_CLANG) && defined(BOOST_WINDOWS) && defined(_MSC_VER) && (__clang_major__ >= 4)) + +#ifndef BOOST_VERSION_HPP +# include +#endif + +#ifndef BOOST_LIB_NAME +# error "Macro BOOST_LIB_NAME not set (internal error)" +#endif + +// +// error check: +// +#if defined(__MSVC_RUNTIME_CHECKS) && !defined(_DEBUG) +# pragma message("Using the /RTC option without specifying a debug runtime will lead to linker errors") +# pragma message("Hint: go to the code generation options and switch to one of the debugging runtimes") +# error "Incompatible build options" +#endif +// +// select toolset if not defined already: +// +#ifndef BOOST_LIB_TOOLSET +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1200) + // Note: no compilers before 1200 are supported +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +# ifdef UNDER_CE + // eVC4: +# define BOOST_LIB_TOOLSET "evc4" +# else + // vc6: +# define BOOST_LIB_TOOLSET "vc6" +# endif + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1310) + + // vc7: +# define BOOST_LIB_TOOLSET "vc7" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + + // vc71: +# define BOOST_LIB_TOOLSET "vc71" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1500) + + // vc80: +# define BOOST_LIB_TOOLSET "vc80" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1600) + + // vc90: +# define BOOST_LIB_TOOLSET "vc90" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1700) + + // vc10: +# define BOOST_LIB_TOOLSET "vc100" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) + + // vc11: +# define BOOST_LIB_TOOLSET "vc110" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900) + + // vc12: +# define BOOST_LIB_TOOLSET "vc120" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1910) + + // vc14: +# define BOOST_LIB_TOOLSET "vc140" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1920) + + // vc14.1: +# define BOOST_LIB_TOOLSET "vc141" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1930) + + // vc14.2: +# define BOOST_LIB_TOOLSET "vc142" + +# elif defined(BOOST_MSVC) + + // vc14.3: +# define BOOST_LIB_TOOLSET "vc143" + +# elif defined(BOOST_EMBTC_WINDOWS) + + // Embarcadero Clang based compilers: +# define BOOST_LIB_TOOLSET "embtc" + +# elif defined(BOOST_BORLANDC) + + // CBuilder 6: +# define BOOST_LIB_TOOLSET "bcb" + +# elif defined(__ICL) + + // Intel C++, no version number: +# define BOOST_LIB_TOOLSET "iw" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x31FF ) + + // Metrowerks CodeWarrior 8.x +# define BOOST_LIB_TOOLSET "cw8" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x32FF ) + + // Metrowerks CodeWarrior 9.x +# define BOOST_LIB_TOOLSET "cw9" + +# elif defined(BOOST_CLANG) && defined(BOOST_WINDOWS) && defined(_MSC_VER) && (__clang_major__ >= 4) + + // Clang on Windows +# define BOOST_LIB_TOOLSET "clangw" BOOST_STRINGIZE(__clang_major__) + +# endif +#endif // BOOST_LIB_TOOLSET + +// +// select thread opt: +// +#if defined(_MT) || defined(__MT__) +# define BOOST_LIB_THREAD_OPT "-mt" +#else +# define BOOST_LIB_THREAD_OPT +#endif + +#if defined(_MSC_VER) || defined(__MWERKS__) + +# ifdef _DLL + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-p" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-pn" +# endif + +# else + +# if defined(_DEBUG) && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gd" +# else +# define BOOST_LIB_RT_OPT +# endif + +# endif + +# else + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-sp" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-spn" +# endif + +# else + +# if defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +# endif + +#elif defined(BOOST_EMBTC_WINDOWS) + +# ifdef _RTLDLL + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-d" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#elif defined(BOOST_BORLANDC) + +// +// figure out whether we want the debug builds or not: +// +#if BOOST_BORLANDC > 0x561 +#pragma defineonoption BOOST_BORLAND_DEBUG -v +#endif +// +// sanity check: +// +#if defined(__STL_DEBUG) || defined(_STLP_DEBUG) +#error "Pre-built versions of the Boost libraries are not provided in STLport-debug form" +#endif + +# ifdef _RTLDLL + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-yd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-d" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-y" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-syd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-sd" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sy" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#endif + +// +// BOOST_LIB_ARCH_AND_MODEL_OPT +// + +#if defined( _M_IX86 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-x32" +#elif defined( _M_X64 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-x64" +#elif defined( _M_ARM ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-a32" +#elif defined( _M_ARM64 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-a64" +#endif + +// +// select linkage opt: +// +#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) +# define BOOST_LIB_PREFIX +#elif defined(BOOST_DYN_LINK) +# error "Mixing a dll boost library with a static runtime is a really bad idea..." +#else +# define BOOST_LIB_PREFIX "lib" +#endif + +// +// now include the lib: +// +#if defined(BOOST_LIB_NAME) \ + && defined(BOOST_LIB_PREFIX) \ + && defined(BOOST_LIB_TOOLSET) \ + && defined(BOOST_LIB_THREAD_OPT) \ + && defined(BOOST_LIB_RT_OPT) \ + && defined(BOOST_LIB_ARCH_AND_MODEL_OPT) \ + && defined(BOOST_LIB_VERSION) + +#if defined(BOOST_EMBTC_WIN64) +# define BOOST_LIB_SUFFIX ".a" +#else +# define BOOST_LIB_SUFFIX ".lib" +#endif + +#ifdef BOOST_AUTO_LINK_NOMANGLE +# pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_AUTO_LINK_TAGGED) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_AUTO_LINK_SYSTEM) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_LIB_BUILDID) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) BOOST_LIB_SUFFIX) +# endif +#else +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION BOOST_LIB_SUFFIX) +# endif +#endif + +#else +# error "some required macros where not defined (internal logic error)." +#endif + + +#endif // _MSC_VER || __BORLANDC__ + +// +// finally undef any macros we may have set: +// +#ifdef BOOST_LIB_PREFIX +# undef BOOST_LIB_PREFIX +#endif +#if defined(BOOST_LIB_NAME) +# undef BOOST_LIB_NAME +#endif +// Don't undef this one: it can be set by the user and should be the +// same for all libraries: +//#if defined(BOOST_LIB_TOOLSET) +//# undef BOOST_LIB_TOOLSET +//#endif +#if defined(BOOST_LIB_THREAD_OPT) +# undef BOOST_LIB_THREAD_OPT +#endif +#if defined(BOOST_LIB_RT_OPT) +# undef BOOST_LIB_RT_OPT +#endif +#if defined(BOOST_LIB_ARCH_AND_MODEL_OPT) +# undef BOOST_LIB_ARCH_AND_MODEL_OPT +#endif +#if defined(BOOST_LIB_LINK_OPT) +# undef BOOST_LIB_LINK_OPT +#endif +#if defined(BOOST_LIB_DEBUG_OPT) +# undef BOOST_LIB_DEBUG_OPT +#endif +#if defined(BOOST_DYN_LINK) +# undef BOOST_DYN_LINK +#endif +#if defined(BOOST_LIB_SUFFIX) +# undef BOOST_LIB_SUFFIX +#endif diff --git a/src/boost/config/compiler/borland.hpp b/src/boost/config/compiler/borland.hpp new file mode 100644 index 00000000..51d51886 --- /dev/null +++ b/src/boost/config/compiler/borland.hpp @@ -0,0 +1,342 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are 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 most recent version. + +// Borland C++ compiler setup: + +// +// versions check: +// we don't support Borland prior to version 5.4: +#if __BORLANDC__ < 0x540 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// last known compiler version: +#if (__BORLANDC__ > 0x613) +//# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +//# else +//# pragma message( "boost: Unknown compiler version - please run the configure tests and report the results") +//# endif +#elif (__BORLANDC__ == 0x600) +# error "CBuilderX preview compiler is no longer supported" +#endif + +// +// Support macros to help with standard library detection +#if (__BORLANDC__ < 0x560) || defined(_USE_OLD_RW_STL) +# define BOOST_BCB_WITH_ROGUE_WAVE +#elif __BORLANDC__ < 0x570 +# define BOOST_BCB_WITH_STLPORT +#else +# define BOOST_BCB_WITH_DINKUMWARE +#endif + +// +// Version 5.0 and below: +# if __BORLANDC__ <= 0x0550 +// Borland C++Builder 4 and 5: +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# if __BORLANDC__ == 0x0550 +// Borland C++Builder 5, command-line compiler 5.5: +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# endif +// Variadic macros do not exist for C++ Builder versions 5 and below +#define BOOST_NO_CXX11_VARIADIC_MACROS +# endif + +// Version 5.51 and below: +#if (__BORLANDC__ <= 0x551) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# define BOOST_NO_DEDUCED_TYPENAME +// workaround for missing WCHAR_MAX/WCHAR_MIN: +#ifdef __cplusplus +#include +#include +#else +#include +#include +#endif // __cplusplus +#ifndef WCHAR_MAX +# define WCHAR_MAX 0xffff +#endif +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#endif + +// Borland C++ Builder 6 and below: +#if (__BORLANDC__ <= 0x564) + +# if defined(NDEBUG) && defined(__cplusplus) + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif + +// +// new bug in 5.61: +#if (__BORLANDC__ >= 0x561) && (__BORLANDC__ <= 0x580) + // this seems to be needed by the command line compiler, but not the IDE: +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +// Borland C++ Builder 2006 Update 2 and below: +#if (__BORLANDC__ <= 0x582) +# define BOOST_NO_SFINAE +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# define BOOST_NO_TEMPLATE_TEMPLATES + +# define BOOST_NO_PRIVATE_IN_AGGREGATE + +# ifdef _WIN32 +# define BOOST_NO_SWPRINTF +# elif defined(linux) || defined(__linux__) || defined(__linux) + // we should really be able to do without this + // but the wcs* functions aren't imported into std:: +# define BOOST_NO_STDC_NAMESPACE + // _CPPUNWIND doesn't get automatically set for some reason: +# pragma defineonoption BOOST_CPPUNWIND -x +# endif +#endif + +#if (__BORLANDC__ <= 0x613) // Beman has asked Alisdair for more info + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +# define BOOST_NO_USING_TEMPLATE +# define BOOST_SP_NO_SP_CONVERTIBLE + +// Temporary workaround +#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif + +// Borland C++ Builder 2008 and below: +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# define BOOST_NO_NESTED_FRIENDSHIP +# define BOOST_NO_TYPENAME_WITH_CTOR +#if (__BORLANDC__ < 0x600) +# define BOOST_ILLEGAL_CV_REFERENCES +#endif + +// +// Positive Feature detection +// +// Borland C++ Builder 2008 and below: +#if (__BORLANDC__ >= 0x599) +# pragma defineonoption BOOST_CODEGEAR_0X_SUPPORT -Ax +#endif +// +// C++0x Macros: +// +#if !defined( BOOST_CODEGEAR_0X_SUPPORT ) || (__BORLANDC__ < 0x610) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_STATIC_ASSERT +#else +# define BOOST_HAS_ALIGNOF +# define BOOST_HAS_CHAR16_T +# define BOOST_HAS_CHAR32_T +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_EXPLICIT_CONVERSION_OPS +# define BOOST_HAS_REF_QUALIFIER +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +#endif + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DEFAULTED_MOVES +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS // UTF-8 still not supported +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#if __BORLANDC__ >= 0x590 +# define BOOST_HAS_TR1_HASH + +# define BOOST_HAS_MACRO_USE_FACET +#endif + +// +// Post 0x561 we have long long and stdint.h: +#if __BORLANDC__ >= 0x561 +# ifndef __NO_LONG_LONG +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + // On non-Win32 platforms let the platform config figure this out: +# ifdef _WIN32 +# define BOOST_HAS_STDINT_H +# endif +#endif + +// Borland C++Builder 6 defaults to using STLPort. If _USE_OLD_RW_STL is +// defined, then we have 0x560 or greater with the Rogue Wave implementation +// which presumably has the std::DBL_MAX bug. +#if defined( BOOST_BCB_WITH_ROGUE_WAVE ) +// is partly broken, some macros define symbols that are really in +// namespace std, so you end up having to use illegal constructs like +// std::DBL_MAX, as a fix we'll just include float.h and have done with: +#include +#endif +// +// __int64: +// +#if (__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#ifndef __STRICT_ANSI__ +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif +// +// ABI fixing headers: +// +#if __BORLANDC__ != 0x600 // not implemented for version 6 compiler yet +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +#endif +// +// Disable Win32 support in ANSI mode: +// +#if __BORLANDC__ < 0x600 +# pragma defineonoption BOOST_DISABLE_WIN32 -A +#elif defined(__STRICT_ANSI__) +# define BOOST_DISABLE_WIN32 +#endif +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +// Borland did not implement value-initialization completely, as I reported +// in 2007, Borland Report 51854, "Value-initialization: POD struct should be +// zero-initialized", http://qc.embarcadero.com/wc/qcmain.aspx?d=51854 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + +#define BOOST_BORLANDC __BORLANDC__ +#define BOOST_COMPILER "Classic Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) diff --git a/src/boost/config/compiler/clang.hpp b/src/boost/config/compiler/clang.hpp new file mode 100644 index 00000000..f9a5050b --- /dev/null +++ b/src/boost/config/compiler/clang.hpp @@ -0,0 +1,370 @@ +// (C) Copyright Douglas Gregor 2010 +// +// Use, modification and distribution are 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 most recent version. + +// Clang compiler setup. + +#define BOOST_HAS_PRAGMA_ONCE + +// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used. +#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif + +// When compiling with clang before __has_extension was defined, +// even if one writes 'defined(__has_extension) && __has_extension(xxx)', +// clang reports a compiler error. So the only workaround found is: + +#ifndef __has_extension +#define __has_extension __has_feature +#endif + +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif + +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(x) 0 +#endif + +#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#if !__has_feature(cxx_thread_local) +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#ifdef __is_identifier +#if !__is_identifier(__int64) && !defined(__GNUC__) +# define BOOST_HAS_MS_INT64 +#endif +#endif + +#if __has_include() +# define BOOST_HAS_STDINT_H +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) +#if (__clang_major__ >= 4) && defined(__has_include) +#if __has_include() +# define BOOST_HAS_FLOAT128 +#endif +#endif +#endif + + +#define BOOST_HAS_NRVO + +// Branch prediction hints +#if !defined (__c2__) && defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif +#endif + +// Clang supports "long long" in all compilation modes. +#define BOOST_HAS_LONG_LONG + +// +// We disable this if the compiler is really nvcc with C++03 as it +// doesn't actually support __int128 as of CUDA_VERSION=7500 +// even though it defines __SIZEOF_INT128__. +// See https://svn.boost.org/trac/boost/ticket/10418 +// https://svn.boost.org/trac/boost/ticket/11852 +// Only re-enable this for nvcc if you're absolutely sure +// of the circumstances under which it's supported. +// Similarly __SIZEOF_INT128__ is defined when targetting msvc +// compatibility even though the required support functions are absent. +// +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) && !defined(_MSC_VER) +# define BOOST_HAS_INT128 +#endif + + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) +# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) +#else +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +#endif + +// +// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +// between switch labels. +// +#if __cplusplus >= 201103L && defined(__has_warning) +# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +# define BOOST_FALLTHROUGH [[clang::fallthrough]] +# endif +#endif + +#if !__has_feature(cxx_auto_type) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// +// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t +// +#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(__GNUC__) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +#if !__has_feature(cxx_constexpr) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#if !__has_feature(cxx_decltype) +# define BOOST_NO_CXX11_DECLTYPE +#endif + +#if !__has_feature(cxx_decltype_incomplete_return_types) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if !__has_feature(cxx_defaulted_functions) +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +#if !__has_feature(cxx_deleted_functions) +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +#if !__has_feature(cxx_explicit_conversions) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +#if !__has_feature(cxx_default_function_template_args) +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if !__has_feature(cxx_lambdas) +# define BOOST_NO_CXX11_LAMBDAS +#endif + +#if !__has_feature(cxx_local_type_template_args) +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if !__has_feature(cxx_noexcept) +# define BOOST_NO_CXX11_NOEXCEPT +#endif + +#if !__has_feature(cxx_nullptr) +# define BOOST_NO_CXX11_NULLPTR +#endif + +#if !__has_feature(cxx_range_for) +# define BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +#if !__has_feature(cxx_raw_string_literals) +# define BOOST_NO_CXX11_RAW_LITERALS +#endif + +#if !__has_feature(cxx_reference_qualified_functions) +# define BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +#if !__has_feature(cxx_rvalue_references) +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +#if !__has_feature(cxx_strong_enums) +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#if !__has_feature(cxx_static_assert) +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +#if !__has_feature(cxx_alias_templates) +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +#if !__has_feature(cxx_unicode_literals) +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +#if !__has_feature(cxx_variadic_templates) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if !__has_feature(cxx_user_literals) +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +#if !__has_feature(cxx_alignas) +# define BOOST_NO_CXX11_ALIGNAS +#endif + +#if !__has_feature(cxx_alignof) +# define BOOST_NO_CXX11_ALIGNOF +#endif + +#if !__has_feature(cxx_trailing_return) +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !__has_feature(cxx_inline_namespaces) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +#if !__has_feature(cxx_override_control) +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_OVERRIDE +#endif + +#if !__has_feature(cxx_unrestricted_unions) +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +#if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__)) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +#if !__has_feature(__cxx_decltype_auto__) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif + +#if !__has_feature(__cxx_aggregate_nsdmi__) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif + +#if !__has_feature(__cxx_init_captures__) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif + +#if !__has_feature(__cxx_generic_lambdas__) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif + +// clang < 3.5 has a defect with dependent type, like following. +// +// template +// constexpr typename enable_if >::type foo(T &) +// { } // error: no return statement in constexpr function +// +// This issue also affects C++11 mode, but C++11 constexpr requires return stmt. +// Therefore we don't care such case. +// +// Note that we can't check Clang version directly as the numbering system changes depending who's +// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873) +// so instead verify that we have a feature that was introduced at the same time as working C++14 +// constexpr (generic lambda's in this case): +// +#if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__) +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if !__has_feature(__cxx_return_type_deduction__) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif + +#if !__has_feature(__cxx_variable_templates__) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif + +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +// Clang 3.9+ in c++1z +#if !__has_cpp_attribute(fallthrough) || __cplusplus < 201406L +# define BOOST_NO_CXX17_INLINE_VARIABLES +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif + +#if (__clang_major__ < 4) || (__cplusplus < 201406L) /* non-standard value that is greater than 201402, which is reported by clang 4.0.0 for C++1z */ +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#if __cplusplus < 201103L +#define BOOST_NO_CXX11_SFINAE_EXPR +#endif + +#if __cplusplus < 201400 +// All versions with __cplusplus above this value seem to support this: +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif + +// Unreachable code markup +#if defined(__has_builtin) +#if __has_builtin(__builtin_unreachable) +#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); +#endif +#endif + +// Deprecated symbol markup +#if __has_attribute(deprecated) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + +#if (__clang_major__ == 3) && (__clang_minor__ == 0) +// Apparently a clang bug: +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#endif + +// Clang has supported the 'unused' attribute since the first release. +#define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) + +// Type aliasing hint. +#if __has_attribute(__may_alias__) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Clang version " __clang_version__ +#endif + +// Macro used to identify the Clang compiler. +#define BOOST_CLANG 1 + +// BOOST_CLANG_VERSION +#include diff --git a/src/boost/config/compiler/clang_version.hpp b/src/boost/config/compiler/clang_version.hpp new file mode 100644 index 00000000..a61de13d --- /dev/null +++ b/src/boost/config/compiler/clang_version.hpp @@ -0,0 +1,89 @@ +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt) + +#if !defined(__apple_build_version__) + +# define BOOST_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__ % 100) + +#else +# define BOOST_CLANG_REPORTED_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__ % 100) + +// https://en.wikipedia.org/wiki/Xcode#Toolchain_versions + +# if BOOST_CLANG_REPORTED_VERSION >= 150000 +# define BOOST_CLANG_VERSION 160000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 140003 +# define BOOST_CLANG_VERSION 150000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 140000 +# define BOOST_CLANG_VERSION 140000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 130100 +# define BOOST_CLANG_VERSION 130000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 130000 +# define BOOST_CLANG_VERSION 120000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 120005 +# define BOOST_CLANG_VERSION 110100 + +# elif BOOST_CLANG_REPORTED_VERSION >= 120000 +# define BOOST_CLANG_VERSION 100000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 110003 +# define BOOST_CLANG_VERSION 90000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 110000 +# define BOOST_CLANG_VERSION 80000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 100001 +# define BOOST_CLANG_VERSION 70000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 100000 +# define BOOST_CLANG_VERSION 60001 + +# elif BOOST_CLANG_REPORTED_VERSION >= 90100 +# define BOOST_CLANG_VERSION 50002 + +# elif BOOST_CLANG_REPORTED_VERSION >= 90000 +# define BOOST_CLANG_VERSION 40000 + +# elif BOOST_CLANG_REPORTED_VERSION >= 80000 +# define BOOST_CLANG_VERSION 30900 + +# elif BOOST_CLANG_REPORTED_VERSION >= 70300 +# define BOOST_CLANG_VERSION 30800 + +# elif BOOST_CLANG_REPORTED_VERSION >= 70000 +# define BOOST_CLANG_VERSION 30700 + +# elif BOOST_CLANG_REPORTED_VERSION >= 60100 +# define BOOST_CLANG_VERSION 30600 + +# elif BOOST_CLANG_REPORTED_VERSION >= 60000 +# define BOOST_CLANG_VERSION 30500 + +# elif BOOST_CLANG_REPORTED_VERSION >= 50100 +# define BOOST_CLANG_VERSION 30400 + +# elif BOOST_CLANG_REPORTED_VERSION >= 50000 +# define BOOST_CLANG_VERSION 30300 + +# elif BOOST_CLANG_REPORTED_VERSION >= 40200 +# define BOOST_CLANG_VERSION 30200 + +# elif BOOST_CLANG_REPORTED_VERSION >= 30100 +# define BOOST_CLANG_VERSION 30100 + +# elif BOOST_CLANG_REPORTED_VERSION >= 20100 +# define BOOST_CLANG_VERSION 30000 + +# else +# define BOOST_CLANG_VERSION 20900 + +# endif + +# undef BOOST_CLANG_REPORTED_VERSION +#endif diff --git a/src/boost/config/compiler/codegear.hpp b/src/boost/config/compiler/codegear.hpp new file mode 100644 index 00000000..49f934c0 --- /dev/null +++ b/src/boost/config/compiler/codegear.hpp @@ -0,0 +1,389 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are 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 most recent version. + +// CodeGear C++ compiler setup: + +// +// versions check: +// last known and checked version is 0x740 +#if (__CODEGEARC__ > 0x740) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message( "boost: Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + +#ifdef __clang__ // Clang enhanced Windows compiler + +# include "clang.hpp" +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR + +// This bug has been reported to Embarcadero + +#if defined(BOOST_HAS_INT128) +#undef BOOST_HAS_INT128 +#endif +#if defined(BOOST_HAS_FLOAT128) +#undef BOOST_HAS_FLOAT128 +#endif + +// The clang-based compilers can not do 128 atomic exchanges + +#define BOOST_ATOMIC_NO_CMPXCHG16B + +// 32 functions are missing from the current RTL in cwchar, so it really can not be used even if it exists + +# define BOOST_NO_CWCHAR + +# ifndef __MT__ /* If compiling in single-threaded mode, assume there is no CXX11_HDR_ATOMIC */ +# define BOOST_NO_CXX11_HDR_ATOMIC +# endif + +/* temporarily disable this until we can link against fegetround fesetround feholdexcept */ + +#define BOOST_NO_FENV_H + +/* Reported this bug to Embarcadero with the latest C++ Builder Rio release */ + +#define BOOST_NO_CXX11_HDR_EXCEPTION + +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +/* + +// On non-Win32 platforms let the platform config figure this out: +#ifdef _WIN32 +# define BOOST_HAS_STDINT_H +#endif + +// +// __int64: +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// all versions have a : +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_DIRENT_H +#endif +// +// Disable Win32 support in ANSI mode: +// +# pragma defineonoption BOOST_DISABLE_WIN32 -A +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif +// + +*/ + +// Specific settings for Embarcadero drivers +# define BOOST_EMBTC __CODEGEARC__ +# define BOOST_EMBTC_FULL_VER ((__clang_major__ << 16) | \ + (__clang_minor__ << 8) | \ + __clang_patchlevel__ ) + +// Detecting which Embarcadero driver is being used +#if defined(BOOST_EMBTC) +# if defined(_WIN64) +# define BOOST_EMBTC_WIN64 1 +# define BOOST_EMBTC_WINDOWS 1 +# ifndef BOOST_USE_WINDOWS_H +# define BOOST_USE_WINDOWS_H +# endif +# elif defined(_WIN32) +# define BOOST_EMBTC_WIN32C 1 +# define BOOST_EMBTC_WINDOWS 1 +# ifndef BOOST_USE_WINDOWS_H +# define BOOST_USE_WINDOWS_H +# endif +# elif defined(__APPLE__) && defined(__arm__) +# define BOOST_EMBTC_IOSARM 1 +# define BOOST_EMBTC_IOS 1 +# elif defined(__APPLE__) && defined(__aarch64__) +# define BOOST_EMBTC_IOSARM64 1 +# define BOOST_EMBTC_IOS 1 +# elif defined(__ANDROID__) && defined(__arm__) +# define BOOST_EMBTC_AARM 1 +# define BOOST_EMBTC_ANDROID 1 +# elif +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown Embarcadero driver" +# else +# warning "Unknown Embarcadero driver" +# endif /* defined(BOOST_ASSERT_CONFIG) */ +# endif +#endif /* defined(BOOST_EMBTC) */ + +#if defined(BOOST_EMBTC_WINDOWS) + +#if !defined(_chdir) +#define _chdir(x) chdir(x) +#endif + +#if !defined(_dup2) +#define _dup2(x,y) dup2(x,y) +#endif + +#endif + +# undef BOOST_COMPILER +# define BOOST_COMPILER "Embarcadero-Clang C++ version " BOOST_STRINGIZE(__CODEGEARC__) " clang: " __clang_version__ +// # define __CODEGEARC_CLANG__ __CODEGEARC__ +// # define __EMBARCADERO_CLANG__ __CODEGEARC__ +// # define __BORLANDC_CLANG__ __BORLANDC__ + +#else // #if !defined(__clang__) + +# define BOOST_CODEGEARC __CODEGEARC__ +# define BOOST_BORLANDC __BORLANDC__ + +#if !defined( BOOST_WITH_CODEGEAR_WARNINGS ) +// these warnings occur frequently in optimized template code +# pragma warn -8004 // var assigned value, but never used +# pragma warn -8008 // condition always true/false +# pragma warn -8066 // dead code can never execute +# pragma warn -8104 // static members with ctors not threadsafe +# pragma warn -8105 // reference member in class without ctors +#endif + +// CodeGear C++ Builder 2009 +#if (__CODEGEARC__ <= 0x613) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_PRIVATE_IN_AGGREGATE +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +// CodeGear C++ Builder 2010 +#if (__CODEGEARC__ <= 0x621) +# define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_NESTED_FRIENDSHIP // TC1 gives nested classes access rights as any other member +# define BOOST_NO_USING_TEMPLATE +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +// Temporary hack, until specific MPL preprocessed headers are generated +# define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +// CodeGear has not yet completely implemented value-initialization, for +// example for array types, as I reported in 2010: Embarcadero Report 83751, +// "Value-initialization: arrays should have each element value-initialized", +// http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 +// Last checked version: Embarcadero C++ 6.21 +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, April 2010) +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION + +# if defined(NDEBUG) && defined(__cplusplus) + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif + +// Reportedly, #pragma once is supported since C++ Builder 2010 +#if (__CODEGEARC__ >= 0x620) +# define BOOST_HAS_PRAGMA_ONCE +#endif + +#define BOOST_NO_FENV_H + +// +// C++0x macros: +// +#if (__CODEGEARC__ <= 0x620) +#define BOOST_NO_CXX11_STATIC_ASSERT +#else +#define BOOST_HAS_STATIC_ASSERT +#endif +#define BOOST_HAS_CHAR16_T +#define BOOST_HAS_CHAR32_T +#define BOOST_HAS_LONG_LONG +// #define BOOST_HAS_ALIGNOF +#define BOOST_HAS_DECLTYPE +#define BOOST_HAS_EXPLICIT_CONVERSION_OPS +// #define BOOST_HAS_RVALUE_REFS +#define BOOST_HAS_SCOPED_ENUM +// #define BOOST_HAS_STATIC_ASSERT +#define BOOST_HAS_STD_TYPE_TRAITS + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif + +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif + +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif + +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +// +// TR1 macros: +// +#define BOOST_HAS_TR1_HASH +#define BOOST_HAS_TR1_TYPE_TRAITS +#define BOOST_HAS_TR1_UNORDERED_MAP +#define BOOST_HAS_TR1_UNORDERED_SET + +#define BOOST_HAS_MACRO_USE_FACET + +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST + +// On non-Win32 platforms let the platform config figure this out: +#ifdef _WIN32 +# define BOOST_HAS_STDINT_H +#endif + +// +// __int64: +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif +// +// ABI fixing headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +// +// Disable Win32 support in ANSI mode: +// +# pragma defineonoption BOOST_DISABLE_WIN32 -A +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +#define BOOST_COMPILER "CodeGear C++ version " BOOST_STRINGIZE(__CODEGEARC__) + +#endif // #if !defined(__clang__) diff --git a/src/boost/config/compiler/comeau.hpp b/src/boost/config/compiler/comeau.hpp new file mode 100644 index 00000000..ca80fac3 --- /dev/null +++ b/src/boost/config/compiler/comeau.hpp @@ -0,0 +1,59 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Douglas Gregor 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are 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 most recent version. + +// Comeau C++ compiler setup: + +#include + +#if (__COMO_VERSION__ <= 4245) + +# if defined(_MSC_VER) && _MSC_VER <= 1300 +# if _MSC_VER > 100 + // only set this in non-strict mode: +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# endif +# endif + +// Void returns don't work when emulating VC 6 (Peter Dimov) +// TODO: look up if this doesn't apply to the whole 12xx range +# if defined(_MSC_VER) && (_MSC_VER < 1300) +# define BOOST_NO_VOID_RETURNS +# endif + +#endif // version 4245 + +// +// enable __int64 support in VC emulation mode +// +# if defined(_MSC_VER) && (_MSC_VER >= 1200) +# define BOOST_HAS_MS_INT64 +# endif + +#define BOOST_COMPILER "Comeau compiler version " BOOST_STRINGIZE(__COMO_VERSION__) + +// +// versions check: +// we don't know Comeau prior to version 4245: +#if __COMO_VERSION__ < 4245 +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4245: +#if (__COMO_VERSION__ > 4245) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + diff --git a/src/boost/config/compiler/common_edg.hpp b/src/boost/config/compiler/common_edg.hpp new file mode 100644 index 00000000..0d59ae0e --- /dev/null +++ b/src/boost/config/compiler/common_edg.hpp @@ -0,0 +1,185 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright Markus Schoepflin 2005. +// Use, modification and distribution are 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 most recent version. + +// +// Options common to all edg based compilers. +// +// This is included from within the individual compiler mini-configs. + +#ifndef __EDG_VERSION__ +# error This file requires that __EDG_VERSION__ be defined. +#endif + +#if (__EDG_VERSION__ <= 238) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_SFINAE +#endif + +#if (__EDG_VERSION__ <= 240) +# define BOOST_NO_VOID_RETURNS +#endif + +#if (__EDG_VERSION__ <= 241) && !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +#endif + +#if (__EDG_VERSION__ <= 244) && !defined(BOOST_NO_TEMPLATE_TEMPLATES) +# define BOOST_NO_TEMPLATE_TEMPLATES +#endif + +#if (__EDG_VERSION__ < 300) && !defined(BOOST_NO_IS_ABSTRACT) +# define BOOST_NO_IS_ABSTRACT +#endif + +#if (__EDG_VERSION__ <= 303) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// See also kai.hpp which checks a Kai-specific symbol for EH +# if !defined(__KCC) && !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +# if !defined(__NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + +// Not sure what version was the first to support #pragma once, but +// different EDG-based compilers (e.g. Intel) supported it for ages. +// Add a proper version check if it causes problems. +#define BOOST_HAS_PRAGMA_ONCE + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG +// +#if (__EDG_VERSION__ < 310) +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if (__EDG_VERSION__ <= 310) +// No support for initializer lists +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif +#if (__EDG_VERSION__ < 400) +# define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +//__cpp_decltype 200707 possibly? +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 + +#if !defined(__cpp_unicode_characters) || (__cpp_unicode_characters < 200704) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif +#if !defined(__cpp_unicode_literals) || (__cpp_unicode_literals < 200710) +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif +#if !defined(__cpp_user_defined_literals) || (__cpp_user_defined_literals < 200809) +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif +#if !defined(__cpp_variadic_templates) || (__cpp_variadic_templates < 200704) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 200907) +# define BOOST_NO_CXX11_CONSTEXPR +#endif +#if !defined(__cpp_lambdas) || (__cpp_lambdas < 200907) +# define BOOST_NO_CXX11_LAMBDAS +#endif +#if !defined(__cpp_range_based_for) || (__cpp_range_based_for < 200710) +# define BOOST_NO_CXX11_RANGE_BASED_FOR +#endif +#if !defined(__cpp_raw_strings) || (__cpp_raw_strings < 200610) +# define BOOST_NO_CXX11_RAW_LITERALS +#endif + + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#ifdef c_plusplus +// EDG has "long long" in non-strict mode +// However, some libraries have insufficient "long long" support +// #define BOOST_HAS_LONG_LONG +#endif diff --git a/src/boost/config/compiler/compaq_cxx.hpp b/src/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 00000000..4d6b8ab3 --- /dev/null +++ b/src/boost/config/compiler/compaq_cxx.hpp @@ -0,0 +1,19 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are 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 most recent version. + +// Tru64 C++ compiler setup (now HP): + +#define BOOST_COMPILER "HP Tru64 C++ " BOOST_STRINGIZE(__DECCXX_VER) + +#include + +// +// versions check: +// Nothing to do here? + + + diff --git a/src/boost/config/compiler/cray.hpp b/src/boost/config/compiler/cray.hpp new file mode 100644 index 00000000..e40fd05a --- /dev/null +++ b/src/boost/config/compiler/cray.hpp @@ -0,0 +1,446 @@ +// Copyright 2011 John Maddock +// Copyright 2013, 2017-2018 Cray, Inc. +// Use, modification and distribution are 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 most recent version. + +// Cray C++ compiler setup. +// +// There are a few parameters that affect the macros defined in this file: +// +// - What version of CCE (Cray Compiling Environment) are we running? This +// comes from the '_RELEASE_MAJOR', '_RELEASE_MINOR', and +// '_RELEASE_PATCHLEVEL' macros. +// - What C++ standards conformance level are we using (e.g. '-h +// std=c++14')? This comes from the '__cplusplus' macro. +// - Are we using GCC extensions ('-h gnu' or '-h nognu')? If we have '-h +// gnu' then CCE emulates GCC, and the macros '__GNUC__', +// '__GNUC_MINOR__', and '__GNUC_PATCHLEVEL__' are defined. +// +// This file is organized as follows: +// +// - Verify that the combination of parameters listed above is supported. +// If we have an unsupported combination, we abort with '#error'. +// - Establish baseline values for all Boost macros. +// - Apply changes to the baseline macros based on compiler version. These +// changes are cummulative so each version section only describes the +// changes since the previous version. +// - Within each version section, we may also apply changes based on +// other parameters (i.e. C++ standards conformance level and GCC +// extensions). +// +// To test changes to this file: +// +// ``` +// module load cce/8.6.5 # Pick the version you want to test. +// cd boost/libs/config/test/all +// b2 -j 8 toolset=cray cxxstd=03 cxxstd=11 cxxstd=14 cxxstd-dialect=gnu linkflags=-lrt +// ``` +// Note: Using 'cxxstd-dialect=iso' is not supported at this time (the +// tests run, but many tests fail). +// +// Note: 'linkflags=-lrt' is needed in Cray Linux Environment. Otherwise +// you get an 'undefined reference to clock_gettime' error. +// +// Note: If a test '*_fail.cpp' file compiles, but fails to run, then it is +// reported as a defect. However, this is not actually a defect. This is an +// area where the test system is somewhat broken. Tests that are failing +// because of this problem are noted in the comments. +// +// Pay attention to the macro definitions for the macros you wish to +// modify. For example, only macros categorized as compiler macros should +// appear in this file; platform macros should not appear in this file. +// Also, some macros have to be defined to specific values; it is not +// always enough to define or undefine a macro. +// +// Macro definitions are available in the source code at: +// +// `boost/libs/config/doc/html/boost_config/boost_macro_reference.html` +// +// Macro definitions are also available online at: +// +// http://www.boost.org/doc/libs/master/libs/config/doc/html/boost_config/boost_macro_reference.html +// +// Typically, if you enable a feature, and the tests pass, then you have +// nothing to worry about. However, it's sometimes hard to figure out if a +// disabled feature needs to stay disabled. To get a list of disabled +// features, run 'b2' in 'boost/libs/config/checks'. These are the macros +// you should pay attention to (in addition to macros that cause test +// failures). + +//// +//// Front matter +//// + +// In a developer build of the Cray compiler (i.e. a compiler built by a +// Cray employee), the release patch level is reported as "x". This gives +// versions that look like e.g. "8.6.x". +// +// To accomplish this, the the Cray compiler preprocessor inserts: +// +// #define _RELEASE_PATCHLEVEL x +// +// If we are using a developer build of the compiler, we want to use the +// configuration macros for the most recent patch level of the release. To +// accomplish this, we'll pretend that _RELEASE_PATCHLEVEL is 99. +// +// However, it's difficult to detect if _RELEASE_PATCHLEVEL is x. We must +// consider that the x will be expanded if x is defined as a macro +// elsewhere. For example, imagine if someone put "-D x=3" on the command +// line, and _RELEASE_PATCHLEVEL is x. Then _RELEASE_PATCHLEVEL would +// expand to 3, and we could not distinguish it from an actual +// _RELEASE_PATCHLEVEL of 3. This problem only affects developer builds; in +// production builds, _RELEASE_PATCHLEVEL is always an integer. +// +// IMPORTANT: In developer builds, if x is defined as a macro, you will get +// an incorrect configuration. The behavior in this case is undefined. +// +// Even if x is not defined, we have to use some trickery to detect if +// _RELEASE_PATCHLEVEL is x. First we define BOOST_CRAY_x to some arbitrary +// magic value, 9867657. Then we use BOOST_CRAY_APPEND to append the +// expanded value of _RELEASE_PATCHLEVEL to the string "BOOST_CRAY_". +// +// - If _RELEASE_PATCHLEVEL is undefined, we get "BOOST_CRAY_". +// - If _RELEASE_PATCHLEVEL is 5, we get "BOOST_CRAY_5". +// - If _RELEASE_PATCHLEVEL is x (and x is not defined) we get +// "BOOST_CRAY_x": +// +// Then we check if BOOST_CRAY_x is equal to the output of +// BOOST_CRAY_APPEND. In other words, the output of BOOST_CRAY_APPEND is +// treated as a macro name, and expanded again. If we can safely assume +// that BOOST_CRAY_ is not a macro defined as our magic number, and +// BOOST_CRAY_5 is not a macro defined as our magic number, then the only +// way the equality test can pass is if _RELEASE_PATCHLEVEL expands to x. +// +// So, that is how we detect if we are using a developer build of the Cray +// compiler. + +#define BOOST_CRAY_x 9867657 // Arbitrary number +#define BOOST_CRAY_APPEND(MACRO) BOOST_CRAY_APPEND_INTERNAL(MACRO) +#define BOOST_CRAY_APPEND_INTERNAL(MACRO) BOOST_CRAY_##MACRO + +#if BOOST_CRAY_x == BOOST_CRAY_APPEND(_RELEASE_PATCHLEVEL) + + // This is a developer build. + // + // - _RELEASE_PATCHLEVEL is defined as x, and x is not defined as a macro. + + // Pretend _RELEASE_PATCHLEVEL is 99, so we get the configuration for the + // most recent patch level in this release. + + #define BOOST_CRAY_VERSION (_RELEASE_MAJOR * 10000 + _RELEASE_MINOR * 100 + 99) + +#else + + // This is a production build. + // + // _RELEASE_PATCHLEVEL is not defined as x, or x is defined as a macro. + + #define BOOST_CRAY_VERSION (_RELEASE_MAJOR * 10000 + _RELEASE_MINOR * 100 + _RELEASE_PATCHLEVEL) + +#endif // BOOST_CRAY_x == BOOST_CRAY_APPEND(_RELEASE_PATCHLEVEL) + +#undef BOOST_CRAY_APPEND_INTERNAL +#undef BOOST_CRAY_APPEND +#undef BOOST_CRAY_x + + +#ifdef __GNUC__ +# define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Cray C++ version " BOOST_STRINGIZE(_RELEASE_MAJOR) "." BOOST_STRINGIZE(_RELEASE_MINOR) "." BOOST_STRINGIZE(_RELEASE_PATCHLEVEL) +#endif + +// Since the Cray compiler defines '__GNUC__', we have to emulate some +// additional GCC macros in order to make everything work. +// +// FIXME: Perhaps Cray should fix the compiler to define these additional +// macros for GCC emulation? + +#if __cplusplus >= 201103L && defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define __GXX_EXPERIMENTAL_CXX0X__ 1 +#endif + +//// +//// Parameter validation +//// + +// FIXME: Do we really need to support compilers before 8.5? Do they pass +// the Boost.Config tests? + +#if BOOST_CRAY_VERSION < 80000 +# error "Boost is not configured for Cray compilers prior to version 8, please try the configure script." +#endif + +// We only support recent EDG based compilers. + +#ifndef __EDG__ +# error "Unsupported Cray compiler, please try running the configure script." +#endif + +//// +//// Baseline values +//// + +#include + +#define BOOST_HAS_NRVO +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNRESTRICTED_UNION +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +//#define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +#define BOOST_MATH_DISABLE_STD_FPCLASSIFY +//#define BOOST_HAS_FPCLASSIFY + +#define BOOST_SP_USE_PTHREADS +#define BOOST_AC_USE_PTHREADS + +// +// Everything that follows is working around what are thought to be +// compiler shortcomings. Revist all of these regularly. +// + +//#define BOOST_USE_ENUM_STATIC_ASSERT +//#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS //(this may be implied by the previous #define + +// These constants should be provided by the compiler. + +#ifndef __ATOMIC_RELAXED +#define __ATOMIC_RELAXED 0 +#define __ATOMIC_CONSUME 1 +#define __ATOMIC_ACQUIRE 2 +#define __ATOMIC_RELEASE 3 +#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_SEQ_CST 5 +#endif + +//// +//// Version changes +//// + +// +// 8.5.0 +// + +#if BOOST_CRAY_VERSION >= 80500 + +#if __cplusplus >= 201103L + +#undef BOOST_HAS_NRVO +#undef BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#undef BOOST_NO_CXX11_AUTO_DECLARATIONS +#undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#undef BOOST_NO_CXX11_CHAR16_T +#undef BOOST_NO_CXX11_CHAR32_T +#undef BOOST_NO_CXX11_CONSTEXPR +#undef BOOST_NO_CXX11_DECLTYPE +#undef BOOST_NO_CXX11_DECLTYPE_N3276 +#undef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#undef BOOST_NO_CXX11_DELETED_FUNCTIONS +#undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#undef BOOST_NO_CXX11_FINAL +#undef BOOST_NO_CXX11_OVERRIDE +#undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#undef BOOST_NO_CXX11_LAMBDAS +#undef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#undef BOOST_NO_CXX11_NOEXCEPT +#undef BOOST_NO_CXX11_NULLPTR +#undef BOOST_NO_CXX11_RANGE_BASED_FOR +#undef BOOST_NO_CXX11_RAW_LITERALS +#undef BOOST_NO_CXX11_REF_QUALIFIERS +#undef BOOST_NO_CXX11_RVALUE_REFERENCES +#undef BOOST_NO_CXX11_SCOPED_ENUMS +#undef BOOST_NO_CXX11_SFINAE_EXPR +#undef BOOST_NO_CXX11_STATIC_ASSERT +#undef BOOST_NO_CXX11_TEMPLATE_ALIASES +#undef BOOST_NO_CXX11_THREAD_LOCAL +#undef BOOST_NO_CXX11_UNICODE_LITERALS +#undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#undef BOOST_NO_CXX11_USER_DEFINED_LITERALS +#undef BOOST_NO_CXX11_VARIADIC_MACROS +#undef BOOST_NO_CXX11_VARIADIC_TEMPLATES +#undef BOOST_NO_CXX11_UNRESTRICTED_UNION +#undef BOOST_NO_SFINAE_EXPR +#undef BOOST_NO_TWO_PHASE_NAME_LOOKUP +#undef BOOST_MATH_DISABLE_STD_FPCLASSIFY +#undef BOOST_SP_USE_PTHREADS +#undef BOOST_AC_USE_PTHREADS + +#define BOOST_HAS_VARIADIC_TMPL +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG +#define BOOST_HAS_TR1_COMPLEX_OVERLOADS +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_STATIC_ASSERT +#define BOOST_HAS_SIGACTION +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_RVALUE_REFS +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_YIELD +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#define BOOST_HAS_NRVO +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_NANOSLEEP +#define BOOST_NO_CXX11_SMART_PTR +#define BOOST_NO_CXX11_HDR_FUNCTIONAL +#define BOOST_NO_CXX14_CONSTEXPR +#define BOOST_HAS_LONG_LONG +#define BOOST_HAS_FLOAT128 + +#if __cplusplus < 201402L +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif // __cplusplus < 201402L + +#endif // __cplusplus >= 201103L + +#endif // BOOST_CRAY_VERSION >= 80500 + +// +// 8.6.4 +// (versions prior to 8.6.5 do not define _RELEASE_PATCHLEVEL) +// + +#if BOOST_CRAY_VERSION >= 80600 + +#if __cplusplus >= 199711L +#define BOOST_HAS_FLOAT128 +#define BOOST_HAS_PTHREAD_YIELD // This is a platform macro, but it improves test results. +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION // This is correct. Test compiles, but fails to run. +#undef BOOST_NO_CXX11_CHAR16_T +#undef BOOST_NO_CXX11_CHAR32_T +#undef BOOST_NO_CXX11_INLINE_NAMESPACES +#undef BOOST_NO_CXX11_FINAL +#undef BOOST_NO_CXX11_OVERRIDE +#undef BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_SFINAE_EXPR // This is correct, even though '*_fail.cpp' test fails. +#undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#undef BOOST_NO_CXX11_VARIADIC_MACROS +#undef BOOST_NO_CXX11_VARIADIC_TEMPLATES +// 'BOOST_NO_DEDUCED_TYPENAME' test is broken. The test files are enabled / +// disabled with an '#ifdef BOOST_DEDUCED_TYPENAME'. However, +// 'boost/libs/config/include/boost/config/detail/suffix.hpp' ensures that +// 'BOOST_DEDUCED_TYPENAME' is always defined (the value it is defined as +// depends on 'BOOST_NO_DEDUCED_TYPENAME'). So, modifying +// 'BOOST_NO_DEDUCED_TYPENAME' has no effect on which tests are run. +// +// The 'no_ded_typename_pass.cpp' test should always compile and run +// successfully, because 'BOOST_DEDUCED_TYPENAME' must always have an +// appropriate value (it's not just something that you turn on or off). +// Therefore, if you wish to test changes to 'BOOST_NO_DEDUCED_TYPENAME', +// you have to modify 'no_ded_typename_pass.cpp' to unconditionally include +// 'boost_no_ded_typename.ipp'. +#undef BOOST_NO_DEDUCED_TYPENAME // This is correct. Test is broken. +#undef BOOST_NO_SFINAE_EXPR +#undef BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif // __cplusplus >= 199711L + +#if __cplusplus >= 201103L +#undef BOOST_NO_CXX11_ALIGNAS +#undef BOOST_NO_CXX11_ALIGNOF +#undef BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_HDR_ATOMIC +#undef BOOST_NO_CXX11_HDR_FUNCTIONAL +#define BOOST_NO_CXX11_HDR_REGEX // This is correct. Test compiles, but fails to run. +#undef BOOST_NO_CXX11_SFINAE_EXPR +#undef BOOST_NO_CXX11_SMART_PTR +#undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201402L +#undef BOOST_NO_CXX14_CONSTEXPR +#define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif // __cplusplus == 201402L + +#endif // BOOST_CRAY_VERSION >= 80600 + +// +// 8.6.5 +// (no change from 8.6.4) +// + +// +// 8.7.0 +// + +#if BOOST_CRAY_VERSION >= 80700 + +#if __cplusplus >= 199711L +#endif // __cplusplus >= 199711L + +#if __cplusplus >= 201103L +#undef BOOST_NO_CXX11_HDR_ATOMIC +#undef BOOST_NO_CXX11_HDR_REGEX +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201402L +#endif // __cplusplus == 201402L + +#endif // BOOST_CRAY_VERSION >= 80700 + +// +// Next release +// + +#if BOOST_CRAY_VERSION > 80799 + +#if __cplusplus >= 199711L +#endif // __cplusplus >= 199711L + +#if __cplusplus >= 201103L +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201402L +#endif // __cplusplus == 201402L + +#endif // BOOST_CRAY_VERSION > 80799 + +//// +//// Remove temporary macros +//// + +// I've commented out some '#undef' statements to signify that we purposely +// want to keep certain macros. + +//#undef __GXX_EXPERIMENTAL_CXX0X__ +//#undef BOOST_COMPILER +#undef BOOST_GCC_VERSION +#undef BOOST_CRAY_VERSION diff --git a/src/boost/config/compiler/diab.hpp b/src/boost/config/compiler/diab.hpp new file mode 100644 index 00000000..943db83f --- /dev/null +++ b/src/boost/config/compiler/diab.hpp @@ -0,0 +1,26 @@ +// (C) Copyright Brian Kuhl 2016. +// Use, modification and distribution are 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) + +// Check this is a recent EDG based compiler, otherwise we don't support it here: + + +#ifndef __EDG_VERSION__ +# error "Unknown Diab compiler version - please run the configure tests and report the results" +#endif + +#include "boost/config/compiler/common_edg.hpp" + +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS + +#define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE +#define BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS +#define BOOST_REGEX_NO_EXTERNAL_TEMPLATES + +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_HDR_CODECVT +#define BOOST_NO_CXX11_NUMERIC_LIMITS + +#define BOOST_COMPILER "Wind River Diab " BOOST_STRINGIZE(__VERSION_NUMBER__) diff --git a/src/boost/config/compiler/digitalmars.hpp b/src/boost/config/compiler/digitalmars.hpp new file mode 100644 index 00000000..4fa347ab --- /dev/null +++ b/src/boost/config/compiler/digitalmars.hpp @@ -0,0 +1,146 @@ +// Copyright (C) Christof Meerwald 2003 +// Copyright (C) Dan Watkins 2003 +// +// Use, modification and distribution are 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) + +// Digital Mars C++ compiler setup: +#define BOOST_COMPILER __DMC_VERSION_STRING__ + +#define BOOST_HAS_LONG_LONG +#define BOOST_HAS_PRAGMA_ONCE + +#if !defined(BOOST_STRICT_CONFIG) +#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#define BOOST_NO_OPERATORS_IN_NAMESPACE +#define BOOST_NO_UNREACHABLE_RETURN_DETECTION +#define BOOST_NO_SFINAE +#define BOOST_NO_USING_TEMPLATE +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// has macros: +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_WINTHREADS + +#if (__DMC__ >= 0x847) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// +// Is this really the best way to detect whether the std lib is in namespace std? +// +#ifdef __cplusplus +#include +#endif +#if !defined(__STL_IMPORT_VENDOR_CSTD) && !defined(_STLP_IMPORT_VENDOR_CSTD) +# define BOOST_NO_STDC_NAMESPACE +#endif + + +// check for exception handling support: +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +// +// C++0x features +// +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#if (__DMC__ <= 0x840) +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is ...: +#if (__DMC__ > 0x848) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/src/boost/config/compiler/gcc.hpp b/src/boost/config/compiler/gcc.hpp new file mode 100644 index 00000000..fc05a918 --- /dev/null +++ b/src/boost/config/compiler/gcc.hpp @@ -0,0 +1,386 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Jens Maurer 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Douglas Gregor 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Synge Todo 2003. +// Use, modification and distribution are 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 most recent version. + +// GNU C++ compiler setup. + +// +// Define BOOST_GCC so we know this is "real" GCC and not some pretender: +// +#define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#if !defined(__CUDACC__) +#define BOOST_GCC BOOST_GCC_VERSION +#endif + +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) +# define BOOST_GCC_CXX11 +#endif + +#if __GNUC__ == 3 +# if defined (__PATHSCALE__) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_IS_ABSTRACT +# endif + +# if __GNUC_MINOR__ < 4 +# define BOOST_NO_IS_ABSTRACT +# endif +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if __GNUC__ < 4 +// +// All problems to gcc-3.x and earlier here: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# ifdef __OPEN64__ +# define BOOST_NO_IS_ABSTRACT +# endif +#endif + +// GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links +#if BOOST_GCC_VERSION >= 30400 +#define BOOST_HAS_PRAGMA_ONCE +#endif + +#if BOOST_GCC_VERSION < 40400 +// Previous versions of GCC did not completely implement value-initialization: +// GCC Bug 30111, "Value-initialization of POD base class doesn't initialize +// members", reported by Jonathan Wakely in 2006, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4) +// GCC Bug 33916, "Default constructor fails to initialize array members", +// reported by Michael Elizabeth Chastain in 2007, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4) +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +#if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// Except on Darwin with standard compliance enabled (-pedantic) +// Apple gcc helpfully defines this macro we can query +// +#if !defined(__DARWIN_NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +#endif + +// +// gcc implements the named return value optimization since version 3.1 +// +#define BOOST_HAS_NRVO + +// Branch prediction hints +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __GNUC__ >= 4 +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) + // All Win32 development environments, including 64-bit Windows and MinGW, define + // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, + // so does not define _WIN32 or its variants, but still supports dllexport/dllimport. +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) +# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) +# else +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# endif +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#else +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif + +// +// RTTI and typeinfo detection is possible post gcc-4.3: +// +#if BOOST_GCC_VERSION > 40300 +# ifndef __GXX_RTTI +# ifndef BOOST_NO_TYPEID +# define BOOST_NO_TYPEID +# endif +# ifndef BOOST_NO_RTTI +# define BOOST_NO_RTTI +# endif +# endif +#endif + +// +// Recent GCC versions have __int128 when in 64-bit mode. +// +// We disable this if the compiler is really nvcc with C++03 as it +// doesn't actually support __int128 as of CUDA_VERSION=7500 +// even though it defines __SIZEOF_INT128__. +// See https://svn.boost.org/trac/boost/ticket/8048 +// https://svn.boost.org/trac/boost/ticket/11852 +// Only re-enable this for nvcc if you're absolutely sure +// of the circumstances under which it's supported: +// +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_INT128 +#endif +// +// Recent GCC versions have a __float128 native type, we need to +// include a std lib header to detect this - not ideal, but we'll +// be including later anyway when we select the std lib. +// +// Nevertheless, as of CUDA 7.5, using __float128 with the host +// compiler in pre-C++11 mode is still not supported. +// See https://svn.boost.org/trac/boost/ticket/11852 +// +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_FLOAT128 +#endif + +// C++0x features in 4.3.n and later +// +#if (BOOST_GCC_VERSION >= 40300) && defined(BOOST_GCC_CXX11) +// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are +// passed on the command line, which in turn defines +// __GXX_EXPERIMENTAL_CXX0X__. +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +# define BOOST_HAS_VARIADIC_TMPL +#else +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +// C++0x features in 4.4.n and later +// +#if (BOOST_GCC_VERSION < 40400) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if BOOST_GCC_VERSION < 40500 +# define BOOST_NO_SFINAE_EXPR +#endif + +// GCC 4.5 forbids declaration of defaulted functions in private or protected sections +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 5) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// C++0x features in 4.5.0 and later +// +#if (BOOST_GCC_VERSION < 40500) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_ALIGNOF +#endif + +// C++0x features in 4.5.1 and later +// +#if (BOOST_GCC_VERSION < 40501) || !defined(BOOST_GCC_CXX11) +// scoped enums have a serious bug in 4.4.0, so define BOOST_NO_CXX11_SCOPED_ENUMS before 4.5.1 +// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064 +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +// C++0x features in 4.6.n and later +// +#if (BOOST_GCC_VERSION < 40600) || !defined(BOOST_GCC_CXX11) +#define BOOST_NO_CXX11_DEFAULTED_MOVES +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +// C++0x features in 4.7.n and later +// +#if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11) +// Note that while constexpr is partly supported in gcc-4.6 it's a +// pre-std version with several bugs: +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +# define BOOST_NO_CXX11_OVERRIDE +#endif + +// C++0x features in 4.8.n and later +// +#if (BOOST_GCC_VERSION < 40800) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_SFINAE_EXPR +#endif + +// C++0x features in 4.8.1 and later +// +#if (BOOST_GCC_VERSION < 40801) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +// C++0x features in 4.9.n and later +// +#if (BOOST_GCC_VERSION < 40900) || !defined(BOOST_GCC_CXX11) +// Although alignas support is added in gcc 4.8, it does not accept +// dependent constant expressions as an argument until gcc 4.9. +# define BOOST_NO_CXX11_ALIGNAS +#endif + +// C++0x features in 5.1 and later +// +#if (BOOST_GCC_VERSION < 50100) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +// C++14 features in 4.9.0 and later +// +#if (BOOST_GCC_VERSION < 40900) || (__cplusplus < 201300) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX14_DECLTYPE_AUTO +# if !((BOOST_GCC_VERSION >= 40801) && (BOOST_GCC_VERSION < 40900) && defined(BOOST_GCC_CXX11)) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# endif +#endif + + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if (BOOST_GCC_VERSION < 50200) || !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if (__GNUC__ < 7) || (__cplusplus < 201703L) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#if __GNUC__ >= 7 +# define BOOST_FALLTHROUGH __attribute__((fallthrough)) +#endif + +#if (__GNUC__ < 11) && defined(__MINGW32__) && !defined(__MINGW64__) +// thread_local was broken on mingw for all 32bit compiler releases prior to 11.x, see +// https://sourceforge.net/p/mingw-w64/bugs/527/ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 +// Not setting this causes program termination on thread exit. +#define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +// +// Unused attribute: +#if __GNUC__ >= 4 +# define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#endif + +// Type aliasing hint. Supported since gcc 3.3. +#define BOOST_MAY_ALIAS __attribute__((__may_alias__)) + +// Unreachable code markup +#if BOOST_GCC_VERSION >= 40500 +#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); +#endif + +// Deprecated symbol markup +#if BOOST_GCC_VERSION >= 40500 +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#else +#define BOOST_DEPRECATED(msg) __attribute__((deprecated)) +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "GNU C++ version " __VERSION__ +#endif + +// ConceptGCC compiler: +// http://www.generic-programming.org/software/ConceptGCC/ +#ifdef __GXX_CONCEPTS__ +# define BOOST_HAS_CONCEPTS +# define BOOST_COMPILER "ConceptGCC version " __VERSION__ +#endif + +// versions check: +// we don't know gcc prior to version 3.30: +#if (BOOST_GCC_VERSION < 30300) +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 8.1: +#if (BOOST_GCC_VERSION > 80100) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your compiler - please check for an updated Boost release." +# else +// we don't emit warnings here anymore since there are no defect macros defined for +// gcc post 3.4, so any failures are gcc regressions... +//# warning "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + diff --git a/src/boost/config/compiler/gcc_xml.hpp b/src/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 00000000..e23b14d0 --- /dev/null +++ b/src/boost/config/compiler/gcc_xml.hpp @@ -0,0 +1,115 @@ +// (C) Copyright John Maddock 2006. +// Use, modification and distribution are 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 most recent version. + +// GCC-XML C++ compiler setup: + +# if !defined(__GCCXML_GNUC__) || ((__GCCXML_GNUC__ <= 3) && (__GCCXML_GNUC_MINOR__ <= 3)) +# define BOOST_NO_IS_ABSTRACT +# endif + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// +#define BOOST_HAS_LONG_LONG + +// C++0x features: +// +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_SFINAE_EXPR +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_ALIGNOF +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_OVERRIDE +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ diff --git a/src/boost/config/compiler/greenhills.hpp b/src/boost/config/compiler/greenhills.hpp new file mode 100644 index 00000000..39112c2c --- /dev/null +++ b/src/boost/config/compiler/greenhills.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are 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 most recent version. + +// Greenhills C++ compiler setup: + +#define BOOST_COMPILER "Greenhills C++ version " BOOST_STRINGIZE(__ghs) + +#include + +// +// versions check: +// we don't support Greenhills prior to version 0: +#if __ghs < 0 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0: +#if (__ghs > 0) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/src/boost/config/compiler/hp_acc.hpp b/src/boost/config/compiler/hp_acc.hpp new file mode 100644 index 00000000..42e35e55 --- /dev/null +++ b/src/boost/config/compiler/hp_acc.hpp @@ -0,0 +1,153 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are 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 most recent version. + +// HP aCC C++ compiler setup: + +#if defined(__EDG__) +#include +#endif + +#if (__HP_aCC <= 33100) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# if !defined(_NAMESPACE_STD) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +# endif +#endif + +#if (__HP_aCC <= 33300) +// member templates are sufficiently broken that we disable them for now +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +#endif + +#if (__HP_aCC <= 38000) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#if (__HP_aCC > 50000) && (__HP_aCC < 60000) +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_NO_TEMPLATE_TEMPLATES +# define BOOST_NO_SWPRINTF +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +// optional features rather than defects: +#if (__HP_aCC >= 33900) +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +#if (__HP_aCC >= 50000 ) && (__HP_aCC <= 53800 ) || (__HP_aCC < 31300 ) +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +// This macro should not be defined when compiling in strict ansi +// mode, but, currently, we don't have the ability to determine +// what standard mode we are compiling with. Some future version +// of aCC6 compiler will provide predefined macros reflecting the +// compilation options, including the standard mode. +#if (__HP_aCC >= 60000) || ((__HP_aCC > 38000) && defined(__hpxstd98)) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#define BOOST_COMPILER "HP aCC version " BOOST_STRINGIZE(__HP_aCC) + +// +// versions check: +// we don't support HP aCC prior to version 33000: +#if __HP_aCC < 33000 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// +// Extended checks for supporting aCC on PA-RISC +#if __HP_aCC > 30000 && __HP_aCC < 50000 +# if __HP_aCC < 38000 + // versions prior to version A.03.80 not supported +# error "Compiler version not supported - version A.03.80 or higher is required" +# elif !defined(__hpxstd98) + // must compile using the option +hpxstd98 with version A.03.80 and above +# error "Compiler option '+hpxstd98' is required for proper support" +# endif //PA-RISC +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if !defined(__EDG__) + +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +/* + See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and + https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443436 +*/ + +#if (__HP_aCC < 62500) || !defined(HP_CXX0x_SOURCE) + #define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#endif + +// +// last known and checked version for HP-UX/ia64 is 61300 +// last known and checked version for PA-RISC is 38000 +#if ((__HP_aCC > 61300) || ((__HP_aCC > 38000) && defined(__hpxstd98))) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/src/boost/config/compiler/intel.hpp b/src/boost/config/compiler/intel.hpp new file mode 100644 index 00000000..6a343972 --- /dev/null +++ b/src/boost/config/compiler/intel.hpp @@ -0,0 +1,577 @@ +// (C) Copyright John Maddock 2001-8. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright Guillaume Melquiond 2002 - 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Martin Wille 2003. +// Use, modification and distribution are 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 most recent version. + +// Intel compiler setup: + +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) + +#ifdef _MSC_VER + +#include + +#undef BOOST_MSVC +#undef BOOST_MSVC_FULL_VER + +#if (__INTEL_COMPILER >= 1500) && (_MSC_VER >= 1900) +// +// These appear to be supported, even though VC++ may not support them: +// +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#undef BOOST_NO_CXX14_BINARY_LITERALS +// This one may be a little risky to enable?? +#undef BOOST_NO_SFINAE_EXPR + +#endif + +#if (__INTEL_COMPILER <= 1600) && !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#else // defined(_MSC_VER) + +#include + +#undef BOOST_GCC_VERSION +#undef BOOST_GCC_CXX11 +#undef BOOST_GCC +#undef BOOST_FALLTHROUGH + +// Broken in all versions up to 17 (newer versions not tested) +#if (__INTEL_COMPILER <= 1700) && !defined(BOOST_NO_CXX14_CONSTEXPR) +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if (__INTEL_COMPILER >= 1800) && (__cplusplus >= 201703) +# define BOOST_FALLTHROUGH [[fallthrough]] +#endif + +#endif // defined(_MSC_VER) + +#undef BOOST_COMPILER + +#if defined(__INTEL_COMPILER) +#if __INTEL_COMPILER == 9999 +# define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. +#else +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#endif +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +// Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' +#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_INTEL_STDCXX0X +#endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_INTEL_STDCXX0X +#endif + +#ifdef __GNUC__ +# define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#if !defined(BOOST_COMPILER) +# if defined(BOOST_INTEL_STDCXX0X) +# define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# else +# define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# endif +#endif + +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#else // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) + +#include + +#if defined(__INTEL_COMPILER) +#if __INTEL_COMPILER == 9999 +# define BOOST_INTEL_CXX_VERSION 1200 // Intel bug in 12.1. +#else +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#endif +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +// Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' +#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_INTEL_STDCXX0X +#endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_INTEL_STDCXX0X +#endif + +#ifdef __GNUC__ +# define BOOST_INTEL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#if !defined(BOOST_COMPILER) +# if defined(BOOST_INTEL_STDCXX0X) +# define BOOST_COMPILER "Intel C++ C++0x mode version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# else +# define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +# endif +#endif + +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 600) + +# if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) + +// Boost libraries assume strong standard conformance unless otherwise +// indicated by a config macro. As configured by Intel, the EDG front-end +// requires certain compiler options be set to achieve that strong conformance. +// Particularly /Qoption,c,--arg_dep_lookup (reported by Kirk Klobe & Thomas Witt) +// and /Zc:wchar_t,forScope. See boost-root/tools/build/intel-win32-tools.jam for +// details as they apply to particular versions of the compiler. When the +// compiler does not predefine a macro indicating if an option has been set, +// this config file simply assumes the option has been set. +// Thus BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP will not be defined, even if +// the compiler option is not enabled. + +# define BOOST_NO_SWPRINTF +# endif + +// Void returns, 64 bit integrals don't work when emulating VC 6 (Peter Dimov) + +# if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_VOID_RETURNS +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 710) && defined(_WIN32) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +// See http://aspn.activestate.com/ASPN/Mail/Message/boost/1614864 +#if BOOST_INTEL_CXX_VERSION < 600 +# define BOOST_NO_INTRINSIC_WCHAR_T +#else +// We should test the macro _WCHAR_T_DEFINED to check if the compiler +// supports wchar_t natively. *BUT* there is a problem here: the standard +// headers define this macro if they typedef wchar_t. Anyway, we're lucky +// because they define it without a value, while Intel C++ defines it +// to 1. So we can check its value to see if the macro was defined natively +// or not. +// Under UNIX, the situation is exactly the same, but the macro _WCHAR_T +// is used instead. +# if ((_WCHAR_T_DEFINED + 0) == 0) && ((_WCHAR_T + 0) == 0) +# define BOOST_NO_INTRINSIC_WCHAR_T +# endif +#endif + +#if defined(__GNUC__) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +// +// Figure out when Intel is emulating this gcc bug +// (All Intel versions prior to 9.0.26, and versions +// later than that if they are set up to emulate gcc 3.2 +// or earlier): +// +# if ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 2)) || (BOOST_INTEL < 900) || (__INTEL_COMPILER_BUILD_DATE < 20050912) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# endif +#endif +#if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_WIN32) && (BOOST_INTEL_CXX_VERSION <= 1200)) || (BOOST_INTEL_CXX_VERSION <= 1200) +// GCC or VC emulation: +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif +// +// Verify that we have actually got BOOST_NO_INTRINSIC_WCHAR_T +// set correctly, if we don't do this now, we will get errors later +// in type_traits code among other things, getting this correct +// for the Intel compiler is actually remarkably fragile and tricky: +// +#ifdef __cplusplus +#if defined(BOOST_NO_INTRINSIC_WCHAR_T) +#include +template< typename T > struct assert_no_intrinsic_wchar_t; +template<> struct assert_no_intrinsic_wchar_t { typedef void type; }; +// if you see an error here then you need to unset BOOST_NO_INTRINSIC_WCHAR_T +// where it is defined above: +typedef assert_no_intrinsic_wchar_t::type assert_no_intrinsic_wchar_t_; +#else +template< typename T > struct assert_intrinsic_wchar_t; +template<> struct assert_intrinsic_wchar_t {}; +// if you see an error here then define BOOST_NO_INTRINSIC_WCHAR_T on the command line: +template<> struct assert_intrinsic_wchar_t {}; +#endif +#endif + +#if defined(_MSC_VER) && (_MSC_VER+0 >= 1000) +# if _MSC_VER >= 1200 +# define BOOST_HAS_MS_INT64 +# endif +# define BOOST_NO_SWPRINTF +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#elif defined(_WIN32) +# define BOOST_DISABLE_WIN32 +#endif + +// I checked version 6.0 build 020312Z, it implements the NRVO. +// Correct this as you find out which version of the compiler +// implemented the NRVO first. (Daniel Frey) +#if (BOOST_INTEL_CXX_VERSION >= 600) +# define BOOST_HAS_NRVO +#endif + +// Branch prediction hints +// I'm not sure 8.0 was the first version to support these builtins, +// update the condition if the version is not accurate. (Andrey Semashev) +#if defined(__GNUC__) && BOOST_INTEL_CXX_VERSION >= 800 +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif + +// RTTI +// __RTTI is the EDG macro +// __INTEL_RTTI__ is the Intel macro +// __GXX_RTTI is the g++ macro +// _CPPRTTI is the MSVC++ macro +#if !defined(__RTTI) && !defined(__INTEL_RTTI__) && !defined(__GXX_RTTI) && !defined(_CPPRTTI) + +#if !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// in MS mode, static typeid works even when RTTI is off +#if !defined(_MSC_VER) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#endif + +// +// versions check: +// we don't support Intel prior to version 6.0: +#if BOOST_INTEL_CXX_VERSION < 600 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// Intel on MacOS requires +#if defined(__APPLE__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// Intel on Altix Itanium +#if defined(__itanium__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// +// An attempt to value-initialize a pointer-to-member may trigger an +// internal error on Intel <= 11.1 (last checked version), as was +// reported by John Maddock, Intel support issue 589832, May 2010. +// Moreover, according to test results from Huang-Vista-x86_32_intel, +// intel-vc9-win-11.1 may leave a non-POD array uninitialized, in some +// cases when it should be value-initialized. +// (Niels Dekker, LKEB, May 2010) +// Apparently Intel 12.1 (compiler version number 9999 !!) has the same issue (compiler regression). +#if defined(__INTEL_COMPILER) +# if (__INTEL_COMPILER <= 1110) || (__INTEL_COMPILER == 9999) || (defined(_WIN32) && (__INTEL_COMPILER < 1600)) +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif +#endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) +#endif + +// Type aliasing hint +#if defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1300) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +#endif + +// +// C++0x features +// For each feature we need to check both the Intel compiler version, +// and the version of MSVC or GCC that we are emulating. +// See http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler/ +// for a list of which features were implemented in which Intel releases. +// +#if defined(BOOST_INTEL_STDCXX0X) +// BOOST_NO_CXX11_CONSTEXPR: +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && !defined(_MSC_VER) +// Available in earlier Intel versions, but fail our tests: +# undef BOOST_NO_CXX11_CONSTEXPR +#endif +// BOOST_NO_CXX11_NULLPTR: +#if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_NULLPTR +#endif +// BOOST_NO_CXX11_TEMPLATE_ALIASES +#if (BOOST_INTEL_CXX_VERSION >= 1210) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +// BOOST_NO_CXX11_DECLTYPE +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_DECLTYPE +#endif + +// BOOST_NO_CXX11_DECLTYPE_N3276 +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +// BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +// BOOST_NO_CXX11_RVALUE_REFERENCES +#if (BOOST_INTEL_CXX_VERSION >= 1300) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +// This is available from earlier Intel versions, but breaks Filesystem and other libraries: +# undef BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +// BOOST_NO_CXX11_STATIC_ASSERT +#if (BOOST_INTEL_CXX_VERSION >= 1110) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40300)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_STATIC_ASSERT +#endif + +// BOOST_NO_CXX11_VARIADIC_TEMPLATES +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +// BOOST_NO_CXX11_VARIADIC_MACROS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40200)) && (!defined(_MSC_VER) || (_MSC_VER >= 1400)) +# undef BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +// BOOST_NO_CXX11_AUTO_DECLARATIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_AUTO_DECLARATIONS +#endif + +// BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// BOOST_NO_CXX11_CHAR16_T +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_CHAR16_T +#endif + +// BOOST_NO_CXX11_CHAR32_T +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_CHAR32_T +#endif + +// BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +// BOOST_NO_CXX11_DELETED_FUNCTIONS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +// BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +// BOOST_NO_CXX11_SCOPED_ENUMS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40501)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +// This is available but broken in earlier Intel releases. +# undef BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +// BOOST_NO_SFINAE_EXPR +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_SFINAE_EXPR +#endif + +// BOOST_NO_CXX11_SFINAE_EXPR +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && !defined(_MSC_VER) +# undef BOOST_NO_CXX11_SFINAE_EXPR +#endif + +// BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +// This is available in earlier Intel releases, but breaks Multiprecision: +# undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +// BOOST_NO_CXX11_LAMBDAS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 1600)) +# undef BOOST_NO_CXX11_LAMBDAS +#endif + +// BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) +# undef BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +// BOOST_NO_CXX11_RANGE_BASED_FOR +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +// BOOST_NO_CXX11_RAW_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_RAW_LITERALS +#endif + +// BOOST_NO_CXX11_UNICODE_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40500)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +// BOOST_NO_CXX11_NOEXCEPT +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +// Available in earlier Intel release, but generates errors when used with +// conditional exception specifications, for example in multiprecision: +# undef BOOST_NO_CXX11_NOEXCEPT +#endif + +// BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40600)) && (!defined(_MSC_VER) || (_MSC_VER >= 9999)) +# undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +// BOOST_NO_CXX11_USER_DEFINED_LITERALS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +// BOOST_NO_CXX11_ALIGNAS +#if (BOOST_INTEL_CXX_VERSION >= 1500) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_ALIGNAS +# undef BOOST_NO_CXX11_ALIGNOF +#endif + +// BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#if (BOOST_INTEL_CXX_VERSION >= 1200) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 180020827)) +# undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +// BOOST_NO_CXX11_INLINE_NAMESPACES +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40400)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +// BOOST_NO_CXX11_REF_QUALIFIERS +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40800)) && (!defined(_MSC_VER) || (_MSC_FULL_VER >= 190021730)) +# undef BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +// BOOST_NO_CXX11_FINAL +// BOOST_NO_CXX11_OVERRIDE +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 40700)) && (!defined(_MSC_VER) || (_MSC_VER >= 1700)) +# undef BOOST_NO_CXX11_FINAL +# undef BOOST_NO_CXX11_OVERRIDE +#endif + +// BOOST_NO_CXX11_UNRESTRICTED_UNION +#if (BOOST_INTEL_CXX_VERSION >= 1400) && (!defined(BOOST_INTEL_GCC_VERSION) || (BOOST_INTEL_GCC_VERSION >= 50100)) && (!defined(_MSC_VER)) +# undef BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +#endif // defined(BOOST_INTEL_STDCXX0X) + +// +// Broken in all versions up to 15: +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION <= 1310) +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION == 1400) +// A regression in Intel's compiler means that seems to be broken in this release as well as : +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +#if (BOOST_INTEL_CXX_VERSION < 1200) +// +// fenv.h appears not to work with Intel prior to 12.0: +// +# define BOOST_NO_FENV_H +#endif + +// Intel 13.10 fails to access defaulted functions of a base class declared in private or protected sections, +// producing the following errors: +// error #453: protected function "..." (declared at ...") is not accessible through a "..." pointer or object +#if (BOOST_INTEL_CXX_VERSION <= 1310) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +# define BOOST_HAS_STDINT_H +#endif + +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__LP64__) && defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1310) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_INT128 +#endif + +#endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500) && (defined(_MSC_VER) || defined(__GNUC__)) +// +// last known and checked version: +#if (BOOST_INTEL_CXX_VERSION > 1700) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your compiler - please check for an updated Boost release." +# elif defined(_MSC_VER) +// +// We don't emit this warning any more, since we have so few +// defect macros set anyway (just the one). +// +//# pragma message("boost: Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + diff --git a/src/boost/config/compiler/kai.hpp b/src/boost/config/compiler/kai.hpp new file mode 100644 index 00000000..0b22ec1d --- /dev/null +++ b/src/boost/config/compiler/kai.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are 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 most recent version. + +// Kai C++ compiler setup: + +#include + +# if (__KCC_VERSION <= 4001) || !defined(BOOST_STRICT_CONFIG) + // at least on Sun, the contents of is not in namespace std +# define BOOST_NO_STDC_NAMESPACE +# endif + +// see also common_edg.hpp which needs a special check for __KCC +# if !defined(_EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +// +// last known and checked version is 4001: +#if (__KCC_VERSION > 4001) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + diff --git a/src/boost/config/compiler/metrowerks.hpp b/src/boost/config/compiler/metrowerks.hpp new file mode 100644 index 00000000..c38efb32 --- /dev/null +++ b/src/boost/config/compiler/metrowerks.hpp @@ -0,0 +1,201 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Stefan Slapeta 2004. +// Use, modification and distribution are 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 most recent version. + +// Metrowerks C++ compiler setup: + +// locale support is disabled when linking with the dynamic runtime +# ifdef _MSL_NO_LOCALE +# define BOOST_NO_STD_LOCALE +# endif + +# if __MWERKS__ <= 0x2301 // 5.3 +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_NO_POINTER_TO_MEMBER_CONST +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# endif + +# if __MWERKS__ <= 0x2401 // 6.2 +//# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if(__MWERKS__ <= 0x2407) // 7.x +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# endif + +# if(__MWERKS__ <= 0x3003) // 8.x +# define BOOST_NO_SFINAE +# endif + +// the "|| !defined(BOOST_STRICT_CONFIG)" part should apply to the last +// tested version *only*: +# if(__MWERKS__ <= 0x3207) || !defined(BOOST_STRICT_CONFIG) // 9.6 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_IS_ABSTRACT +# endif + +#if !__option(wchar_type) +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +#if !__option(exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if (__INTEL__ && _WIN32) || (__POWERPC__ && macintosh) +# if __MWERKS__ == 0x3000 +# define BOOST_COMPILER_VERSION 8.0 +# elif __MWERKS__ == 0x3001 +# define BOOST_COMPILER_VERSION 8.1 +# elif __MWERKS__ == 0x3002 +# define BOOST_COMPILER_VERSION 8.2 +# elif __MWERKS__ == 0x3003 +# define BOOST_COMPILER_VERSION 8.3 +# elif __MWERKS__ == 0x3200 +# define BOOST_COMPILER_VERSION 9.0 +# elif __MWERKS__ == 0x3201 +# define BOOST_COMPILER_VERSION 9.1 +# elif __MWERKS__ == 0x3202 +# define BOOST_COMPILER_VERSION 9.2 +# elif __MWERKS__ == 0x3204 +# define BOOST_COMPILER_VERSION 9.3 +# elif __MWERKS__ == 0x3205 +# define BOOST_COMPILER_VERSION 9.4 +# elif __MWERKS__ == 0x3206 +# define BOOST_COMPILER_VERSION 9.5 +# elif __MWERKS__ == 0x3207 +# define BOOST_COMPILER_VERSION 9.6 +# else +# define BOOST_COMPILER_VERSION __MWERKS__ +# endif +#else +# define BOOST_COMPILER_VERSION __MWERKS__ +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if __MWERKS__ > 0x3206 && __option(rvalue_refs) +# define BOOST_HAS_RVALUE_REFS +#else +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// versions check: +// we don't support Metrowerks prior to version 5.3: +#if __MWERKS__ < 0x2301 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (__MWERKS__ > 0x3205) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + + + + diff --git a/src/boost/config/compiler/mpw.hpp b/src/boost/config/compiler/mpw.hpp new file mode 100644 index 00000000..3adb6122 --- /dev/null +++ b/src/boost/config/compiler/mpw.hpp @@ -0,0 +1,143 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are 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 most recent version. + +// MPW C++ compilers setup: + +# if defined(__SC__) +# define BOOST_COMPILER "MPW SCpp version " BOOST_STRINGIZE(__SC__) +# elif defined(__MRC__) +# define BOOST_COMPILER "MPW MrCpp version " BOOST_STRINGIZE(__MRC__) +# else +# error "Using MPW compiler configuration by mistake. Please update." +# endif + +// +// MPW 8.90: +// +#if (MPW_CPLUS <= 0x890) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define BOOST_NO_USING_TEMPLATE + +# define BOOST_NO_CWCHAR +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + +# define BOOST_NO_STD_ALLOCATOR /* actually a bug with const reference overloading */ + +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +// +// versions check: +// we don't support MPW prior to version 8.9: +#if MPW_CPLUS < 0x890 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x890: +#if (MPW_CPLUS > 0x890) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/src/boost/config/compiler/nvcc.hpp b/src/boost/config/compiler/nvcc.hpp new file mode 100644 index 00000000..147f75db --- /dev/null +++ b/src/boost/config/compiler/nvcc.hpp @@ -0,0 +1,64 @@ +// (C) Copyright Eric Jourdanneau, Joel Falcou 2010 +// Use, modification and distribution are 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 most recent version. + +// NVIDIA CUDA C++ compiler setup + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "NVIDIA CUDA C++ Compiler" +#endif + +#if defined(__CUDACC_VER_MAJOR__) && defined(__CUDACC_VER_MINOR__) && defined(__CUDACC_VER_BUILD__) +# define BOOST_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__) +#else +// We don't really know what the CUDA version is, but it's definitely before 7.5: +# define BOOST_CUDA_VERSION 7000000 +#endif + +// NVIDIA Specific support +// BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device +#define BOOST_GPU_ENABLED __host__ __device__ + +#if !defined(__clang__) || defined(__NVCC__) +// A bug in version 7.0 of CUDA prevents use of variadic templates in some occasions +// https://svn.boost.org/trac/boost/ticket/11897 +// This is fixed in 7.5. As the following version macro was introduced in 7.5 an existance +// check is enough to detect versions < 7.5 +#if BOOST_CUDA_VERSION < 7050000 +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +// The same bug is back again in 8.0: +#if (BOOST_CUDA_VERSION > 8000000) && (BOOST_CUDA_VERSION < 8010000) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +// CUDA (8.0) has no constexpr support in msvc mode: +#if defined(_MSC_VER) && (BOOST_CUDA_VERSION < 9000000) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#endif + +#ifdef __CUDACC__ +// +// When compiing .cu files, there's a bunch of stuff that doesn't work with msvc: +// +#if defined(_MSC_VER) +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif +// +// And this one effects the NVCC front end, +// See https://svn.boost.org/trac/boost/ticket/13049 +// +#if (BOOST_CUDA_VERSION >= 8000000) && (BOOST_CUDA_VERSION < 8010000) +# define BOOST_NO_CXX11_NOEXCEPT +#endif + +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#endif diff --git a/src/boost/config/compiler/pathscale.hpp b/src/boost/config/compiler/pathscale.hpp new file mode 100644 index 00000000..59ab9b00 --- /dev/null +++ b/src/boost/config/compiler/pathscale.hpp @@ -0,0 +1,141 @@ +// (C) Copyright Bryce Lelbach 2011 + +// Use, modification and distribution are 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 most recent version. + +// PathScale EKOPath C++ Compiler + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "PathScale EKOPath C++ Compiler version " __PATHSCALE__ +#endif + +#if __PATHCC__ >= 6 +// PathCC is based on clang, and supports the __has_*() builtins used +// to detect features in clang.hpp. Since the clang toolset is much +// better maintained, it is more convenient to reuse its definitions. +# include "boost/config/compiler/clang.hpp" +#elif __PATHCC__ >= 4 +# define BOOST_MSVC6_MEMBER_TEMPLATES +# define BOOST_HAS_UNISTD_H +# define BOOST_HAS_STDINT_H +# define BOOST_HAS_SIGACTION +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREAD_YIELD +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# define BOOST_HAS_NRVO +# define BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NANOSLEEP +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_LOG1P +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_EXPM1 +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_CLOCK_GETTIME +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_SFINAE_EXPR +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_ALIGNOF +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_OVERRIDE +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif +#endif diff --git a/src/boost/config/compiler/pgi.hpp b/src/boost/config/compiler/pgi.hpp new file mode 100644 index 00000000..4e909d8a --- /dev/null +++ b/src/boost/config/compiler/pgi.hpp @@ -0,0 +1,23 @@ +// (C) Copyright Noel Belcourt 2007. +// Copyright 2017, NVIDIA CORPORATION. +// Use, modification and distribution are 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 most recent version. + +// PGI C++ compiler setup: + +#define BOOST_COMPILER_VERSION __PGIC__##__PGIC_MINOR__ +#define BOOST_COMPILER "PGI compiler version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// PGI is mostly GNU compatible. So start with that. +#include + +// Now adjust for things that are different. + +// __float128 is a typedef, not a distinct type. +#undef BOOST_HAS_FLOAT128 + +// __int128 is not supported. +#undef BOOST_HAS_INT128 diff --git a/src/boost/config/compiler/sgi_mipspro.hpp b/src/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 00000000..54433c99 --- /dev/null +++ b/src/boost/config/compiler/sgi_mipspro.hpp @@ -0,0 +1,29 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are 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 most recent version. + +// SGI C++ compiler setup: + +#define BOOST_COMPILER "SGI Irix compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) + +#include + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// +#define BOOST_HAS_THREADS +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +#undef BOOST_NO_SWPRINTF +#undef BOOST_DEDUCED_TYPENAME + +// +// version check: +// probably nothing to do here? + + diff --git a/src/boost/config/compiler/sunpro_cc.hpp b/src/boost/config/compiler/sunpro_cc.hpp new file mode 100644 index 00000000..334b604b --- /dev/null +++ b/src/boost/config/compiler/sunpro_cc.hpp @@ -0,0 +1,225 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Peter Dimov 2002. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright David Abrahams 2002. +// Use, modification and distribution are 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 most recent version. + +// Sun C++ compiler setup: + +# if __SUNPRO_CC <= 0x500 +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if (__SUNPRO_CC <= 0x520) + // + // Sunpro 5.2 and earler: + // + // although sunpro 5.2 supports the syntax for + // inline initialization it often gets the value + // wrong, especially where the value is computed + // from other constants (J Maddock 6th May 2001) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // Although sunpro 5.2 supports the syntax for + // partial specialization, it often seems to + // bind to the wrong specialization. Better + // to disable it until suppport becomes more stable + // (J Maddock 6th May 2001). +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# endif + +# if (__SUNPRO_CC <= 0x530) + // Requesting debug info (-g) with Boost.Python results + // in an internal compiler error for "static const" + // initialized in-class. + // >> Assertion: (../links/dbg_cstabs.cc, line 611) + // while processing ../test.cpp at line 0. + // (Jens Maurer according to Gottfried Ganssauge 04 Mar 2002) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // SunPro 5.3 has better support for partial specialization, + // but breaks when compiling std::less > + // (Jens Maurer 4 Nov 2001). + + // std::less specialization fixed as reported by George + // Heintzelman; partial specialization re-enabled + // (Peter Dimov 17 Jan 2002) + +//# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // integral constant expressions with 64 bit numbers fail +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +# if (__SUNPRO_CC < 0x570) +# define BOOST_NO_TEMPLATE_TEMPLATES + // see http://lists.boost.org/MailArchives/boost/msg47184.php + // and http://lists.boost.org/MailArchives/boost/msg47220.php +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_SFINAE +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif +# if (__SUNPRO_CC <= 0x580) +# define BOOST_NO_IS_ABSTRACT +# endif + +# if (__SUNPRO_CC <= 0x5100) + // Sun 5.10 may not correctly value-initialize objects of + // some user defined types, as was reported in April 2010 + // (CR 6947016), and confirmed by Steve Clamage. + // (Niels Dekker, LKEB, May 2010). +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +# endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __SUNPRO_CC > 0x500 +# define BOOST_SYMBOL_EXPORT __global +# define BOOST_SYMBOL_IMPORT __global +# define BOOST_SYMBOL_VISIBLE __global +#endif + +// Deprecated symbol markup +// Oracle Studio 12.4 supports deprecated attribute with a message; this is the first release that supports the attribute. +#if (__SUNPRO_CC >= 0x5130) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + +#if (__SUNPRO_CC < 0x5130) +// C++03 features in 12.4: +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_ADL_BARRIER +#define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#if (__SUNPRO_CC < 0x5130) || (__cplusplus < 201100) +// C++11 only featuires in 12.4: +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_CXX11_EXTERN_TEMPLATE +#define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RVALUE_REFERENCES +#define BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +#if (__SUNPRO_CC < 0x5140) || (__cplusplus < 201103) +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// +// C++0x features +// +# define BOOST_HAS_LONG_LONG + +#define BOOST_NO_CXX11_SFINAE_EXPR + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) || (__cplusplus < 201402L) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +// Turn on threading support for Solaris 12. +// Ticket #11972 +#if (__SUNPRO_CC >= 0x5140) && defined(__SunOS_5_12) && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Version +// + +#define BOOST_COMPILER "Sun compiler version " BOOST_STRINGIZE(__SUNPRO_CC) + +// +// versions check: +// we don't support sunpro prior to version 4: +#if __SUNPRO_CC < 0x400 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (__SUNPRO_CC > 0x5150) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your compiler - please check for an updated Boost release." +# endif +#endif diff --git a/src/boost/config/compiler/vacpp.hpp b/src/boost/config/compiler/vacpp.hpp new file mode 100644 index 00000000..3794d360 --- /dev/null +++ b/src/boost/config/compiler/vacpp.hpp @@ -0,0 +1,189 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Toon Knapen 2001 - 2003. +// (C) Copyright Lie-Quan Lee 2001. +// (C) Copyright Markus Schoepflin 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are 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 most recent version. + +// Visual Age (IBM) C++ compiler setup: + +#if __IBMCPP__ <= 501 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +#if (__IBMCPP__ <= 502) +// Actually the compiler supports inclass member initialization but it +// requires a definition for the class member and it doesn't recognize +// it as an integral constant expression when used as a template argument. +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +#if (__IBMCPP__ <= 600) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +#if (__IBMCPP__ <= 1110) +// XL C++ V11.1 and earlier versions may not always value-initialize +// a temporary object T(), when T is a non-POD aggregate class type. +// Michael Wong (IBM Canada Ltd) has confirmed this issue and gave it +// high priority. -- Niels Dekker (LKEB), May 2010. +# define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +// +// On AIX thread support seems to be indicated by _THREAD_SAFE: +// +#ifdef _THREAD_SAFE +# define BOOST_HAS_THREADS +#endif + +#define BOOST_COMPILER "IBM Visual Age version " BOOST_STRINGIZE(__IBMCPP__) + +// +// versions check: +// we don't support Visual age prior to version 5: +#if __IBMCPP__ < 500 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 1210: +#if (__IBMCPP__ > 1210) +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + +// Some versions of the compiler have issues with default arguments on partial specializations +#if __IBMCPP__ <= 1010 +#define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +#endif + +// Type aliasing hint. Supported since XL C++ 13.1 +#if (__IBMCPP__ >= 1310) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if ! __IBMCPP_AUTO_TYPEDEDUCTION +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif +#if ! __IBMCPP_UTF_LITERAL__ +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif +#if ! __IBMCPP_CONSTEXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif +#if ! __IBMCPP_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE +#else +# define BOOST_HAS_DECLTYPE +#endif +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#define BOOST_NO_CXX11_DELETED_FUNCTIONS +#if ! __IBMCPP_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif +#if ! __IBMCPP_EXTERN_TEMPLATE +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if ! __IBMCPP_VARIADIC_TEMPLATES +// not enabled separately at this time +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#if ! __IBMCPP_RVALUE_REFERENCES +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif +#if ! __IBMCPP_SCOPED_ENUM +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#if ! __IBMCPP_STATIC_ASSERT +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_UNICODE_LITERALS +#if ! __IBMCPP_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif +#if ! __C99_MACRO_WITH_VA_ARGS +# define BOOST_NO_CXX11_VARIADIC_MACROS +#endif +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_UNRESTRICTED_UNION + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if !defined(__cpp_decltype_auto) || (__cpp_decltype_auto < 201304) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif +#if (__cplusplus < 201304) // There's no SD6 check for this.... +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif +#if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif +#if !defined(__cpp_init_captures) || (__cpp_init_captures < 201304) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif +#if !defined(__cpp_return_type_deduction) || (__cpp_return_type_deduction < 201304) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif +#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif diff --git a/src/boost/config/compiler/visualc.hpp b/src/boost/config/compiler/visualc.hpp new file mode 100644 index 00000000..ce0fc15e --- /dev/null +++ b/src/boost/config/compiler/visualc.hpp @@ -0,0 +1,398 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are 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 most recent version. +// +// Microsoft Visual C++ compiler setup: +// +// We need to be careful with the checks in this file, as contrary +// to popular belief there are versions with _MSC_VER with the final +// digit non-zero (mainly the MIPS cross compiler). +// +// So we either test _MSC_VER >= XXXX or else _MSC_VER < XXXX. +// No other comparisons (==, >, or <=) are safe. +// + +#define BOOST_MSVC _MSC_VER + +// +// Helper macro BOOST_MSVC_FULL_VER for use in Boost code: +// +#if _MSC_FULL_VER > 100000000 +# define BOOST_MSVC_FULL_VER _MSC_FULL_VER +#else +# define BOOST_MSVC_FULL_VER (_MSC_FULL_VER * 10) +#endif + +// Attempt to suppress VC6 warnings about the length of decorated names (obsolete): +#pragma warning( disable : 4503 ) // warning: decorated name length exceeded + +#define BOOST_HAS_PRAGMA_ONCE + +// +// versions check: +// we don't support Visual C++ prior to version 7.1: +#if _MSC_VER < 1310 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// VS2005 (VC8) docs: __assume has been in Visual C++ for multiple releases +#define BOOST_UNREACHABLE_RETURN(x) __assume(0); + +#if _MSC_FULL_VER < 180020827 +# define BOOST_NO_FENV_H +#endif + +#if _MSC_VER < 1400 +// although a conforming signature for swprint exists in VC7.1 +// it appears not to actually work: +# define BOOST_NO_SWPRINTF +// Our extern template tests also fail for this compiler: +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +// Variadic macros do not exist for VC7.1 and lower +# define BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if _MSC_VER < 1500 // 140X == VC++ 8.0 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +#if _MSC_VER < 1600 // 150X == VC++ 9.0 + // A bug in VC9: +# define BOOST_NO_ADL_BARRIER +#endif + + +#ifndef _NATIVE_WCHAR_T_DEFINED +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// check for exception handling support: +#if !defined(_CPPUNWIND) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +// +// __int64 support: +// +#define BOOST_HAS_MS_INT64 +#if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400) +# define BOOST_HAS_LONG_LONG +#else +# define BOOST_NO_LONG_LONG +#endif +#if (_MSC_VER >= 1400) && !defined(_DEBUG) +# define BOOST_HAS_NRVO +#endif +#if _MSC_VER >= 1600 // 160X == VC++ 10.0 +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif +// +// disable Win32 API's if compiler extensions are +// turned off: +// +#if !defined(_MSC_EXTENSIONS) && !defined(BOOST_DISABLE_WIN32) +# define BOOST_DISABLE_WIN32 +#endif +#if !defined(_CPPRTTI) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// Deprecated symbol markup +#if (_MSC_VER >= 1400) +#define BOOST_DEPRECATED(msg) __declspec(deprecated(msg)) +#else +// MSVC 7.1 only supports the attribute without a message +#define BOOST_DEPRECATED(msg) __declspec(deprecated) +#endif + +// +// TR1 features: +// +#if (_MSC_VER >= 1700) && defined(_HAS_CXX17) && (_HAS_CXX17 > 0) +// # define BOOST_HAS_TR1_HASH // don't know if this is true yet. +// # define BOOST_HAS_TR1_TYPE_TRAITS // don't know if this is true yet. +# define BOOST_HAS_TR1_UNORDERED_MAP +# define BOOST_HAS_TR1_UNORDERED_SET +#endif + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG + +// C++ features supported by VC++ 10 (aka 2010) +// +#if _MSC_VER < 1600 +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +# define BOOST_NO_CXX11_NULLPTR +# define BOOST_NO_CXX11_DECLTYPE +#endif // _MSC_VER < 1600 + +#if _MSC_VER >= 1600 +# define BOOST_HAS_STDINT_H +#endif + +// C++11 features supported by VC++ 11 (aka 2012) +// +#if _MSC_VER < 1700 +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_RANGE_BASED_FOR +# define BOOST_NO_CXX11_SCOPED_ENUMS +# define BOOST_NO_CXX11_OVERRIDE +#endif // _MSC_VER < 1700 + +// C++11 features supported by VC++ 12 (aka 2013). +// +#if _MSC_FULL_VER < 180020827 +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if _MSC_FULL_VER >= 180020827 +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// C++11 features supported by VC++ 14 (aka 2015) +// +#if (_MSC_FULL_VER < 190023026) +# define BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NO_CXX11_DEFAULTED_MOVES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_ALIGNAS +# define BOOST_NO_CXX11_ALIGNOF +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_UNICODE_LITERALS +# define BOOST_NO_CXX14_DECLTYPE_AUTO +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# define BOOST_NO_CXX14_BINARY_LITERALS +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif +// C++11 features supported by VC++ 14 update 3 (aka 2015) +// +#if (_MSC_FULL_VER < 190024210) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +# define BOOST_NO_SFINAE_EXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +// C++14 features supported by VC++ 14.1 (Visual Studio 2017) +// +#if (_MSC_VER < 1910) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif + +// C++17 features supported by VC++ 14.1 (Visual Studio 2017) Update 3 +// +#if (_MSC_VER < 1911) || (_MSVC_LANG < 201703) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +# define BOOST_NO_CXX17_IF_CONSTEXPR +// Let the defaults handle these now: +//# define BOOST_NO_CXX17_HDR_OPTIONAL +//# define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif + +// MSVC including version 14 has not yet completely +// implemented value-initialization, as is reported: +// "VC++ does not value-initialize members of derived classes without +// user-declared constructor", reported in 2009 by Sylvester Hesp: +// https://connect.microsoft.com/VisualStudio/feedback/details/484295 +// "Presence of copy constructor breaks member class initialization", +// reported in 2009 by Alex Vakulenko: +// https://connect.microsoft.com/VisualStudio/feedback/details/499606 +// "Value-initialization in new-expression", reported in 2005 by +// Pavel Kuznetsov (MetaCommunications Engineering): +// https://connect.microsoft.com/VisualStudio/feedback/details/100744 +// Reported again by John Maddock in 2015 for VC14: +// https://connect.microsoft.com/VisualStudio/feedback/details/1582233/c-subobjects-still-not-value-initialized-correctly +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +// (Niels Dekker, LKEB, May 2010) +// Still present in VC15.5, Dec 2017. +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +// +// C++ 11: +// +// This is supported with /permissive- for 15.5 onwards, unfortunately we appear to have no way to tell +// if this is in effect or not, in any case nothing in Boost is currently using this, so we'll just go +// on defining it for now: +// +#if (_MSC_FULL_VER < 193030705) || (_MSVC_LANG < 202004) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#if (_MSC_VER < 1912) || (_MSVC_LANG < 201402) +// Supported from msvc-15.5 onwards: +#define BOOST_NO_CXX11_SFINAE_EXPR +#endif +#if (_MSC_VER < 1915) || (_MSVC_LANG < 201402) +// C++ 14: +// Still gives internal compiler error for msvc-15.5: +# define BOOST_NO_CXX14_CONSTEXPR +#endif +// C++ 17: +#if (_MSC_VER < 1912) || (_MSVC_LANG < 201703) +#define BOOST_NO_CXX17_INLINE_VARIABLES +#define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if (_MSC_VER < 1914) || (_MSVC_LANG < 201703) +#define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +// +// Things that don't work in clr mode: +// +#ifdef _M_CEE +#ifndef BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif +#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(_MSVC_LANG) +# define BOOST_NO_SFINAE_EXPR +#endif +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_REF_QUALIFIERS +#endif +#endif +#ifdef _M_CEE_PURE +#ifndef BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_CONSTEXPR +#endif +#endif + +// +// prefix and suffix headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/msvc_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/msvc_suffix.hpp" +#endif + +// +// Approximate compiler conformance version +// +#ifdef _MSVC_LANG +# define BOOST_CXX_VERSION _MSVC_LANG +#elif defined(_HAS_CXX17) +# define BOOST_CXX_VERSION 201703L +#elif BOOST_MSVC >= 1916 +# define BOOST_CXX_VERSION 201402L +#endif + +#if BOOST_CXX_VERSION >= 201703L +# define BOOST_ATTRIBUTE_UNUSED [[maybe_unused]] +#endif + +#ifndef BOOST_COMPILER +// TODO: +// these things are mostly bogus. 1200 means version 12.0 of the compiler. The +// artificial versions assigned to them only refer to the versions of some IDE +// these compilers have been shipped with, and even that is not all of it. Some +// were shipped with freely downloadable SDKs, others as crosscompilers in eVC. +// IOW, you can't use these 'versions' in any sensible way. Sorry. +# if defined(UNDER_CE) +# if _MSC_VER < 1400 + // Note: I'm not aware of any CE compiler with version 13xx +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("boost: Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# elif _MSC_VER < 1500 +# define BOOST_COMPILER_VERSION evc8 +# elif _MSC_VER < 1600 +# define BOOST_COMPILER_VERSION evc9 +# elif _MSC_VER < 1700 +# define BOOST_COMPILER_VERSION evc10 +# elif _MSC_VER < 1800 +# define BOOST_COMPILER_VERSION evc11 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION evc12 +# elif _MSC_VER < 2000 +# define BOOST_COMPILER_VERSION evc14 +# else +# if defined(BOOST_ASSERT_CONFIG) +# error "boost: Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("boost: Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# endif +# else +# if _MSC_VER < 1200 + // Note: Versions up to 10.0 aren't supported. +# define BOOST_COMPILER_VERSION 5.0 +# elif _MSC_VER < 1300 +# define BOOST_COMPILER_VERSION 6.0 +# elif _MSC_VER < 1310 +# define BOOST_COMPILER_VERSION 7.0 +# elif _MSC_VER < 1400 +# define BOOST_COMPILER_VERSION 7.1 +# elif _MSC_VER < 1500 +# define BOOST_COMPILER_VERSION 8.0 +# elif _MSC_VER < 1600 +# define BOOST_COMPILER_VERSION 9.0 +# elif _MSC_VER < 1700 +# define BOOST_COMPILER_VERSION 10.0 +# elif _MSC_VER < 1800 +# define BOOST_COMPILER_VERSION 11.0 +# elif _MSC_VER < 1900 +# define BOOST_COMPILER_VERSION 12.0 +# elif _MSC_VER < 1910 +# define BOOST_COMPILER_VERSION 14.0 +# elif _MSC_VER < 1920 +# define BOOST_COMPILER_VERSION 14.1 +# elif _MSC_VER < 1930 +# define BOOST_COMPILER_VERSION 14.2 +# elif _MSC_VER < 1940 +# define BOOST_COMPILER_VERSION 14.3 +# else +# define BOOST_COMPILER_VERSION _MSC_VER +# endif +# endif + +# define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) +#endif + +#include + +// +// last known and checked version is 19.3x (VS2022): +#if (_MSC_VER >= 1940) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your current compiler version." +# elif !defined(BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE) + // + // Disabled as of March 2018 - the pace of VS releases is hard to keep up with + // and in any case, we have relatively few defect macros defined now. + // BOOST_PRAGMA_MESSAGE("Info: Boost.Config is older than your compiler version - probably nothing bad will happen - but you may wish to look for an updated Boost version. Define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE to suppress this message.") +# endif +#endif diff --git a/src/boost/config/compiler/xlcpp.hpp b/src/boost/config/compiler/xlcpp.hpp new file mode 100644 index 00000000..4a4477d9 --- /dev/null +++ b/src/boost/config/compiler/xlcpp.hpp @@ -0,0 +1,303 @@ +// (C) Copyright Douglas Gregor 2010 +// +// Use, modification and distribution are 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 most recent version. + +// compiler setup for IBM XL C/C++ for Linux (Little Endian) based on clang. + +#define BOOST_HAS_PRAGMA_ONCE + +// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used. +#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) +# define BOOST_HAS_PRAGMA_DETECT_MISMATCH +#endif + +// When compiling with clang before __has_extension was defined, +// even if one writes 'defined(__has_extension) && __has_extension(xxx)', +// clang reports a compiler error. So the only workaround found is: + +#ifndef __has_extension +#define __has_extension __has_feature +#endif + +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(x) 0 +#endif + +#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID) +# define BOOST_NO_TYPEID +#endif + +#if defined(__int64) && !defined(__GNUC__) +# define BOOST_HAS_MS_INT64 +#endif + +#define BOOST_HAS_NRVO + +// Branch prediction hints +#if defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) +#endif +#endif + +// Clang supports "long long" in all compilation modes. +#define BOOST_HAS_LONG_LONG + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32) +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#endif + +// +// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +// between switch labels. +// +#if __cplusplus >= 201103L && defined(__has_warning) +# if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +# define BOOST_FALLTHROUGH [[clang::fallthrough]] +# endif +#endif + +#if !__has_feature(cxx_auto_type) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#endif + +// +// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t +// +#if defined(_MSC_VER) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +#endif + +#if !__has_feature(cxx_constexpr) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#if !__has_feature(cxx_decltype) +# define BOOST_NO_CXX11_DECLTYPE +#endif + +#if !__has_feature(cxx_decltype_incomplete_return_types) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif + +#if !__has_feature(cxx_defaulted_functions) +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +#endif + +#if !__has_feature(cxx_deleted_functions) +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +#endif + +#if !__has_feature(cxx_explicit_conversions) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +#if !__has_feature(cxx_default_function_template_args) +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#endif + +#if !__has_feature(cxx_lambdas) +# define BOOST_NO_CXX11_LAMBDAS +#endif + +#if !__has_feature(cxx_local_type_template_args) +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif + +#if !__has_feature(cxx_noexcept) +# define BOOST_NO_CXX11_NOEXCEPT +#endif + +#if !__has_feature(cxx_nullptr) +# define BOOST_NO_CXX11_NULLPTR +#endif + +#if !__has_feature(cxx_range_for) +# define BOOST_NO_CXX11_RANGE_BASED_FOR +#endif + +#if !__has_feature(cxx_raw_string_literals) +# define BOOST_NO_CXX11_RAW_LITERALS +#endif + +#if !__has_feature(cxx_reference_qualified_functions) +# define BOOST_NO_CXX11_REF_QUALIFIERS +#endif + +#if !__has_feature(cxx_generalized_initializers) +# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +#if !__has_feature(cxx_rvalue_references) +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +#if !__has_feature(cxx_strong_enums) +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#if !__has_feature(cxx_static_assert) +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +#if !__has_feature(cxx_alias_templates) +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +#endif + +#if !__has_feature(cxx_unicode_literals) +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +#if !__has_feature(cxx_variadic_templates) +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if !__has_feature(cxx_user_literals) +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#endif + +#if !__has_feature(cxx_alignas) +# define BOOST_NO_CXX11_ALIGNAS +#endif + +#if !__has_feature(cxx_alignof) +# define BOOST_NO_CXX11_ALIGNOF +#endif + +#if !__has_feature(cxx_trailing_return) +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !__has_feature(cxx_inline_namespaces) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +#if !__has_feature(cxx_override_control) +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_OVERRIDE +#endif + +#if !__has_feature(cxx_unrestricted_unions) +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +#if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__)) +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +#if !__has_feature(__cxx_decltype_auto__) +# define BOOST_NO_CXX14_DECLTYPE_AUTO +#endif + +#if !__has_feature(__cxx_aggregate_nsdmi__) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif + +#if !__has_feature(__cxx_init_captures__) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#endif + +#if !__has_feature(__cxx_generic_lambdas__) +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +#endif + +// clang < 3.5 has a defect with dependent type, like following. +// +// template +// constexpr typename enable_if >::type foo(T &) +// { } // error: no return statement in constexpr function +// +// This issue also affects C++11 mode, but C++11 constexpr requires return stmt. +// Therefore we don't care such case. +// +// Note that we can't check Clang version directly as the numbering system changes depending who's +// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873) +// so instead verify that we have a feature that was introduced at the same time as working C++14 +// constexpr (generic lambda's in this case): +// +#if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__) +# define BOOST_NO_CXX14_CONSTEXPR +#endif + +#if !__has_feature(__cxx_return_type_deduction__) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#endif + +#if !__has_feature(__cxx_variable_templates__) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif + +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +// Clang 3.9+ in c++1z +#if !__has_cpp_attribute(fallthrough) || __cplusplus < 201406L +# define BOOST_NO_CXX17_INLINE_VARIABLES +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif + +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + +#if !__has_feature(cxx_thread_local) +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if __cplusplus < 201400 +// All versions with __cplusplus above this value seem to support this: +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +#endif + +// Deprecated symbol markup +#if __has_attribute(deprecated) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + +// Unused attribute: +#if defined(__GNUC__) && (__GNUC__ >= 4) +# define BOOST_ATTRIBUTE_UNUSED __attribute__((unused)) +#endif + +// Type aliasing hint. +#if __has_attribute(__may_alias__) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "Clang version " __clang_version__ +#endif + +// Macro used to identify the Clang compiler. +#define BOOST_CLANG 1 + +#define BOOST_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) diff --git a/src/boost/config/compiler/xlcpp_zos.hpp b/src/boost/config/compiler/xlcpp_zos.hpp new file mode 100644 index 00000000..0b288a88 --- /dev/null +++ b/src/boost/config/compiler/xlcpp_zos.hpp @@ -0,0 +1,174 @@ +// Copyright (c) 2017 Dynatrace +// +// 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 + +// See http://www.boost.org for most recent version. + +// Compiler setup for IBM z/OS XL C/C++ compiler. + +// Oldest compiler version currently supported is 2.1 (V2R1) +#if !defined(__IBMCPP__) || !defined(__COMPILER_VER__) || __COMPILER_VER__ < 0x42010000 +# error "Compiler not supported or configured - please reconfigure" +#endif + +#if __COMPILER_VER__ > 0x42010000 +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + +#define BOOST_COMPILER "IBM z/OS XL C/C++ version " BOOST_STRINGIZE(__COMPILER_VER__) +#define BOOST_XLCPP_ZOS __COMPILER_VER__ + +// ------------------------------------- + +#include // For __UU, __C99, __TR1, ... + +#if !defined(__IBMCPP_DEFAULTED_AND_DELETED_FUNCTIONS) +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// ------------------------------------- + +#if defined(__UU) || defined(__C99) || defined(__TR1) +# define BOOST_HAS_LOG1P +# define BOOST_HAS_EXPM1 +#endif + +#if defined(__C99) || defined(__TR1) +# define BOOST_HAS_STDINT_H +#else +# define BOOST_NO_FENV_H +#endif + +// ------------------------------------- + +#define BOOST_HAS_NRVO + +#if !defined(__RTTI_ALL__) +# define BOOST_NO_RTTI +#endif + +#if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + +#if defined(_LONG_LONG) || defined(__IBMCPP_C99_LONG_LONG) || defined(__LL) +# define BOOST_HAS_LONG_LONG +#else +# define BOOST_NO_LONG_LONG +#endif + +#if defined(_LONG_LONG) || defined(__IBMCPP_C99_LONG_LONG) || defined(__LL) || defined(_LP64) +# define BOOST_HAS_MS_INT64 +#endif + +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_CXX11_SFINAE_EXPR + +#if defined(__IBMCPP_VARIADIC_TEMPLATES) +# define BOOST_HAS_VARIADIC_TMPL +#else +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif + +#if defined(__IBMCPP_STATIC_ASSERT) +# define BOOST_HAS_STATIC_ASSERT +#else +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +#if defined(__IBMCPP_RVALUE_REFERENCES) +# define BOOST_HAS_RVALUE_REFS +#else +# define BOOST_NO_CXX11_RVALUE_REFERENCES +#endif + +#if !defined(__IBMCPP_SCOPED_ENUM) +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#define BOOST_NO_CXX11_TEMPLATE_ALIASES +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS + +#if !defined(__IBMCPP_EXPLICIT_CONVERSION_OPERATORS) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#endif + +#if !defined(__IBMCPP_DECLTYPE) +# define BOOST_NO_CXX11_DECLTYPE +#else +# define BOOST_HAS_DECLTYPE +#endif +#define BOOST_NO_CXX11_DECLTYPE_N3276 + +#if !defined(__IBMCPP_INLINE_NAMESPACE) +# define BOOST_NO_CXX11_INLINE_NAMESPACES +#endif + +#if !defined(__IBMCPP_AUTO_TYPEDEDUCTION) +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +#endif + +#if !defined(__IBM_CHAR32_T__) +# define BOOST_NO_CXX11_CHAR32_T +#endif +#if !defined(__IBM_CHAR16_T__) +# define BOOST_NO_CXX11_CHAR16_T +#endif + +#if !defined(__IBMCPP_CONSTEXPR) +# define BOOST_NO_CXX11_CONSTEXPR +#endif + +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_CXX11_RAW_LITERALS +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_CXX11_THREAD_LOCAL +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_OVERRIDE +#define BOOST_NO_CXX11_ALIGNAS +#define BOOST_NO_CXX11_ALIGNOF +#define BOOST_NO_CXX11_UNRESTRICTED_UNION +#define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +#define BOOST_NO_CXX14_AGGREGATE_NSDMI +#define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +#define BOOST_NO_CXX14_GENERIC_LAMBDAS +#define BOOST_NO_CXX14_DIGIT_SEPARATORS +#define BOOST_NO_CXX14_DECLTYPE_AUTO +#define BOOST_NO_CXX14_CONSTEXPR +#define BOOST_NO_CXX14_BINARY_LITERALS +#define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#define BOOST_NO_CXX17_INLINE_VARIABLES +#define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#define BOOST_NO_CXX17_IF_CONSTEXPR +#define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS + +// ------------------------------------- + +#if defined(__IBM_ATTRIBUTES) +# define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) +# define BOOST_NOINLINE __attribute__ ((__noinline__)) +# define BOOST_MAY_ALIAS __attribute__((__may_alias__)) +// No BOOST_ALIGNMENT - explicit alignment support is broken (V2R1). +#endif + +extern "builtin" long __builtin_expect(long, long); + +#define BOOST_LIKELY(x) __builtin_expect((x) && true, 1) +#define BOOST_UNLIKELY(x) __builtin_expect((x) && true, 0) diff --git a/src/boost/config/detail/cxx_composite.hpp b/src/boost/config/detail/cxx_composite.hpp new file mode 100644 index 00000000..acd8e849 --- /dev/null +++ b/src/boost/config/detail/cxx_composite.hpp @@ -0,0 +1,218 @@ +// This file was automatically generated on Fri Oct 13 19:09:38 2023 +// by libs/config/tools/generate.cpp +// Copyright John Maddock 2002-21. +// Use, modification and distribution are 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/libs/config for the most recent version.// +// Revision $Id$ +// + +#if defined(BOOST_NO_ADL_BARRIER)\ + || defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)\ + || defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)\ + || defined(BOOST_NO_COMPLETE_VALUE_INITIALIZATION)\ + || defined(BOOST_NO_CTYPE_FUNCTIONS)\ + || defined(BOOST_NO_CV_SPECIALIZATIONS)\ + || defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)\ + || defined(BOOST_NO_CWCHAR)\ + || defined(BOOST_NO_CWCTYPE)\ + || defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS)\ + || defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS)\ + || defined(BOOST_NO_EXCEPTIONS)\ + || defined(BOOST_NO_EXCEPTION_STD_NAMESPACE)\ + || defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)\ + || defined(BOOST_NO_FENV_H)\ + || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)\ + || defined(BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS)\ + || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\ + || defined(BOOST_NO_INTEGRAL_INT64_T)\ + || defined(BOOST_NO_INTRINSIC_WCHAR_T)\ + || defined(BOOST_NO_IOSFWD)\ + || defined(BOOST_NO_IOSTREAM)\ + || defined(BOOST_NO_IS_ABSTRACT)\ + || defined(BOOST_NO_LIMITS)\ + || defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)\ + || defined(BOOST_NO_LONG_LONG)\ + || defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)\ + || defined(BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS)\ + || defined(BOOST_NO_MEMBER_TEMPLATES)\ + || defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)\ + || defined(BOOST_NO_MEMBER_TEMPLATE_KEYWORD)\ + || defined(BOOST_NO_NESTED_FRIENDSHIP)\ + || defined(BOOST_NO_OPERATORS_IN_NAMESPACE)\ + || defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS)\ + || defined(BOOST_NO_POINTER_TO_MEMBER_CONST)\ + || defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS)\ + || defined(BOOST_NO_PRIVATE_IN_AGGREGATE)\ + || defined(BOOST_NO_RESTRICT_REFERENCES)\ + || defined(BOOST_NO_RTTI)\ + || defined(BOOST_NO_SFINAE)\ + || defined(BOOST_NO_SFINAE_EXPR)\ + || defined(BOOST_NO_STDC_NAMESPACE)\ + || defined(BOOST_NO_STD_ALLOCATOR)\ + || defined(BOOST_NO_STD_DISTANCE)\ + || defined(BOOST_NO_STD_ITERATOR)\ + || defined(BOOST_NO_STD_ITERATOR_TRAITS)\ + || defined(BOOST_NO_STD_LOCALE)\ + || defined(BOOST_NO_STD_MESSAGES)\ + || defined(BOOST_NO_STD_MIN_MAX)\ + || defined(BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN)\ + || defined(BOOST_NO_STD_TYPEINFO)\ + || defined(BOOST_NO_STD_USE_FACET)\ + || defined(BOOST_NO_STD_WSTREAMBUF)\ + || defined(BOOST_NO_STD_WSTRING)\ + || defined(BOOST_NO_STRINGSTREAM)\ + || defined(BOOST_NO_TEMPLATED_IOSTREAMS)\ + || defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\ + || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)\ + || defined(BOOST_NO_TEMPLATE_TEMPLATES)\ + || defined(BOOST_NO_TWO_PHASE_NAME_LOOKUP)\ + || defined(BOOST_NO_TYPEID)\ + || defined(BOOST_NO_TYPENAME_WITH_CTOR)\ + || defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION)\ + || defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)\ + || defined(BOOST_NO_USING_TEMPLATE)\ + || defined(BOOST_NO_VOID_RETURNS) +# define BOOST_NO_CXX03 +#endif + +#if defined(BOOST_NO_CXX03)\ + || defined(BOOST_NO_CXX11_ADDRESSOF)\ + || defined(BOOST_NO_CXX11_ALIGNAS)\ + || defined(BOOST_NO_CXX11_ALIGNOF)\ + || defined(BOOST_NO_CXX11_ALLOCATOR)\ + || defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)\ + || defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS)\ + || defined(BOOST_NO_CXX11_CHAR16_T)\ + || defined(BOOST_NO_CXX11_CHAR32_T)\ + || defined(BOOST_NO_CXX11_CONSTEXPR)\ + || defined(BOOST_NO_CXX11_DECLTYPE)\ + || defined(BOOST_NO_CXX11_DECLTYPE_N3276)\ + || defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)\ + || defined(BOOST_NO_CXX11_DEFAULTED_MOVES)\ + || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)\ + || defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)\ + || defined(BOOST_NO_CXX11_EXTERN_TEMPLATE)\ + || defined(BOOST_NO_CXX11_FINAL)\ + || defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS)\ + || defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)\ + || defined(BOOST_NO_CXX11_HDR_ARRAY)\ + || defined(BOOST_NO_CXX11_HDR_ATOMIC)\ + || defined(BOOST_NO_CXX11_HDR_CHRONO)\ + || defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE)\ + || defined(BOOST_NO_CXX11_HDR_EXCEPTION)\ + || defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)\ + || defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)\ + || defined(BOOST_NO_CXX11_HDR_FUTURE)\ + || defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)\ + || defined(BOOST_NO_CXX11_HDR_MUTEX)\ + || defined(BOOST_NO_CXX11_HDR_RANDOM)\ + || defined(BOOST_NO_CXX11_HDR_RATIO)\ + || defined(BOOST_NO_CXX11_HDR_REGEX)\ + || defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)\ + || defined(BOOST_NO_CXX11_HDR_THREAD)\ + || defined(BOOST_NO_CXX11_HDR_TUPLE)\ + || defined(BOOST_NO_CXX11_HDR_TYPEINDEX)\ + || defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)\ + || defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)\ + || defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)\ + || defined(BOOST_NO_CXX11_INLINE_NAMESPACES)\ + || defined(BOOST_NO_CXX11_LAMBDAS)\ + || defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS)\ + || defined(BOOST_NO_CXX11_NOEXCEPT)\ + || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)\ + || defined(BOOST_NO_CXX11_NULLPTR)\ + || defined(BOOST_NO_CXX11_NUMERIC_LIMITS)\ + || defined(BOOST_NO_CXX11_OVERRIDE)\ + || defined(BOOST_NO_CXX11_POINTER_TRAITS)\ + || defined(BOOST_NO_CXX11_RANGE_BASED_FOR)\ + || defined(BOOST_NO_CXX11_RAW_LITERALS)\ + || defined(BOOST_NO_CXX11_REF_QUALIFIERS)\ + || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)\ + || defined(BOOST_NO_CXX11_SCOPED_ENUMS)\ + || defined(BOOST_NO_CXX11_SFINAE_EXPR)\ + || defined(BOOST_NO_CXX11_SMART_PTR)\ + || defined(BOOST_NO_CXX11_STATIC_ASSERT)\ + || defined(BOOST_NO_CXX11_STD_ALIGN)\ + || defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)\ + || defined(BOOST_NO_CXX11_THREAD_LOCAL)\ + || defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)\ + || defined(BOOST_NO_CXX11_UNICODE_LITERALS)\ + || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)\ + || defined(BOOST_NO_CXX11_UNRESTRICTED_UNION)\ + || defined(BOOST_NO_CXX11_USER_DEFINED_LITERALS)\ + || defined(BOOST_NO_CXX11_VARIADIC_MACROS)\ + || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# define BOOST_NO_CXX11 +#endif + +#if defined(BOOST_NO_CXX11)\ + || defined(BOOST_NO_CXX14_AGGREGATE_NSDMI)\ + || defined(BOOST_NO_CXX14_BINARY_LITERALS)\ + || defined(BOOST_NO_CXX14_CONSTEXPR)\ + || defined(BOOST_NO_CXX14_DECLTYPE_AUTO)\ + || defined(BOOST_NO_CXX14_DIGIT_SEPARATORS)\ + || defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)\ + || defined(BOOST_NO_CXX14_HDR_SHARED_MUTEX)\ + || defined(BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES)\ + || defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION)\ + || defined(BOOST_NO_CXX14_STD_EXCHANGE)\ + || defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) +# define BOOST_NO_CXX14 +#endif + +#if defined(BOOST_NO_CXX14)\ + || defined(BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS)\ + || defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)\ + || defined(BOOST_NO_CXX17_FOLD_EXPRESSIONS)\ + || defined(BOOST_NO_CXX17_HDR_ANY)\ + || defined(BOOST_NO_CXX17_HDR_CHARCONV)\ + || defined(BOOST_NO_CXX17_HDR_EXECUTION)\ + || defined(BOOST_NO_CXX17_HDR_FILESYSTEM)\ + || defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)\ + || defined(BOOST_NO_CXX17_HDR_OPTIONAL)\ + || defined(BOOST_NO_CXX17_HDR_STRING_VIEW)\ + || defined(BOOST_NO_CXX17_HDR_VARIANT)\ + || defined(BOOST_NO_CXX17_IF_CONSTEXPR)\ + || defined(BOOST_NO_CXX17_INLINE_VARIABLES)\ + || defined(BOOST_NO_CXX17_ITERATOR_TRAITS)\ + || defined(BOOST_NO_CXX17_STD_APPLY)\ + || defined(BOOST_NO_CXX17_STD_INVOKE)\ + || defined(BOOST_NO_CXX17_STRUCTURED_BINDINGS) +# define BOOST_NO_CXX17 +#endif + +#if defined(BOOST_NO_CXX17)\ + || defined(BOOST_NO_CXX20_HDR_BARRIER)\ + || defined(BOOST_NO_CXX20_HDR_BIT)\ + || defined(BOOST_NO_CXX20_HDR_COMPARE)\ + || defined(BOOST_NO_CXX20_HDR_CONCEPTS)\ + || defined(BOOST_NO_CXX20_HDR_COROUTINE)\ + || defined(BOOST_NO_CXX20_HDR_FORMAT)\ + || defined(BOOST_NO_CXX20_HDR_LATCH)\ + || defined(BOOST_NO_CXX20_HDR_NUMBERS)\ + || defined(BOOST_NO_CXX20_HDR_RANGES)\ + || defined(BOOST_NO_CXX20_HDR_SEMAPHORE)\ + || defined(BOOST_NO_CXX20_HDR_SOURCE_LOCATION)\ + || defined(BOOST_NO_CXX20_HDR_SPAN)\ + || defined(BOOST_NO_CXX20_HDR_STOP_TOKEN)\ + || defined(BOOST_NO_CXX20_HDR_SYNCSTREAM)\ + || defined(BOOST_NO_CXX20_HDR_VERSION) +# define BOOST_NO_CXX20 +#endif + +#if defined(BOOST_NO_CXX20)\ + || defined(BOOST_NO_CXX23_HDR_EXPECTED)\ + || defined(BOOST_NO_CXX23_HDR_FLAT_MAP)\ + || defined(BOOST_NO_CXX23_HDR_FLAT_SET)\ + || defined(BOOST_NO_CXX23_HDR_GENERATOR)\ + || defined(BOOST_NO_CXX23_HDR_MDSPAN)\ + || defined(BOOST_NO_CXX23_HDR_PRINT)\ + || defined(BOOST_NO_CXX23_HDR_SPANSTREAM)\ + || defined(BOOST_NO_CXX23_HDR_STACKTRACE)\ + || defined(BOOST_NO_CXX23_HDR_STDFLOAT) +# define BOOST_NO_CXX23 +#endif + diff --git a/src/boost/config/detail/posix_features.hpp b/src/boost/config/detail/posix_features.hpp new file mode 100644 index 00000000..d1295479 --- /dev/null +++ b/src/boost/config/detail/posix_features.hpp @@ -0,0 +1,95 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are 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 most recent version. + +// All POSIX feature tests go in this file, +// Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well +// _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's +// may be present but none-functional unless _POSIX_C_SOURCE and +// _XOPEN_SOURCE have been defined to the right value (it's up +// to the user to do this *before* including any header, although +// in most cases the compiler will do this for you). + +# if defined(BOOST_HAS_UNISTD_H) +# include + + // XOpen has , but is this the correct version check? +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3) +# define BOOST_HAS_NL_TYPES_H +# endif + + // POSIX version 6 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100) +# define BOOST_HAS_STDINT_H +# endif + + // POSIX version 2 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L) +# define BOOST_HAS_DIRENT_H +# endif + + // POSIX version 3 requires to have sigaction: +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) +# define BOOST_HAS_SIGACTION +# endif + // POSIX defines _POSIX_THREADS > 0 for pthread support, + // however some platforms define _POSIX_THREADS without + // a value, hence the (_POSIX_THREADS+0 >= 0) check. + // Strictly speaking this may catch platforms with a + // non-functioning stub , but such occurrences should + // occur very rarely if at all. +# if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS) +# define BOOST_HAS_PTHREADS +# endif + + // BOOST_HAS_NANOSLEEP: + // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME: +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_NANOSLEEP +# endif + + // BOOST_HAS_CLOCK_GETTIME: + // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME + // but at least one platform - linux - defines that flag without + // defining clock_gettime): +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) +# define BOOST_HAS_CLOCK_GETTIME +# endif + + // BOOST_HAS_SCHED_YIELD: + // This is predicated on _POSIX_PRIORITY_SCHEDULING or + // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME. +# if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\ + || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_SCHED_YIELD +# endif + + // BOOST_HAS_GETTIMEOFDAY: + // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE: + // These are predicated on _XOPEN_VERSION, and appears to be first released + // in issue 4, version 2 (_XOPEN_VERSION > 500). + // Likewise for the functions log1p and expm1. +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500) +# define BOOST_HAS_GETTIMEOFDAY +# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500) +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +# endif + + + + diff --git a/src/boost/config/detail/select_compiler_config.hpp b/src/boost/config/detail/select_compiler_config.hpp new file mode 100644 index 00000000..c3d99e1a --- /dev/null +++ b/src/boost/config/detail/select_compiler_config.hpp @@ -0,0 +1,157 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Martin Wille 2003. +// (C) Copyright Guillaume Melquiond 2003. +// +// 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) + +// See http://www.boost.org/ for most recent version. + +// locate which compiler we are using and define +// BOOST_COMPILER_CONFIG as needed: + +#if defined __CUDACC__ +// NVIDIA CUDA C++ compiler for GPU +# include "boost/config/compiler/nvcc.hpp" + +#endif + +#if defined(__GCCXML__) +// GCC-XML emulates other compilers, it has to appear first here! +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" + +#elif defined(_CRAYC) +// EDG based Cray compiler: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp" + +#elif defined __COMO__ +// Comeau C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" + +#elif defined(__PATHSCALE__) && (__PATHCC__ >= 4) +// PathScale EKOPath compiler (has to come before clang and gcc) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pathscale.hpp" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp" + +#elif defined __clang__ && !defined(__ibmxl__) && !defined(__CODEGEARC__) +// Clang C++ emulates GCC, so it has to appear early. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp" + +#elif defined __DMC__ +// Digital Mars C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" + +#elif defined __DCC__ +// Wind River Diab C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/diab.hpp" + +#elif defined(__PGI) +// Portland Group Inc. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp" + +# elif defined(__GNUC__) && !defined(__ibmxl__) +// GNU C++: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp" + +#elif defined __KCC +// Kai C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp" + +#elif defined __sgi +// SGI MIPSpro C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp" + +#elif defined __ghs +// Greenhills C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp" + +#elif defined __CODEGEARC__ +// CodeGear - must be checked for before Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp" + +#elif defined __BORLANDC__ +// Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp" + +#elif defined __HP_aCC +// HP aCC +# define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp" + +#elif defined(__MRC__) || defined(__SC__) +// MPW MrCpp or SCpp +# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp" + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__) +// IBM z/OS XL C/C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp_zos.hpp" + +#elif defined(__ibmxl__) +// IBM XL C/C++ for Linux (Little Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp.hpp" + +#elif defined(__IBMCPP__) +// IBM Visual Age or IBM XL C/C++ for Linux (Big Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the compiler: +# error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)" + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the headers we *might* include: +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/src/boost/config/detail/select_platform_config.hpp b/src/boost/config/detail/select_platform_config.hpp new file mode 100644 index 00000000..dbff74aa --- /dev/null +++ b/src/boost/config/detail/select_platform_config.hpp @@ -0,0 +1,147 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are 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 most recent version. + +// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. +// Note that we define the headers to include using "header_name" not +// in order to prevent macro expansion within the header +// name (for example "linux" is a macro on linux systems). + +#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) +// linux, also other platforms (Hurd etc) that use GLIBC, should these really have their own config headers though? +# define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp" + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +// BSD: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp" + +#elif defined(sun) || defined(__sun) +// solaris: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp" + +#elif defined(__sgi) +// SGI Irix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp" + +#elif defined(__hpux) +// hp unix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp" + +#elif defined(__CYGWIN__) +// cygwin is not win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +// win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp" + +#elif defined(__HAIKU__) +// Haiku +# define BOOST_PLATFORM_CONFIG "boost/config/platform/haiku.hpp" + +#elif defined(__BEOS__) +// BeOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp" + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp" + +#elif defined(__TOS_MVS__) +// IBM z/OS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/zos.hpp" + +#elif defined(__IBMCPP__) || defined(_AIX) +// IBM AIX +# define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp" + +#elif defined(__amigaos__) +// AmigaOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp" + +#elif defined(__QNXNTO__) +// QNX: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp" + +#elif defined(__VXWORKS__) +// vxWorks: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp" + +#elif defined(__SYMBIAN32__) +// Symbian: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp" + +#elif defined(_CRAYC) +// Cray: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cray.hpp" + +#elif defined(__VMS) +// VMS: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vms.hpp" + +#elif defined(__CloudABI__) +// Nuxi CloudABI: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cloudabi.hpp" + +#elif defined (__wasm__) +// Web assembly: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/wasm.hpp" + +#else + +# if defined(unix) \ + || defined(__unix) \ + || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) + + // generic unix platform: + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif + +# include + +# endif + +# if defined (BOOST_ASSERT_CONFIG) + // this must come last - generate an error if we don't + // recognise the platform: +# error "Unknown platform - please configure and report the results to boost.org" +# endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/platform/linux.hpp" +# include "boost/config/platform/bsd.hpp" +# include "boost/config/platform/solaris.hpp" +# include "boost/config/platform/irix.hpp" +# include "boost/config/platform/hpux.hpp" +# include "boost/config/platform/cygwin.hpp" +# include "boost/config/platform/win32.hpp" +# include "boost/config/platform/beos.hpp" +# include "boost/config/platform/macos.hpp" +# include "boost/config/platform/zos.hpp" +# include "boost/config/platform/aix.hpp" +# include "boost/config/platform/amigaos.hpp" +# include "boost/config/platform/qnxnto.hpp" +# include "boost/config/platform/vxworks.hpp" +# include "boost/config/platform/symbian.hpp" +# include "boost/config/platform/cray.hpp" +# include "boost/config/platform/vms.hpp" +# include + + + +#endif + diff --git a/src/boost/config/detail/select_stdlib_config.hpp b/src/boost/config/detail/select_stdlib_config.hpp new file mode 100644 index 00000000..1a09dda1 --- /dev/null +++ b/src/boost/config/detail/select_stdlib_config.hpp @@ -0,0 +1,121 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2002. +// Use, modification and distribution are 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 most recent version. + +// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: + +// First, check if __has_include is available and include can be located, +// otherwise include to determine if some version of STLport is in use as the std lib +// (do not rely on this header being included since users can short-circuit this header +// if they know whose std lib they are using.) +#if defined(__cplusplus) && defined(__has_include) +# if __has_include() +// It should be safe to include `` when it is present without checking +// the actual C++ language version as it consists solely of macro definitions. +// [version.syn] p1: The header supplies implementation-dependent +// information about the C++ standard library (e.g., version number and release date). +# include +# else +# include +# endif +#elif defined(__cplusplus) +# include +#else +# include +#endif + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +// STLPort library; this _must_ come first, otherwise since +// STLport typically sits on top of some other library, we +// can end up detecting that first rather than STLport: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp" + +#else + +// If our std lib was not some version of STLport, and has not otherwise +// been detected, then include as it is about +// the smallest of the std lib headers that includes real C++ stuff. +// Some std libs do not include their C++-related macros in +// so this additional include makes sure we get those definitions. +// Note: do not rely on this header being included since users can short-circuit this +// #include if they know whose std lib they are using. +#if !defined(__LIBCOMO__) && !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER)\ + && !defined(_LIBCPP_VERSION) && !defined(__GLIBCPP__) && !defined(__GLIBCXX__)\ + && !defined(__STL_CONFIG_H) && !defined(__MSL_CPP__) && !defined(__IBMCPP__)\ + && !defined(MSIPL_COMPILE_H) && !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#endif + +#if defined(__LIBCOMO__) +// Comeau STL: +#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp" + +#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// Rogue Wave library: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp" + +#elif defined(_LIBCPP_VERSION) +// libc++ +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcpp.hpp" + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +// GNU libstdc++ 3 +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp" + +#elif defined(__STL_CONFIG_H) +// generic SGI STL +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp" + +#elif defined(__MSL_CPP__) +// MSL standard lib: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp" + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__) +// IBM z/OS XL C/C++ +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/xlcpp_zos.hpp" + +#elif defined(__IBMCPP__) +// take the default VACPP std lib +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp" + +#elif defined(MSIPL_COMPILE_H) +// Modena C++ standard library +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp" + +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Dinkumware Library (this has to appear after any possible replacement libraries): +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the library: +# error "Unknown standard library - please configure and report the results to boost.org" + +#endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/stdlib/stlport.hpp" +# include "boost/config/stdlib/libcomo.hpp" +# include "boost/config/stdlib/roguewave.hpp" +# include "boost/config/stdlib/libcpp.hpp" +# include "boost/config/stdlib/libstdcpp3.hpp" +# include "boost/config/stdlib/sgi.hpp" +# include "boost/config/stdlib/msl.hpp" +# include "boost/config/stdlib/xlcpp_zos.hpp" +# include "boost/config/stdlib/vacpp.hpp" +# include "boost/config/stdlib/modena.hpp" +# include "boost/config/stdlib/dinkumware.hpp" +#endif + diff --git a/src/boost/config/detail/suffix.hpp b/src/boost/config/detail/suffix.hpp new file mode 100644 index 00000000..2650510f --- /dev/null +++ b/src/boost/config/detail/suffix.hpp @@ -0,0 +1,1334 @@ +// Boost config.hpp configuration header file ------------------------------// +// boostinspect:ndprecated_macros -- tell the inspect tool to ignore this file + +// Copyright (c) 2001-2003 John Maddock +// Copyright (c) 2001 Darin Adler +// Copyright (c) 2001 Peter Dimov +// Copyright (c) 2002 Bill Kempf +// Copyright (c) 2002 Jens Maurer +// Copyright (c) 2002-2003 David Abrahams +// Copyright (c) 2003 Gennaro Prota +// Copyright (c) 2003 Eric Friedman +// Copyright (c) 2010 Eric Jourdanneau, Joel Falcou +// 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) + +// See http://www.boost.org/ for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config/ +// +// This file is intended to be stable, and relatively unchanging. +// It should contain boilerplate code only - no compiler specific +// code unless it is unavoidable - no changes unless unavoidable. + +#ifndef BOOST_CONFIG_SUFFIX_HPP +#define BOOST_CONFIG_SUFFIX_HPP + +#if defined(__GNUC__) && (__GNUC__ >= 4) +// +// Some GCC-4.x versions issue warnings even when __extension__ is used, +// so use this as a workaround: +// +#pragma GCC system_header +#endif + +// +// ensure that visibility macros are always defined, thus simplifying use +// +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_EXPORT +#endif +#ifndef BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_IMPORT +#endif +#ifndef BOOST_SYMBOL_VISIBLE +# define BOOST_SYMBOL_VISIBLE +#endif + +// +// disable explicitly enforced visibility +// +#if defined(BOOST_DISABLE_EXPLICIT_SYMBOL_VISIBILITY) + +#undef BOOST_SYMBOL_EXPORT +#define BOOST_SYMBOL_EXPORT + +#undef BOOST_SYMBOL_IMPORT +#define BOOST_SYMBOL_IMPORT + +#undef BOOST_SYMBOL_VISIBLE +#define BOOST_SYMBOL_VISIBLE + +#endif + +// +// look for long long by looking for the appropriate macros in . +// Note that we use limits.h rather than climits for maximal portability, +// remember that since these just declare a bunch of macros, there should be +// no namespace issues from this. +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG) \ + && !defined(BOOST_MSVC) && !defined(BOOST_BORLANDC) +# include +# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif +#endif + +// GCC 3.x will clean up all of those nasty macro definitions that +// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine +// it under GCC 3.x. +#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS) +# undef BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// Assume any extensions are in namespace std:: unless stated otherwise: +// +# ifndef BOOST_STD_EXTENSION_NAMESPACE +# define BOOST_STD_EXTENSION_NAMESPACE std +# endif + +// +// If cv-qualified specializations are not allowed, then neither are cv-void ones: +// +# if defined(BOOST_NO_CV_SPECIALIZATIONS) \ + && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# endif + +// +// If there is no numeric_limits template, then it can't have any compile time +// constants either! +// +# if defined(BOOST_NO_LIMITS) \ + && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// if there is no long long then there is no specialisation +// for numeric_limits either: +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +#endif + +// +// if there is no __int64 then there is no specialisation +// for numeric_limits<__int64> either: +// +#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// if member templates are supported then so is the +// VC6 subset of member templates: +// +# if !defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif + +// +// Without partial specialization, can't test for partial specialisation bugs: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# endif + +// +// Without partial specialization, we can't have array-type partial specialisations: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif + +// +// Without partial specialization, std::iterator_traits can't work: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +# define BOOST_NO_STD_ITERATOR_TRAITS +# endif + +// +// Without partial specialization, partial +// specialization with default args won't work either: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) +# define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +# endif + +// +// Without member template support, we can't have template constructors +// in the standard library either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# endif + +// +// Without member template support, we can't have a conforming +// std::allocator template either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_NO_STD_ALLOCATOR +# endif + +// +// without ADL support then using declarations will break ADL as well: +// +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// Without typeid support we have no dynamic RTTI either: +// +#if defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// +// If we have a standard allocator, then we have a partial one as well: +// +#if !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +// +// We can't have a working std::use_facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET) +# define BOOST_NO_STD_USE_FACET +# endif + +// +// We can't have a std::messages facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES) +# define BOOST_NO_STD_MESSAGES +# endif + +// +// We can't have a working std::wstreambuf if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF) +# define BOOST_NO_STD_WSTREAMBUF +# endif + +// +// We can't have a if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE) +# define BOOST_NO_CWCTYPE +# endif + +// +// We can't have a swprintf if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +# endif + +// +// If Win32 support is turned off, then we must turn off +// threading support also, unless there is some other +// thread API enabled: +// +#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \ + && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS) +# define BOOST_DISABLE_THREADS +#endif + +// +// Turn on threading support if the compiler thinks that it's in +// multithreaded mode. We put this here because there are only a +// limited number of macros that identify this (if there's any missing +// from here then add to the appropriate compiler section): +// +#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \ + || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \ + && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if BOOST_DISABLE_THREADS is defined: +// +#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if we don't recognise the threading API: +// +#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\ + && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\ + && !defined(BOOST_HAS_MPTASKS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading detail macros off if we don't (want to) use threading +// +#ifndef BOOST_HAS_THREADS +# undef BOOST_HAS_PTHREADS +# undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# undef BOOST_HAS_PTHREAD_YIELD +# undef BOOST_HAS_PTHREAD_DELAY_NP +# undef BOOST_HAS_WINTHREADS +# undef BOOST_HAS_BETHREADS +# undef BOOST_HAS_MPTASKS +#endif + +// +// If the compiler claims to be C99 conformant, then it had better +// have a : +// +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define BOOST_HAS_STDINT_H +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +// +// Define BOOST_NO_SLIST and BOOST_NO_HASH if required. +// Note that this is for backwards compatibility only. +// +# if !defined(BOOST_HAS_SLIST) && !defined(BOOST_NO_SLIST) +# define BOOST_NO_SLIST +# endif + +# if !defined(BOOST_HAS_HASH) && !defined(BOOST_NO_HASH) +# define BOOST_NO_HASH +# endif + +// +// Set BOOST_SLIST_HEADER if not set already: +// +#if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER) +# define BOOST_SLIST_HEADER +#endif + +// +// Set BOOST_HASH_SET_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER) +# define BOOST_HASH_SET_HEADER +#endif + +// +// Set BOOST_HASH_MAP_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER) +# define BOOST_HASH_MAP_HEADER +#endif + +// BOOST_HAS_ABI_HEADERS +// This macro gets set if we have headers that fix the ABI, +// and prevent ODR violations when linking to external libraries: +#if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS) +# define BOOST_HAS_ABI_HEADERS +#endif + +#if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS) +# undef BOOST_HAS_ABI_HEADERS +#endif + +// BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// +// Because std::size_t usage is so common, even in boost headers which do not +// otherwise use the C library, the workaround is included here so +// that ugly workaround code need not appear in many other boost headers. +// NOTE WELL: This is a workaround for non-conforming compilers; +// must still be #included in the usual places so that inclusion +// works as expected with standard conforming compilers. The resulting +// double inclusion of is harmless. + +# if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus) +# include + namespace std { using ::ptrdiff_t; using ::size_t; } +# endif + +// Workaround for the unfortunate min/max macros defined by some platform headers + +#define BOOST_PREVENT_MACRO_SUBSTITUTION + +#ifndef BOOST_USING_STD_MIN +# define BOOST_USING_STD_MIN() using std::min +#endif + +#ifndef BOOST_USING_STD_MAX +# define BOOST_USING_STD_MAX() using std::max +#endif + +// BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// + +# if defined(BOOST_NO_STD_MIN_MAX) && defined(__cplusplus) + +namespace std { + template + inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; + } + template + inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; + } +} + +# endif + +// BOOST_STATIC_CONSTANT workaround --------------------------------------- // +// On compilers which don't allow in-class initialization of static integral +// constant members, we must use enums as a workaround if we want the constants +// to be available at compile-time. This macro gives us a convenient way to +// declare such constants. + +# ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } +# else +# define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment +# endif + +// BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// +// When the standard library does not have a conforming std::use_facet there +// are various workarounds available, but they differ from library to library. +// The same problem occurs with has_facet. +// These macros provide a consistent way to access a locale's facets. +// Usage: +// replace +// std::use_facet(loc); +// with +// BOOST_USE_FACET(Type, loc); +// Note do not add a std:: prefix to the front of BOOST_USE_FACET! +// Use for BOOST_HAS_FACET is analogous. + +#if defined(BOOST_NO_STD_USE_FACET) +# ifdef BOOST_HAS_TWO_ARG_USE_FACET +# define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast(0)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast(0)) +# elif defined(BOOST_HAS_MACRO_USE_FACET) +# define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type) +# define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type) +# elif defined(BOOST_HAS_STLP_USE_FACET) +# define BOOST_USE_FACET(Type, loc) (*std::_Use_facet(loc)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +# endif +#else +# define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +#endif + +// BOOST_NESTED_TEMPLATE workaround ------------------------------------------// +// Member templates are supported by some compilers even though they can't use +// the A::template member syntax, as a workaround replace: +// +// typedef typename A::template rebind binder; +// +// with: +// +// typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# define BOOST_NESTED_TEMPLATE template +#else +# define BOOST_NESTED_TEMPLATE +#endif + +// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// +// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION +// is defined, in which case it evaluates to return x; Use when you have a return +// statement that can never be reached. + +#ifndef BOOST_UNREACHABLE_RETURN +# ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_UNREACHABLE_RETURN(x) return x; +# else +# define BOOST_UNREACHABLE_RETURN(x) +# endif +#endif + +// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// +// +// Some compilers don't support the use of `typename' for dependent +// types in deduced contexts, e.g. +// +// template void f(T, typename T::type); +// ^^^^^^^^ +// Replace these declarations with: +// +// template void f(T, BOOST_DEDUCED_TYPENAME T::type); + +#ifndef BOOST_NO_DEDUCED_TYPENAME +# define BOOST_DEDUCED_TYPENAME typename +#else +# define BOOST_DEDUCED_TYPENAME +#endif + +#ifndef BOOST_NO_TYPENAME_WITH_CTOR +# define BOOST_CTOR_TYPENAME typename +#else +# define BOOST_CTOR_TYPENAME +#endif + +// +// If we're on a CUDA device (note DEVICE not HOST, irrespective of compiler) then disable __int128 and __float128 support if present: +// +#if defined(__CUDA_ARCH__) && defined(BOOST_HAS_FLOAT128) +# undef BOOST_HAS_FLOAT128 +#endif +#if defined(__CUDA_ARCH__) && defined(BOOST_HAS_INT128) +# undef BOOST_HAS_INT128 +#endif + +// long long workaround ------------------------------------------// +// On gcc (and maybe other compilers?) long long is alway supported +// but it's use may generate either warnings (with -ansi), or errors +// (with -pedantic -ansi) unless it's use is prefixed by __extension__ +// +#if defined(BOOST_HAS_LONG_LONG) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef long long long_long_type; + __extension__ typedef unsigned long long ulong_long_type; +# else + typedef long long long_long_type; + typedef unsigned long long ulong_long_type; +# endif +} +#endif +// same again for __int128: +#if defined(BOOST_HAS_INT128) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef __int128 int128_type; + __extension__ typedef unsigned __int128 uint128_type; +# else + typedef __int128 int128_type; + typedef unsigned __int128 uint128_type; +# endif +} +#endif +// same again for __float128: +#if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus) +namespace boost { +# ifdef __GNUC__ + __extension__ typedef __float128 float128_type; +# else + typedef __float128 float128_type; +# endif +} +#endif + +// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// + +// These macros are obsolete. Port away and remove. + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +// When BOOST_NO_STD_TYPEINFO is defined, we can just import +// the global definition into std namespace, +// see https://svn.boost.org/trac10/ticket/4115 +#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) && defined(BOOST_MSVC) +#include +namespace std{ using ::type_info; } +// Since we do now have typeinfo, undef the macro: +#undef BOOST_NO_STD_TYPEINFO +#endif + +// ---------------------------------------------------------------------------// + +// Helper macro BOOST_STRINGIZE: +// Helper macro BOOST_JOIN: + +#include + +// +// Set some default values for compiler/library/platform names. +// These are for debugging config setup only: +// +# ifndef BOOST_COMPILER +# define BOOST_COMPILER "Unknown ISO C++ Compiler" +# endif +# ifndef BOOST_STDLIB +# define BOOST_STDLIB "Unknown ISO standard library" +# endif +# ifndef BOOST_PLATFORM +# if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) +# define BOOST_PLATFORM "Generic Unix" +# else +# define BOOST_PLATFORM "Unknown" +# endif +# endif + +// +// Set some default values GPU support +// +# ifndef BOOST_GPU_ENABLED +# define BOOST_GPU_ENABLED +# endif + +// BOOST_RESTRICT ---------------------------------------------// +// Macro to use in place of 'restrict' keyword variants +#if !defined(BOOST_RESTRICT) +# if defined(_MSC_VER) +# define BOOST_RESTRICT __restrict +# if !defined(BOOST_NO_RESTRICT_REFERENCES) && (_MSC_FULL_VER < 190023026) +# define BOOST_NO_RESTRICT_REFERENCES +# endif +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_RESTRICT __restrict__ +# else +# define BOOST_RESTRICT +# if !defined(BOOST_NO_RESTRICT_REFERENCES) +# define BOOST_NO_RESTRICT_REFERENCES +# endif +# endif +#endif + +// BOOST_MAY_ALIAS -----------------------------------------------// +// The macro expands to an attribute to mark a type that is allowed to alias other types. +// The macro is defined in the compiler-specific headers. +#if !defined(BOOST_MAY_ALIAS) +# define BOOST_NO_MAY_ALIAS +# define BOOST_MAY_ALIAS +#endif + +// BOOST_FORCEINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to force a function to be inline +#if !defined(BOOST_FORCEINLINE) +# if defined(_MSC_VER) +# define BOOST_FORCEINLINE __forceinline +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) +# else +# define BOOST_FORCEINLINE inline +# endif +#endif + +// BOOST_NOINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to prevent a function to be inlined +#if !defined(BOOST_NOINLINE) +# if defined(_MSC_VER) +# define BOOST_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# if defined(__CUDACC__) + // nvcc doesn't always parse __noinline__, + // see: https://svn.boost.org/trac/boost/ticket/9392 +# define BOOST_NOINLINE __attribute__ ((noinline)) +# elif defined(__HIP__) + // See https://github.com/boostorg/config/issues/392 +# define BOOST_NOINLINE __attribute__ ((noinline)) +# else +# define BOOST_NOINLINE __attribute__ ((__noinline__)) +# endif +# else +# define BOOST_NOINLINE +# endif +#endif + +// BOOST_NORETURN ---------------------------------------------// +// Macro to use before a function declaration/definition to designate +// the function as not returning normally (i.e. with a return statement +// or by leaving the function scope, if the function return type is void). +#if !defined(BOOST_NORETURN) +# if defined(_MSC_VER) +# define BOOST_NORETURN __declspec(noreturn) +# elif defined(__GNUC__) || defined(__CODEGEARC__) && defined(__clang__) +# define BOOST_NORETURN __attribute__ ((__noreturn__)) +# elif defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +# if __has_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# endif +#endif + +#if !defined(BOOST_NORETURN) +# define BOOST_NO_NORETURN +# define BOOST_NORETURN +#endif + +// BOOST_DEPRECATED -------------------------------------------// +// The macro can be used to mark deprecated symbols, such as functions, objects and types. +// Any code that uses these symbols will produce warnings, possibly with a message specified +// as an argument. The warnings can be suppressed by defining BOOST_ALLOW_DEPRECATED_SYMBOLS +// or BOOST_ALLOW_DEPRECATED. +#if !defined(BOOST_DEPRECATED) && __cplusplus >= 201402 +#define BOOST_DEPRECATED(msg) [[deprecated(msg)]] +#endif + +#if defined(BOOST_ALLOW_DEPRECATED_SYMBOLS) || defined(BOOST_ALLOW_DEPRECATED) +#undef BOOST_DEPRECATED +#endif + +#if !defined(BOOST_DEPRECATED) +#define BOOST_DEPRECATED(msg) +#endif + +// Branch prediction hints +// These macros are intended to wrap conditional expressions that yield true or false +// +// if (BOOST_LIKELY(var == 10)) +// { +// // the most probable code here +// } +// +#if !defined(BOOST_LIKELY) +# define BOOST_LIKELY(x) x +#endif +#if !defined(BOOST_UNLIKELY) +# define BOOST_UNLIKELY(x) x +#endif + +#if !defined(BOOST_NO_CXX11_OVERRIDE) +# define BOOST_OVERRIDE override +#else +# define BOOST_OVERRIDE +#endif + +// Type and data alignment specification +// +#if !defined(BOOST_ALIGNMENT) +# if !defined(BOOST_NO_CXX11_ALIGNAS) +# define BOOST_ALIGNMENT(x) alignas(x) +# elif defined(_MSC_VER) +# define BOOST_ALIGNMENT(x) __declspec(align(x)) +# elif defined(__GNUC__) +# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x))) +# else +# define BOOST_NO_ALIGNMENT +# define BOOST_ALIGNMENT(x) +# endif +#endif + +// Lack of non-public defaulted functions is implied by the lack of any defaulted functions +#if !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) && defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// Lack of defaulted moves is implied by the lack of either rvalue references or any defaulted functions +#if !defined(BOOST_NO_CXX11_DEFAULTED_MOVES) && (defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)) +# define BOOST_NO_CXX11_DEFAULTED_MOVES +#endif + +// Defaulted and deleted function declaration helpers +// These macros are intended to be inside a class definition. +// BOOST_DEFAULTED_FUNCTION accepts the function declaration and its +// body, which will be used if the compiler doesn't support defaulted functions. +// BOOST_DELETED_FUNCTION only accepts the function declaration. It +// will expand to a private function declaration, if the compiler doesn't support +// deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION +// in the end of the class definition. +// +// class my_class +// { +// public: +// // Default-constructible +// BOOST_DEFAULTED_FUNCTION(my_class(), {}) +// // Copying prohibited +// BOOST_DELETED_FUNCTION(my_class(my_class const&)) +// BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&)) +// }; +// +#if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)) +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default; +#else +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun body +#endif + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_DELETED_FUNCTION(fun) fun = delete; +#else +# define BOOST_DELETED_FUNCTION(fun) private: fun; +#endif + +// +// Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined +// +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +#define BOOST_NO_CXX11_DECLTYPE_N3276 BOOST_NO_CXX11_DECLTYPE +#endif + +// -------------------- Deprecated macros for 1.50 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET or BOOST_NO_CXX11_HDR_UNORDERED_MAP +// instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) || defined (BOOST_NO_CXX11_HDR_UNORDERED_SET) +# ifndef BOOST_NO_CXX11_STD_UNORDERED +# define BOOST_NO_CXX11_STD_UNORDERED +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST instead of BOOST_NO_INITIALIZER_LISTS +#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_INITIALIZER_LISTS) +# define BOOST_NO_INITIALIZER_LISTS +#endif + +// Use BOOST_NO_CXX11_HDR_ARRAY instead of BOOST_NO_0X_HDR_ARRAY +#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_NO_0X_HDR_ARRAY) +# define BOOST_NO_0X_HDR_ARRAY +#endif +// Use BOOST_NO_CXX11_HDR_CHRONO instead of BOOST_NO_0X_HDR_CHRONO +#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_NO_0X_HDR_CHRONO) +# define BOOST_NO_0X_HDR_CHRONO +#endif +// Use BOOST_NO_CXX11_HDR_CODECVT instead of BOOST_NO_0X_HDR_CODECVT +#if defined(BOOST_NO_CXX11_HDR_CODECVT) && !defined(BOOST_NO_0X_HDR_CODECVT) +# define BOOST_NO_0X_HDR_CODECVT +#endif +// Use BOOST_NO_CXX11_HDR_CONDITION_VARIABLE instead of BOOST_NO_0X_HDR_CONDITION_VARIABLE +#if defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE) && !defined(BOOST_NO_0X_HDR_CONDITION_VARIABLE) +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +#endif +// Use BOOST_NO_CXX11_HDR_FORWARD_LIST instead of BOOST_NO_0X_HDR_FORWARD_LIST +#if defined(BOOST_NO_CXX11_HDR_FORWARD_LIST) && !defined(BOOST_NO_0X_HDR_FORWARD_LIST) +# define BOOST_NO_0X_HDR_FORWARD_LIST +#endif +// Use BOOST_NO_CXX11_HDR_FUTURE instead of BOOST_NO_0X_HDR_FUTURE +#if defined(BOOST_NO_CXX11_HDR_FUTURE) && !defined(BOOST_NO_0X_HDR_FUTURE) +# define BOOST_NO_0X_HDR_FUTURE +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST +// instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS +#ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# ifndef BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# endif +# ifndef BOOST_NO_INITIALIZER_LISTS +# define BOOST_NO_INITIALIZER_LISTS +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_MUTEX instead of BOOST_NO_0X_HDR_MUTEX +#if defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX) +# define BOOST_NO_0X_HDR_MUTEX +#endif +// Use BOOST_NO_CXX11_HDR_RANDOM instead of BOOST_NO_0X_HDR_RANDOM +#if defined(BOOST_NO_CXX11_HDR_RANDOM) && !defined(BOOST_NO_0X_HDR_RANDOM) +# define BOOST_NO_0X_HDR_RANDOM +#endif +// Use BOOST_NO_CXX11_HDR_RATIO instead of BOOST_NO_0X_HDR_RATIO +#if defined(BOOST_NO_CXX11_HDR_RATIO) && !defined(BOOST_NO_0X_HDR_RATIO) +# define BOOST_NO_0X_HDR_RATIO +#endif +// Use BOOST_NO_CXX11_HDR_REGEX instead of BOOST_NO_0X_HDR_REGEX +#if defined(BOOST_NO_CXX11_HDR_REGEX) && !defined(BOOST_NO_0X_HDR_REGEX) +# define BOOST_NO_0X_HDR_REGEX +#endif +// Use BOOST_NO_CXX11_HDR_SYSTEM_ERROR instead of BOOST_NO_0X_HDR_SYSTEM_ERROR +#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_0X_HDR_SYSTEM_ERROR) +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +#endif +// Use BOOST_NO_CXX11_HDR_THREAD instead of BOOST_NO_0X_HDR_THREAD +#if defined(BOOST_NO_CXX11_HDR_THREAD) && !defined(BOOST_NO_0X_HDR_THREAD) +# define BOOST_NO_0X_HDR_THREAD +#endif +// Use BOOST_NO_CXX11_HDR_TUPLE instead of BOOST_NO_0X_HDR_TUPLE +#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_0X_HDR_TUPLE) +# define BOOST_NO_0X_HDR_TUPLE +#endif +// Use BOOST_NO_CXX11_HDR_TYPE_TRAITS instead of BOOST_NO_0X_HDR_TYPE_TRAITS +#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_0X_HDR_TYPE_TRAITS) +# define BOOST_NO_0X_HDR_TYPE_TRAITS +#endif +// Use BOOST_NO_CXX11_HDR_TYPEINDEX instead of BOOST_NO_0X_HDR_TYPEINDEX +#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX) && !defined(BOOST_NO_0X_HDR_TYPEINDEX) +# define BOOST_NO_0X_HDR_TYPEINDEX +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_MAP instead of BOOST_NO_0X_HDR_UNORDERED_MAP +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) && !defined(BOOST_NO_0X_HDR_UNORDERED_MAP) +# define BOOST_NO_0X_HDR_UNORDERED_MAP +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET instead of BOOST_NO_0X_HDR_UNORDERED_SET +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_NO_0X_HDR_UNORDERED_SET) +# define BOOST_NO_0X_HDR_UNORDERED_SET +#endif + +// ------------------ End of deprecated macros for 1.50 --------------------------- + +// -------------------- Deprecated macros for 1.51 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_AUTO_DECLARATIONS instead of BOOST_NO_AUTO_DECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_AUTO_DECLARATIONS) +# define BOOST_NO_AUTO_DECLARATIONS +#endif +// Use BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS instead of BOOST_NO_AUTO_MULTIDECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS) && !defined(BOOST_NO_AUTO_MULTIDECLARATIONS) +# define BOOST_NO_AUTO_MULTIDECLARATIONS +#endif +// Use BOOST_NO_CXX11_CHAR16_T instead of BOOST_NO_CHAR16_T +#if defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CHAR16_T) +# define BOOST_NO_CHAR16_T +#endif +// Use BOOST_NO_CXX11_CHAR32_T instead of BOOST_NO_CHAR32_T +#if defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CHAR32_T) +# define BOOST_NO_CHAR32_T +#endif +// Use BOOST_NO_CXX11_TEMPLATE_ALIASES instead of BOOST_NO_TEMPLATE_ALIASES +#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_TEMPLATE_ALIASES) +# define BOOST_NO_TEMPLATE_ALIASES +#endif +// Use BOOST_NO_CXX11_CONSTEXPR instead of BOOST_NO_CONSTEXPR +#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CONSTEXPR) +# define BOOST_NO_CONSTEXPR +#endif +// Use BOOST_NO_CXX11_DECLTYPE_N3276 instead of BOOST_NO_DECLTYPE_N3276 +#if defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_DECLTYPE_N3276) +# define BOOST_NO_DECLTYPE_N3276 +#endif +// Use BOOST_NO_CXX11_DECLTYPE instead of BOOST_NO_DECLTYPE +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE) +# define BOOST_NO_DECLTYPE +#endif +// Use BOOST_NO_CXX11_DEFAULTED_FUNCTIONS instead of BOOST_NO_DEFAULTED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_DEFAULTED_FUNCTIONS) +# define BOOST_NO_DEFAULTED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_DELETED_FUNCTIONS instead of BOOST_NO_DELETED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_DELETED_FUNCTIONS) +# define BOOST_NO_DELETED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS instead of BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS) +# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#endif +// Use BOOST_NO_CXX11_EXTERN_TEMPLATE instead of BOOST_NO_EXTERN_TEMPLATE +#if defined(BOOST_NO_CXX11_EXTERN_TEMPLATE) && !defined(BOOST_NO_EXTERN_TEMPLATE) +# define BOOST_NO_EXTERN_TEMPLATE +#endif +// Use BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS instead of BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) +# define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif +// Use BOOST_NO_CXX11_LAMBDAS instead of BOOST_NO_LAMBDAS +#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS) +# define BOOST_NO_LAMBDAS +#endif +// Use BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS instead of BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#if defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS) && !defined(BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) +# define BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif +// Use BOOST_NO_CXX11_NOEXCEPT instead of BOOST_NO_NOEXCEPT +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_NOEXCEPT) +# define BOOST_NO_NOEXCEPT +#endif +// Use BOOST_NO_CXX11_NULLPTR instead of BOOST_NO_NULLPTR +#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR) +# define BOOST_NO_NULLPTR +#endif +// Use BOOST_NO_CXX11_RAW_LITERALS instead of BOOST_NO_RAW_LITERALS +#if defined(BOOST_NO_CXX11_RAW_LITERALS) && !defined(BOOST_NO_RAW_LITERALS) +# define BOOST_NO_RAW_LITERALS +#endif +// Use BOOST_NO_CXX11_RVALUE_REFERENCES instead of BOOST_NO_RVALUE_REFERENCES +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES) +# define BOOST_NO_RVALUE_REFERENCES +#endif +// Use BOOST_NO_CXX11_SCOPED_ENUMS instead of BOOST_NO_SCOPED_ENUMS +#if defined(BOOST_NO_CXX11_SCOPED_ENUMS) && !defined(BOOST_NO_SCOPED_ENUMS) +# define BOOST_NO_SCOPED_ENUMS +#endif +// Use BOOST_NO_CXX11_STATIC_ASSERT instead of BOOST_NO_STATIC_ASSERT +#if defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_NO_STATIC_ASSERT) +# define BOOST_NO_STATIC_ASSERT +#endif +// Use BOOST_NO_CXX11_STD_UNORDERED instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_STD_UNORDERED) && !defined(BOOST_NO_STD_UNORDERED) +# define BOOST_NO_STD_UNORDERED +#endif +// Use BOOST_NO_CXX11_UNICODE_LITERALS instead of BOOST_NO_UNICODE_LITERALS +#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(BOOST_NO_UNICODE_LITERALS) +# define BOOST_NO_UNICODE_LITERALS +#endif +// Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead of BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX) +# define BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#endif +// Use BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of BOOST_NO_VARIADIC_TEMPLATES +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_VARIADIC_TEMPLATES) +# define BOOST_NO_VARIADIC_TEMPLATES +#endif +// Use BOOST_NO_CXX11_VARIADIC_MACROS instead of BOOST_NO_VARIADIC_MACROS +#if defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS) +# define BOOST_NO_VARIADIC_MACROS +#endif +// Use BOOST_NO_CXX11_NUMERIC_LIMITS instead of BOOST_NO_NUMERIC_LIMITS_LOWEST +#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_NO_NUMERIC_LIMITS_LOWEST) +# define BOOST_NO_NUMERIC_LIMITS_LOWEST +#endif +// ------------------ End of deprecated macros for 1.51 --------------------------- + + +// +// Helper macro for marking types and methods final +// +#if !defined(BOOST_NO_CXX11_FINAL) +# define BOOST_FINAL final +#else +# define BOOST_FINAL +#endif + +// +// Helper macros BOOST_NOEXCEPT, BOOST_NOEXCEPT_IF, BOOST_NOEXCEPT_EXPR +// These aid the transition to C++11 while still supporting C++03 compilers +// +#ifdef BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NOEXCEPT +# define BOOST_NOEXCEPT_OR_NOTHROW throw() +# define BOOST_NOEXCEPT_IF(Predicate) +# define BOOST_NOEXCEPT_EXPR(Expression) false +#else +# define BOOST_NOEXCEPT noexcept +# define BOOST_NOEXCEPT_OR_NOTHROW noexcept +# define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) +# define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression)) +#endif +// +// Helper macro BOOST_FALLTHROUGH +// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended +// fall-through between case labels in a switch statement. We use a definition +// that requires a semicolon after it to avoid at least one type of misuse even +// on unsupported compilers. +// +#ifndef BOOST_FALLTHROUGH +# define BOOST_FALLTHROUGH ((void)0) +#endif + +// +// constexpr workarounds +// +#if defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_CONSTEXPR +#define BOOST_CONSTEXPR_OR_CONST const +#else +#define BOOST_CONSTEXPR constexpr +#define BOOST_CONSTEXPR_OR_CONST constexpr +#endif +#if defined(BOOST_NO_CXX14_CONSTEXPR) +#define BOOST_CXX14_CONSTEXPR +#else +#define BOOST_CXX14_CONSTEXPR constexpr +#endif +#if !defined(BOOST_NO_CXX17_STRUCTURED_BINDINGS) && defined(BOOST_NO_CXX11_HDR_TUPLE) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif + +// +// C++17 inline variables +// +#if !defined(BOOST_NO_CXX17_INLINE_VARIABLES) +#define BOOST_INLINE_VARIABLE inline +#else +#define BOOST_INLINE_VARIABLE +#endif +// +// C++17 if constexpr +// +#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR) +# define BOOST_IF_CONSTEXPR if constexpr +#else +# define BOOST_IF_CONSTEXPR if +#endif + +#define BOOST_INLINE_CONSTEXPR BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST + +// +// Unused variable/typedef workarounds: +// +#ifndef BOOST_ATTRIBUTE_UNUSED +# if defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +# if __has_attribute(maybe_unused) +# define BOOST_ATTRIBUTE_UNUSED [[maybe_unused]] +# endif +# elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(maybe_unused) +# define BOOST_ATTRIBUTE_UNUSED [[maybe_unused]] +# endif +# endif +#endif + +#ifndef BOOST_ATTRIBUTE_UNUSED +# define BOOST_ATTRIBUTE_UNUSED +#endif + +// +// [[nodiscard]]: +// +#if defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +#if __has_attribute(nodiscard) +# define BOOST_ATTRIBUTE_NODISCARD [[nodiscard]] +#endif +#if __has_attribute(no_unique_address) +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]] +#endif +#elif defined(__has_cpp_attribute) +// clang-6 accepts [[nodiscard]] with -std=c++14, but warns about it -pedantic +#if __has_cpp_attribute(nodiscard) && !(defined(__clang__) && (__cplusplus < 201703L)) && !(defined(__GNUC__) && (__cplusplus < 201100)) +# define BOOST_ATTRIBUTE_NODISCARD [[nodiscard]] +#endif +#if __has_cpp_attribute(no_unique_address) && !(defined(__GNUC__) && (__cplusplus < 201100)) +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]] +#endif +#endif +#ifndef BOOST_ATTRIBUTE_NODISCARD +# define BOOST_ATTRIBUTE_NODISCARD +#endif +#ifndef BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS +#endif + +#define BOOST_STATIC_CONSTEXPR static BOOST_CONSTEXPR_OR_CONST + +#if !defined(BOOST_NO_CXX11_NULLPTR) +# define BOOST_NULLPTR nullptr +#else +# define BOOST_NULLPTR 0 +#endif + +// +// Set BOOST_HAS_STATIC_ASSERT when BOOST_NO_CXX11_STATIC_ASSERT is not defined +// +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_HAS_STATIC_ASSERT) +# define BOOST_HAS_STATIC_ASSERT +#endif + +// +// Set BOOST_HAS_RVALUE_REFS when BOOST_NO_CXX11_RVALUE_REFERENCES is not defined +// +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_RVALUE_REFS) +#define BOOST_HAS_RVALUE_REFS +#endif + +// +// Set BOOST_HAS_VARIADIC_TMPL when BOOST_NO_CXX11_VARIADIC_TEMPLATES is not defined +// +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_HAS_VARIADIC_TMPL) +#define BOOST_HAS_VARIADIC_TMPL +#endif +// +// Set BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS when +// BOOST_NO_CXX11_VARIADIC_TEMPLATES is set: +// +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS) +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#endif + +// This is a catch all case for obsolete compilers / std libs: +#if !defined(_YVALS) && !defined(_CPPLIB_VER) // msvc std lib already configured +#if (!defined(__has_include) || (__cplusplus < 201700)) +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_VARIANT +# define BOOST_NO_CXX17_HDR_ANY +# define BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +# define BOOST_NO_CXX17_HDR_CHARCONV +# define BOOST_NO_CXX17_HDR_EXECUTION +# define BOOST_NO_CXX17_HDR_FILESYSTEM +#else +#if !__has_include() +# define BOOST_NO_CXX17_HDR_OPTIONAL +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_VARIANT +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_ANY +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_CHARCONV +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_FILESYSTEM +#endif +#endif +#endif +// +// Define the std level that the compiler claims to support: +// +#ifndef BOOST_CXX_VERSION +# define BOOST_CXX_VERSION __cplusplus +#endif + +#if (!defined(__has_include) || (BOOST_CXX_VERSION < 201704)) +# define BOOST_NO_CXX20_HDR_BARRIER +# define BOOST_NO_CXX20_HDR_FORMAT +# define BOOST_NO_CXX20_HDR_SOURCE_LOCATION +# define BOOST_NO_CXX20_HDR_BIT +# define BOOST_NO_CXX20_HDR_LATCH +# define BOOST_NO_CXX20_HDR_SPAN +# define BOOST_NO_CXX20_HDR_COMPARE +# define BOOST_NO_CXX20_HDR_NUMBERS +# define BOOST_NO_CXX20_HDR_STOP_TOKEN +# define BOOST_NO_CXX20_HDR_CONCEPTS +# define BOOST_NO_CXX20_HDR_RANGES +# define BOOST_NO_CXX20_HDR_SYNCSTREAM +# define BOOST_NO_CXX20_HDR_COROUTINE +# define BOOST_NO_CXX20_HDR_SEMAPHORE +#else +#if (!__has_include() || !defined(__cpp_lib_barrier) || (__cpp_lib_barrier < 201907L)) && !defined(BOOST_NO_CXX20_HDR_BARRIER) +# define BOOST_NO_CXX20_HDR_BARRIER +#endif +#if (!__has_include() || !defined(__cpp_lib_format) || (__cpp_lib_format < 201907L)) && !defined(BOOST_NO_CXX20_HDR_FORMAT) +# define BOOST_NO_CXX20_HDR_FORMAT +#endif +#if (!__has_include() || !defined(__cpp_lib_source_location) || (__cpp_lib_source_location < 201907L)) && !defined(BOOST_NO_CXX20_HDR_SOURCE_LOCATION) +# define BOOST_NO_CXX20_HDR_SOURCE_LOCATION +#endif +#if (!__has_include() || !defined(__cpp_lib_bit_cast) || (__cpp_lib_bit_cast < 201806L) || !defined(__cpp_lib_bitops) || (__cpp_lib_bitops < 201907L) || !defined(__cpp_lib_endian) || (__cpp_lib_endian < 201907L)) && !defined(BOOST_NO_CXX20_HDR_BIT) +# define BOOST_NO_CXX20_HDR_BIT +#endif +#if (!__has_include() || !defined(__cpp_lib_latch) || (__cpp_lib_latch < 201907L)) && !defined(BOOST_NO_CXX20_HDR_LATCH) +# define BOOST_NO_CXX20_HDR_LATCH +#endif +#if (!__has_include() || !defined(__cpp_lib_span) || (__cpp_lib_span < 202002L)) && !defined(BOOST_NO_CXX20_HDR_SPAN) +# define BOOST_NO_CXX20_HDR_SPAN +#endif +#if (!__has_include() || !defined(__cpp_lib_three_way_comparison) || (__cpp_lib_three_way_comparison < 201907L)) && !defined(BOOST_NO_CXX20_HDR_COMPARE) +# define BOOST_NO_CXX20_HDR_COMPARE +#endif +#if (!__has_include() || !defined(__cpp_lib_math_constants) || (__cpp_lib_math_constants < 201907L)) && !defined(BOOST_NO_CXX20_HDR_NUMBERS) +# define BOOST_NO_CXX20_HDR_NUMBERS +#endif +#if (!__has_include() || !defined(__cpp_lib_jthread) || (__cpp_lib_jthread < 201911L)) && !defined(BOOST_NO_CXX20_HDR_STOP_TOKEN) +# define BOOST_NO_CXX20_HDR_STOP_TOKEN +#endif +#if (!__has_include() || !defined(__cpp_lib_concepts) || (__cpp_lib_concepts < 202002L)) && !defined(_YVALS) && !defined(_CPPLIB_VER) && !defined(BOOST_NO_CXX20_HDR_CONCEPTS) +# define BOOST_NO_CXX20_HDR_CONCEPTS +#endif +#if (!__has_include() || !defined(__cpp_lib_ranges) || (__cpp_lib_ranges < 201911L)) && !defined(BOOST_NO_CXX20_HDR_RANGES) +# define BOOST_NO_CXX20_HDR_RANGES +#endif +#if (!__has_include() || !defined(__cpp_lib_syncbuf) || (__cpp_lib_syncbuf < 201803L)) && !defined(BOOST_NO_CXX20_HDR_SYNCSTREAM) +# define BOOST_NO_CXX20_HDR_SYNCSTREAM +#endif +#if (!__has_include() || !defined(__cpp_lib_coroutine) || (__cpp_lib_coroutine < 201902L)) && !defined(BOOST_NO_CXX20_HDR_COROUTINE) +# define BOOST_NO_CXX20_HDR_COROUTINE +#endif +#if (!__has_include() || !defined(__cpp_lib_semaphore) || (__cpp_lib_semaphore < 201907L)) && !defined(BOOST_NO_CXX20_HDR_SEMAPHORE) +# define BOOST_NO_CXX20_HDR_SEMAPHORE +#endif +#endif + +#if (!defined(__has_include) || (BOOST_CXX_VERSION < 202003L)) +# define BOOST_NO_CXX23_HDR_EXPECTED +# define BOOST_NO_CXX23_HDR_FLAT_MAP +# define BOOST_NO_CXX23_HDR_FLAT_SET +# define BOOST_NO_CXX23_HDR_GENERATOR +# define BOOST_NO_CXX23_HDR_MDSPAN +# define BOOST_NO_CXX23_HDR_PRINT +# define BOOST_NO_CXX23_HDR_SPANSTREAM +# define BOOST_NO_CXX23_HDR_STACKTRACE +# define BOOST_NO_CXX23_HDR_STDFLOAT +#else +#if (!__has_include() || !defined(__cpp_lib_expected) || (__cpp_lib_expected < 202211L)) && !defined(BOOST_NO_CXX23_HDR_EXPECTED) +# define BOOST_NO_CXX23_HDR_EXPECTED +#endif +#if (!__has_include() || !defined(__cpp_lib_flat_map) || (__cpp_lib_flat_map < 202207L)) && !defined(BOOST_NO_CXX23_HDR_FLAT_MAP) +# define BOOST_NO_CXX23_HDR_FLAT_MAP +#endif +#if (!__has_include() || !defined(__cpp_lib_flat_set) || (__cpp_lib_flat_set < 202207L)) && !defined(BOOST_NO_CXX23_HDR_FLAT_SET) +# define BOOST_NO_CXX23_HDR_FLAT_SET +#endif +#if (!__has_include() || !defined(__cpp_lib_generator) || (__cpp_lib_generator < 202207L)) && !defined(BOOST_NO_CXX23_HDR_GENERATOR) +# define BOOST_NO_CXX23_HDR_GENERATOR +#endif +#if (!__has_include() || !defined(__cpp_lib_mdspan) || (__cpp_lib_mdspan < 202207L)) && !defined(BOOST_NO_CXX23_HDR_MDSPAN) +# define BOOST_NO_CXX23_HDR_MDSPAN +#endif +#if (!__has_include() || !defined(__cpp_lib_print) || (__cpp_lib_print < 202207L)) && !defined(BOOST_NO_CXX23_HDR_PRINT) +# define BOOST_NO_CXX23_HDR_PRINT +#endif +#if (!__has_include() || !defined(__cpp_lib_spanstream) || (__cpp_lib_spanstream < 202106L)) && !defined(BOOST_NO_CXX23_HDR_SPANSTREAM) +# define BOOST_NO_CXX23_HDR_SPANSTREAM +#endif +#if (!__has_include() || !defined(__cpp_lib_stacktrace) || (__cpp_lib_stacktrace < 202011L)) && !defined(BOOST_NO_CXX23_HDR_STACKTRACE) +# define BOOST_NO_CXX23_HDR_STACKTRACE +#endif +#if !__has_include() && !defined(BOOST_NO_CXX23_HDR_STDFLOAT) +# define BOOST_NO_CXX23_HDR_STDFLOAT +#endif +#endif + +#if defined(__cplusplus) && defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX20_HDR_VERSION +#else +// For convenience, this is always included: +# include +#endif +#else +# define BOOST_NO_CXX20_HDR_VERSION +#endif + +#if defined(BOOST_MSVC) +#if (BOOST_MSVC < 1914) || (_MSVC_LANG < 201703) +# define BOOST_NO_CXX17_DEDUCTION_GUIDES +#endif +#elif !defined(__cpp_deduction_guides) || (__cpp_deduction_guides < 201606) +# define BOOST_NO_CXX17_DEDUCTION_GUIDES +#endif + +// +// Define composite agregate macros: +// +#include + +// +// Finish off with checks for macros that are depricated / no longer supported, +// if any of these are set then it's very likely that much of Boost will no +// longer work. So stop with a #error for now, but give the user a chance +// to continue at their own risk if they really want to: +// +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_CONFIG_ALLOW_DEPRECATED) +# error "You are using a compiler which lacks features which are now a minimum requirement in order to use Boost, define BOOST_CONFIG_ALLOW_DEPRECATED if you want to continue at your own risk!!!" +#endif + +#endif diff --git a/src/boost/config/header_deprecated.hpp b/src/boost/config/header_deprecated.hpp new file mode 100644 index 00000000..120b4b3a --- /dev/null +++ b/src/boost/config/header_deprecated.hpp @@ -0,0 +1,26 @@ +#ifndef BOOST_CONFIG_HEADER_DEPRECATED_HPP_INCLUDED +#define BOOST_CONFIG_HEADER_DEPRECATED_HPP_INCLUDED + +// Copyright 2017 Peter Dimov. +// +// 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 +// +// BOOST_HEADER_DEPRECATED("") +// +// Expands to the equivalent of +// BOOST_PRAGMA_MESSAGE("This header is deprecated. Use instead.") +// +// Note that this header is C compatible. + +#include + +#if defined(BOOST_ALLOW_DEPRECATED_HEADERS) || defined(BOOST_ALLOW_DEPRECATED) +# define BOOST_HEADER_DEPRECATED(a) +#else +# define BOOST_HEADER_DEPRECATED(a) BOOST_PRAGMA_MESSAGE("This header is deprecated. Use " a " instead.") +#endif + +#endif // BOOST_CONFIG_HEADER_DEPRECATED_HPP_INCLUDED diff --git a/src/boost/config/helper_macros.hpp b/src/boost/config/helper_macros.hpp new file mode 100644 index 00000000..3e79526d --- /dev/null +++ b/src/boost/config/helper_macros.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED +#define BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED + +// Copyright 2001 John Maddock. +// Copyright 2017 Peter Dimov. +// +// 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 +// +// BOOST_STRINGIZE(X) +// BOOST_JOIN(X, Y) +// +// Note that this header is C compatible. + +// +// Helper macro BOOST_STRINGIZE: +// Converts the parameter X to a string after macro replacement +// on X has been performed. +// +#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +#define BOOST_DO_STRINGIZE(X) #X + +// +// Helper macro BOOST_JOIN: +// The following piece of macro magic joins the two +// arguments together, even when one of the arguments is +// itself a macro (see 16.3.1 in C++ standard). The key +// is that macro expansion of macro arguments does not +// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. +// +#define BOOST_JOIN(X, Y) BOOST_DO_JOIN(X, Y) +#define BOOST_DO_JOIN(X, Y) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2(X, Y) X##Y + +#endif // BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED diff --git a/src/boost/config/no_tr1/cmath.hpp b/src/boost/config/no_tr1/cmath.hpp new file mode 100644 index 00000000..d8268d84 --- /dev/null +++ b/src/boost/config/no_tr1/cmath.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2008. +// Use, modification and distribution are 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/cmath is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_CMATH +# define BOOST_CONFIG_CMATH + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_CMATH_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +#endif diff --git a/src/boost/config/no_tr1/complex.hpp b/src/boost/config/no_tr1/complex.hpp new file mode 100644 index 00000000..ca200922 --- /dev/null +++ b/src/boost/config/no_tr1/complex.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/complex is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_COMPLEX +# define BOOST_CONFIG_COMPLEX + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_COMPLEX_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +#endif diff --git a/src/boost/config/no_tr1/functional.hpp b/src/boost/config/no_tr1/functional.hpp new file mode 100644 index 00000000..e395efc1 --- /dev/null +++ b/src/boost/config/no_tr1/functional.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/functional is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_FUNCTIONAL +# define BOOST_CONFIG_FUNCTIONAL + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +#endif diff --git a/src/boost/config/no_tr1/memory.hpp b/src/boost/config/no_tr1/memory.hpp new file mode 100644 index 00000000..2b5d2080 --- /dev/null +++ b/src/boost/config/no_tr1/memory.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/memory is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_MEMORY +# define BOOST_CONFIG_MEMORY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_MEMORY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +#endif diff --git a/src/boost/config/no_tr1/utility.hpp b/src/boost/config/no_tr1/utility.hpp new file mode 100644 index 00000000..dea8f115 --- /dev/null +++ b/src/boost/config/no_tr1/utility.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are 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) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/utility is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_UTILITY +# define BOOST_CONFIG_UTILITY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_UTILITY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +#endif diff --git a/src/boost/config/platform/aix.hpp b/src/boost/config/platform/aix.hpp new file mode 100644 index 00000000..a48e2320 --- /dev/null +++ b/src/boost/config/platform/aix.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are 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 most recent version. + +// IBM/Aix specific config options: + +#define BOOST_PLATFORM "IBM Aix" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME + +// This needs support in "boost/cstdint.hpp" exactly like FreeBSD. +// This platform has header named which includes all +// the things needed. +#define BOOST_HAS_STDINT_H + +// Threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_DELAY_NP +#define BOOST_HAS_SCHED_YIELD +//#define BOOST_HAS_PTHREAD_YIELD + +// boilerplate code: +#include + + + + diff --git a/src/boost/config/platform/amigaos.hpp b/src/boost/config/platform/amigaos.hpp new file mode 100644 index 00000000..34bcf412 --- /dev/null +++ b/src/boost/config/platform/amigaos.hpp @@ -0,0 +1,15 @@ +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are 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 most recent version. + +#define BOOST_PLATFORM "AmigaOS" + +#define BOOST_DISABLE_THREADS +#define BOOST_NO_CWCHAR +#define BOOST_NO_STD_WSTRING +#define BOOST_NO_INTRINSIC_WCHAR_T + + diff --git a/src/boost/config/platform/beos.hpp b/src/boost/config/platform/beos.hpp new file mode 100644 index 00000000..6158c1c2 --- /dev/null +++ b/src/boost/config/platform/beos.hpp @@ -0,0 +1,26 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are 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 most recent version. + +// BeOS specific config options: + +#define BOOST_PLATFORM "BeOS" + +#define BOOST_NO_CWCHAR +#define BOOST_NO_CWCTYPE +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_BETHREADS + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +// boilerplate code: +#include + + + diff --git a/src/boost/config/platform/bsd.hpp b/src/boost/config/platform/bsd.hpp new file mode 100644 index 00000000..ccc7eb05 --- /dev/null +++ b/src/boost/config/platform/bsd.hpp @@ -0,0 +1,83 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Douglas Gregor 2002. +// Use, modification and distribution are 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 most recent version. + +// generic BSD config options: + +#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) +#error "This platform is not BSD" +#endif + +#ifdef __FreeBSD__ +#define BOOST_PLATFORM "FreeBSD " BOOST_STRINGIZE(__FreeBSD__) +#elif defined(__NetBSD__) +#define BOOST_PLATFORM "NetBSD " BOOST_STRINGIZE(__NetBSD__) +#elif defined(__OpenBSD__) +#define BOOST_PLATFORM "OpenBSD " BOOST_STRINGIZE(__OpenBSD__) +#elif defined(__DragonFly__) +#define BOOST_PLATFORM "DragonFly " BOOST_STRINGIZE(__DragonFly__) +#endif + +// +// is this the correct version check? +// FreeBSD has but does not +// advertise the fact in : +// +#if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) \ + || defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_HAS_NL_TYPES_H +#endif + +// +// FreeBSD 3.x has pthreads support, but defines _POSIX_THREADS in +// and not in +// +#if (defined(__FreeBSD__) && (__FreeBSD__ <= 3))\ + || defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_HAS_PTHREADS +#endif + +// +// No wide character support in the BSD header files: +// +#if defined(__NetBSD__) +#define __NetBSD_GCC__ (__GNUC__ * 1000000 \ + + __GNUC_MINOR__ * 1000 \ + + __GNUC_PATCHLEVEL__) +// XXX - the following is required until c++config.h +// defines _GLIBCXX_HAVE_SWPRINTF and friends +// or the preprocessor conditionals are removed +// from the cwchar header. +#define _GLIBCXX_HAVE_SWPRINTF 1 +#endif + +#if !((defined(__FreeBSD__) && (__FreeBSD__ >= 5)) \ + || (defined(__NetBSD_GCC__) && (__NetBSD_GCC__ >= 2095003)) \ + || defined(__OpenBSD__) || defined(__DragonFly__)) +# define BOOST_NO_CWCHAR +#endif +// +// The BSD has macros only, no functions: +// +#if !defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_SIGACTION +#define BOOST_HAS_CLOCK_GETTIME + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include diff --git a/src/boost/config/platform/cloudabi.hpp b/src/boost/config/platform/cloudabi.hpp new file mode 100644 index 00000000..bed7b631 --- /dev/null +++ b/src/boost/config/platform/cloudabi.hpp @@ -0,0 +1,18 @@ +// Copyright Nuxi, https://nuxi.nl/ 2015. +// 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) + +#define BOOST_PLATFORM "CloudABI" + +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_LOG1P +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_SCHED_YIELD diff --git a/src/boost/config/platform/cray.hpp b/src/boost/config/platform/cray.hpp new file mode 100644 index 00000000..103e9c06 --- /dev/null +++ b/src/boost/config/platform/cray.hpp @@ -0,0 +1,18 @@ +// (C) Copyright John Maddock 2011. +// Use, modification and distribution are 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 most recent version. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "Cray" + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/src/boost/config/platform/cygwin.hpp b/src/boost/config/platform/cygwin.hpp new file mode 100644 index 00000000..d0052d8b --- /dev/null +++ b/src/boost/config/platform/cygwin.hpp @@ -0,0 +1,71 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are 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 most recent version. + +// cygwin specific config options: + +#define BOOST_PLATFORM "Cygwin" +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + +// +// Threading API: +// See if we have POSIX threads, if we do use them, otherwise +// revert to native Win threads. +#define BOOST_HAS_UNISTD_H +#include +#if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +//# define BOOST_HAS_SIGACTION +#else +# if !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_WINTHREADS +# endif +# define BOOST_HAS_FTIME +#endif + +// +// find out if we have a stdint.h, there should be a better way to do this: +// +#include +#ifdef _STDINT_H +#define BOOST_HAS_STDINT_H +#endif +#if __GNUC__ > 5 && !defined(BOOST_HAS_STDINT_H) +# define BOOST_HAS_STDINT_H +#endif + +#include +#if (CYGWIN_VERSION_API_MAJOR == 0 && CYGWIN_VERSION_API_MINOR < 231) +/// Cygwin has no fenv.h +#define BOOST_NO_FENV_H +#endif + +// Cygwin has it's own which breaks unless the correct compiler flags are used: +#ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +#include +#if !(__XSI_VISIBLE >= 500 || __POSIX_VISIBLE >= 200112) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#endif + +// boilerplate code: +#include + +// +// Cygwin lies about XSI conformance, there is no nl_types.h: +// +#ifdef BOOST_HAS_NL_TYPES_H +# undef BOOST_HAS_NL_TYPES_H +#endif + + + + diff --git a/src/boost/config/platform/haiku.hpp b/src/boost/config/platform/haiku.hpp new file mode 100644 index 00000000..04244c56 --- /dev/null +++ b/src/boost/config/platform/haiku.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jessica Hamilton 2014. +// Use, modification and distribution are 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 most recent version. + +// Haiku specific config options: + +#define BOOST_PLATFORM "Haiku" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_STDINT_H + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +#define BOOST_NO_CXX11_HDR_TYPE_TRAITS +#define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_VARIADIC_MACROS + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#include diff --git a/src/boost/config/platform/hpux.hpp b/src/boost/config/platform/hpux.hpp new file mode 100644 index 00000000..222622e7 --- /dev/null +++ b/src/boost/config/platform/hpux.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are 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 most recent version. + +// hpux specific config options: + +#define BOOST_PLATFORM "HP-UX" + +// In principle, HP-UX has a nice under the name +// However, it has the following problem: +// Use of UINT32_C(0) results in "0u l" for the preprocessed source +// (verifyable with gcc 2.95.3) +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__HP_aCC) +# define BOOST_HAS_STDINT_H +#endif + +#if !(defined(__HP_aCC) || !defined(_INCLUDE__STDC_A1_SOURCE)) +# define BOOST_NO_SWPRINTF +#endif +#if defined(__HP_aCC) && !defined(_INCLUDE__STDC_A1_SOURCE) +# define BOOST_NO_CWCTYPE +#endif + +#if defined(__GNUC__) +# if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3)) + // GNU C on HP-UX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +# elif !defined(BOOST_DISABLE_THREADS) + // threads supported from gcc-3.3 onwards: +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# endif +#elif defined(__HP_aCC) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_HAS_PTHREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// the following are always available: +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +#endif +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#endif +#ifndef BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NL_TYPES_H +#endif +#ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +#endif +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +#endif +#ifndef BOOST_HAS_CLOCK_GETTIME +# define BOOST_HAS_CLOCK_GETTIME +#endif +#ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +#endif +#ifndef BOOST_HAS_NRVO +# ifndef __parisc +# define BOOST_HAS_NRVO +# endif +#endif +#ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +#endif +#ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +#endif + diff --git a/src/boost/config/platform/irix.hpp b/src/boost/config/platform/irix.hpp new file mode 100644 index 00000000..0acb6515 --- /dev/null +++ b/src/boost/config/platform/irix.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are 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 most recent version. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "SGI Irix" + +#define BOOST_NO_SWPRINTF +// +// these are not auto detected by POSIX feature tests: +// +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#ifdef __GNUC__ + // GNU C on IRIX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/src/boost/config/platform/linux.hpp b/src/boost/config/platform/linux.hpp new file mode 100644 index 00000000..c4eef8f8 --- /dev/null +++ b/src/boost/config/platform/linux.hpp @@ -0,0 +1,106 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are 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 most recent version. + +// linux specific config options: + +#define BOOST_PLATFORM "linux" + +// make sure we have __GLIBC_PREREQ if available at all +#ifdef __cplusplus +#include +#else +#include +#endif + +// +// added to glibc 2.1.1 +// We can only test for 2.1 though: +// +#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) + // defines int64_t unconditionally, but defines + // int64_t only if __GNUC__. Thus, assume a fully usable + // only when using GCC. Update 2017: this appears not to be the case for + // recent glibc releases, see bug report: https://svn.boost.org/trac/boost/ticket/13045 +# if defined(__GNUC__) || ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 5))) +# define BOOST_HAS_STDINT_H +# endif +#endif + +#if defined(__LIBCOMO__) + // + // como on linux doesn't have std:: c functions: + // NOTE: versions of libcomo prior to beta28 have octal version numbering, + // e.g. version 25 is 21 (dec) + // +# if __LIBCOMO_VERSION__ <= 20 +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if __LIBCOMO_VERSION__ <= 21 +# define BOOST_NO_SWPRINTF +# endif + +#endif + +// +// If glibc is past version 2 then we definitely have +// gettimeofday, earlier versions may or may not have it: +// +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#ifdef __USE_POSIX199309 +# define BOOST_HAS_NANOSLEEP +#endif + +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +// __GLIBC_PREREQ is available since 2.1.2 + + // swprintf is available since glibc 2.2.0 +# if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98)) +# define BOOST_NO_SWPRINTF +# endif +#else +# define BOOST_NO_SWPRINTF +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include +#if defined(__USE_GNU) && !defined(__ANDROID__) && !defined(ANDROID) +#define BOOST_HAS_PTHREAD_YIELD +#endif + +#ifndef __GNUC__ +// +// if the compiler is not gcc we still need to be able to parse +// the GNU system headers, some of which (mainly ) +// use GNU specific extensions: +// +# ifndef __extension__ +# define __extension__ +# endif +# ifndef __const__ +# define __const__ const +# endif +# ifndef __volatile__ +# define __volatile__ volatile +# endif +# ifndef __signed__ +# define __signed__ signed +# endif +# ifndef __typeof__ +# define __typeof__ typeof +# endif +# ifndef __inline__ +# define __inline__ inline +# endif +#endif + + diff --git a/src/boost/config/platform/macos.hpp b/src/boost/config/platform/macos.hpp new file mode 100644 index 00000000..ed7dc15f --- /dev/null +++ b/src/boost/config/platform/macos.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Bill Kempf 2002. +// Use, modification and distribution are 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 most recent version. + +// Mac OS specific config options: + +#define BOOST_PLATFORM "Mac OS" + +#if __MACH__ && !defined(_MSL_USING_MSL_C) + +// Using the Mac OS X system BSD-style C library. + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif +// +// Begin by including our boilerplate code for POSIX +// feature detection, this is safe even when using +// the MSL as Metrowerks supply their own +// to replace the platform-native BSD one. G++ users +// should also always be able to do this on MaxOS X. +// +# include +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif + +// +// BSD runtime has pthreads, sigaction, sched_yield and gettimeofday, +// of these only pthreads are advertised in , so set the +// other options explicitly: +// +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_SIGACTION + +# if (__GNUC__ < 3) && !defined( __APPLE_CC__) + +// GCC strange "ignore std" mode works better if you pretend everything +// is in the std namespace, for the most part. + +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if (__GNUC__ >= 4) + +// Both gcc and intel require these. +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_NANOSLEEP + +# endif + +#else + +// Using the MSL C library. + +// We will eventually support threads in non-Carbon builds, but we do +// not support this yet. +# if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON ) + +# if !defined(BOOST_HAS_PTHREADS) +// MPTasks support is deprecated/removed from Boost: +//# define BOOST_HAS_MPTASKS +# elif ( __dest_os == __mac_os_x ) +// We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the +// gettimeofday and no posix. +# define BOOST_HAS_GETTIMEOFDAY +# endif + +#ifdef BOOST_HAS_PTHREADS +# define BOOST_HAS_THREADS +#endif + +// The remote call manager depends on this. +# define BOOST_BIND_ENABLE_PASCAL + +# endif + +#endif + + + diff --git a/src/boost/config/platform/qnxnto.hpp b/src/boost/config/platform/qnxnto.hpp new file mode 100644 index 00000000..d0298cb4 --- /dev/null +++ b/src/boost/config/platform/qnxnto.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jim Douglas 2005. +// Use, modification and distribution are 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 most recent version. + +// QNX specific config options: + +#define BOOST_PLATFORM "QNX" + +#define BOOST_HAS_UNISTD_H +#include + +// QNX claims XOpen version 5 compatibility, but doesn't have an nl_types.h +// or log1p and expm1: +#undef BOOST_HAS_NL_TYPES_H +#undef BOOST_HAS_LOG1P +#undef BOOST_HAS_EXPM1 + +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_NANOSLEEP + + + + + diff --git a/src/boost/config/platform/solaris.hpp b/src/boost/config/platform/solaris.hpp new file mode 100644 index 00000000..51ffe67f --- /dev/null +++ b/src/boost/config/platform/solaris.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are 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 most recent version. + +// sun specific config options: + +#define BOOST_PLATFORM "Sun Solaris" + +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// +// pthreads don't actually work with gcc unless _PTHREADS is defined: +// +#if defined(__GNUC__) && defined(_POSIX_THREADS) && !defined(_PTHREADS) +# undef BOOST_HAS_PTHREADS +#endif + +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + + diff --git a/src/boost/config/platform/symbian.hpp b/src/boost/config/platform/symbian.hpp new file mode 100644 index 00000000..f814d00b --- /dev/null +++ b/src/boost/config/platform/symbian.hpp @@ -0,0 +1,97 @@ +// (C) Copyright Yuriy Krasnoschek 2009. +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are 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 most recent version. + +// symbian specific config options: + + +#define BOOST_PLATFORM "Symbian" +#define BOOST_SYMBIAN 1 + + +#if defined(__S60_3X__) +// Open C / C++ plugin was introdused in this SDK, earlier versions don't have CRT / STL +# define BOOST_S60_3rd_EDITION_FP2_OR_LATER_SDK +// make sure we have __GLIBC_PREREQ if available at all +#ifdef __cplusplus +#include +#else +#include +#endif// boilerplate code: +# define BOOST_HAS_UNISTD_H +# include +// S60 SDK defines _POSIX_VERSION as POSIX.1 +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif +# ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +# endif +# ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +# endif +# ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +# endif +# ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREADS +# endif +# ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +# endif +# ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +# endif +# ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# ifndef BOOST_POSIX_API +# define BOOST_POSIX_API +# endif +// endianess support +# include +// Symbian SDK provides _BYTE_ORDER instead of __BYTE_ORDER +# ifndef __LITTLE_ENDIAN +# ifdef _LITTLE_ENDIAN +# define __LITTLE_ENDIAN _LITTLE_ENDIAN +# else +# define __LITTLE_ENDIAN 1234 +# endif +# endif +# ifndef __BIG_ENDIAN +# ifdef _BIG_ENDIAN +# define __BIG_ENDIAN _BIG_ENDIAN +# else +# define __BIG_ENDIAN 4321 +# endif +# endif +# ifndef __BYTE_ORDER +# define __BYTE_ORDER __LITTLE_ENDIAN // Symbian is LE +# endif +// Known limitations +# define BOOST_ASIO_DISABLE_SERIAL_PORT +# define BOOST_DATE_TIME_NO_LOCALE +# define BOOST_NO_STD_WSTRING +# define BOOST_EXCEPTION_DISABLE +# define BOOST_NO_EXCEPTIONS + +#else // TODO: More platform support e.g. UIQ +# error "Unsuppoted Symbian SDK" +#endif + +#if defined(__WINSCW__) && !defined(BOOST_DISABLE_WIN32) +# define BOOST_DISABLE_WIN32 // winscw defines WIN32 macro +#endif + + diff --git a/src/boost/config/platform/vms.hpp b/src/boost/config/platform/vms.hpp new file mode 100644 index 00000000..f70efcfb --- /dev/null +++ b/src/boost/config/platform/vms.hpp @@ -0,0 +1,25 @@ +// (C) Copyright Artyom Beilis 2010. +// Use, modification and distribution are 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) + +#ifndef BOOST_CONFIG_PLATFORM_VMS_HPP +#define BOOST_CONFIG_PLATFORM_VMS_HPP + +#define BOOST_PLATFORM "OpenVMS" + +#undef BOOST_HAS_STDINT_H +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_THREADS +#undef BOOST_HAS_SCHED_YIELD + +#endif diff --git a/src/boost/config/platform/vxworks.hpp b/src/boost/config/platform/vxworks.hpp new file mode 100644 index 00000000..0564b944 --- /dev/null +++ b/src/boost/config/platform/vxworks.hpp @@ -0,0 +1,422 @@ +// (C) Copyright Dustin Spicuzza 2009. +// Adapted to vxWorks 6.9 by Peter Brockamp 2012. +// Updated for VxWorks 7 by Brian Kuhl 2016 +// Use, modification and distribution are 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 most recent version. + +// Old versions of vxWorks (namely everything below 6.x) are +// absolutely unable to use boost. Old STLs and compilers +// like (GCC 2.96) . Do not even think of getting this to work, +// a miserable failure will be guaranteed! +// +// VxWorks supports C++ linkage in the kernel with +// DKMs (Downloadable Kernel Modules). But, until recently +// the kernel used a C89 library with no +// wide character support and no guarantee of ANSI C. +// Regardless of the C library the same Dinkum +// STL library is used in both contexts. +// +// Similarly the Dinkum abridged STL that supports the loosely specified +// embedded C++ standard has not been tested and is unlikely to work +// on anything but the simplest library. +// ==================================================================== +// +// Some important information regarding the usage of POSIX semaphores: +// ------------------------------------------------------------------- +// +// VxWorks as a real time operating system handles threads somewhat +// different from what "normal" OSes do, regarding their scheduling! +// This could lead to a scenario called "priority inversion" when using +// semaphores, see http://en.wikipedia.org/wiki/Priority_inversion. +// +// Now, VxWorks POSIX-semaphores for DKM's default to the usage of +// priority inverting semaphores, which is fine. On the other hand, +// for RTP's it defaults to using non priority inverting semaphores, +// which could easily pose a serious problem for a real time process. +// +// To change the default properties for POSIX-semaphores in VxWorks 7 +// enable core > CORE_USER Menu > DEFAULT_PTHREAD_PRIO_INHERIT +// +// In VxWorks 6.x so as to integrate with boost. +// - Edit the file +// installDir/vxworks-6.x/target/usr/src/posix/pthreadLib.c +// - Around line 917 there should be the definition of the default +// mutex attributes: +// +// LOCAL pthread_mutexattr_t defaultMutexAttr = +// { +// PTHREAD_INITIALIZED_OBJ, PTHREAD_PRIO_NONE, 0, +// PTHREAD_MUTEX_DEFAULT +// }; +// +// Here, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. +// - Around line 1236 there should be a definition for the function +// pthread_mutexattr_init(). A couple of lines below you should +// find a block of code like this: +// +// pAttr->mutexAttrStatus = PTHREAD_INITIALIZED_OBJ; +// pAttr->mutexAttrProtocol = PTHREAD_PRIO_NONE; +// pAttr->mutexAttrPrioceiling = 0; +// pAttr->mutexAttrType = PTHREAD_MUTEX_DEFAULT; +// +// Here again, replace PTHREAD_PRIO_NONE by PTHREAD_PRIO_INHERIT. +// - Finally, rebuild your VSB. This will rebuild the libraries +// with the changed properties. That's it! Now, using boost should +// no longer cause any problems with task deadlocks! +// +// ==================================================================== + +// Block out all versions before vxWorks 6.x, as these don't work: +// Include header with the vxWorks version information and query them +#include +#if !defined(_WRS_VXWORKS_MAJOR) || (_WRS_VXWORKS_MAJOR < 6) +# error "The vxWorks version you're using is so badly outdated,\ + it doesn't work at all with boost, sorry, no chance!" +#endif + +// Handle versions above 5.X but below 6.9 +#if (_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR < 9) +// TODO: Starting from what version does vxWorks work with boost? +// We can't reasonably insert a #warning "" as a user hint here, +// as this will show up with every file including some boost header, +// badly bugging the user... So for the time being we just leave it. +#endif + +// vxWorks specific config options: +// -------------------------------- +#define BOOST_PLATFORM "vxWorks" + + +// Generally available headers: +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_DIRENT_H +//#define BOOST_HAS_SLIST + +// vxWorks does not have installed an iconv-library by default, +// so unfortunately no Unicode support from scratch is available! +// Thus, instead it is suggested to switch to ICU, as this seems +// to be the most complete and portable option... +#ifndef BOOST_LOCALE_WITH_ICU + #define BOOST_LOCALE_WITH_ICU +#endif + +// Generally available functionality: +#define BOOST_HAS_THREADS +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_MACRO_USE_FACET + +// Generally available threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_SIGACTION + +// Functionality available for RTPs only: +#ifdef __RTP__ +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_LOG1P +# define BOOST_HAS_EXPM1 +#endif + +// Functionality available for DKMs only: +#ifdef _WRS_KERNEL + // Luckily, at the moment there seems to be none! +#endif + +// These #defines allow detail/posix_features to work, since vxWorks doesn't +// #define them itself for DKMs (for RTPs on the contrary it does): +#ifdef _WRS_KERNEL +# ifndef _POSIX_TIMERS +# define _POSIX_TIMERS 1 +# endif +# ifndef _POSIX_THREADS +# define _POSIX_THREADS 1 +# endif +// no sysconf( _SC_PAGESIZE) in kernel +# define BOOST_THREAD_USES_GETPAGESIZE +#endif + +#if (_WRS_VXWORKS_MAJOR < 7) +// vxWorks-around: #defines CLOCKS_PER_SEC as sysClkRateGet() but +// miserably fails to #include the required to make +// sysClkRateGet() available! So we manually include it here. +# ifdef __RTP__ +# include +# include +# endif + +// vxWorks-around: In the macros INT32_C(), UINT32_C(), INT64_C() and +// UINT64_C() are defined erroneously, yielding not a signed/ +// unsigned long/long long type, but a signed/unsigned int/long +// type. Eventually this leads to compile errors in ratio_fwd.hpp, +// when trying to define several constants which do not fit into a +// long type! We correct them here by redefining. + +# include + +// Special behaviour for DKMs: + +// Some macro-magic to do the job +# define VX_JOIN(X, Y) VX_DO_JOIN(X, Y) +# define VX_DO_JOIN(X, Y) VX_DO_JOIN2(X, Y) +# define VX_DO_JOIN2(X, Y) X##Y + +// Correctly setup the macros +# undef INT32_C +# undef UINT32_C +# undef INT64_C +# undef UINT64_C +# define INT32_C(x) VX_JOIN(x, L) +# define UINT32_C(x) VX_JOIN(x, UL) +# define INT64_C(x) VX_JOIN(x, LL) +# define UINT64_C(x) VX_JOIN(x, ULL) + +// #include Libraries required for the following function adaption +# include +#endif // _WRS_VXWORKS_MAJOR < 7 + +#include +#include + +#if defined(_WRS_KERNEL) && (_CPPLIB_VER < 700) + // recent kernels use Dinkum clib v7.00+ + // with widechar but older kernels + // do not have the -header, + // but apparently they do have an intrinsic wchar_t meanwhile! +# define BOOST_NO_CWCHAR + + // Lots of wide-functions and -headers are unavailable for DKMs as well: +# define BOOST_NO_CWCTYPE +# define BOOST_NO_SWPRINTF +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + + +// Use C-linkage for the following helper functions +#ifdef __cplusplus +extern "C" { +#endif + +// vxWorks-around: The required functions getrlimit() and getrlimit() are missing. +// But we have the similar functions getprlimit() and setprlimit(), +// which may serve the purpose. +// Problem: The vxWorks-documentation regarding these functions +// doesn't deserve its name! It isn't documented what the first two +// parameters idtype and id mean, so we must fall back to an educated +// guess - null, argh... :-/ + +// TODO: getprlimit() and setprlimit() do exist for RTPs only, for whatever reason. +// Thus for DKMs there would have to be another implementation. +#if defined ( __RTP__) && (_WRS_VXWORKS_MAJOR < 7) + inline int getrlimit(int resource, struct rlimit *rlp){ + return getprlimit(0, 0, resource, rlp); + } + + inline int setrlimit(int resource, const struct rlimit *rlp){ + return setprlimit(0, 0, resource, const_cast(rlp)); + } +#endif + +// vxWorks has ftruncate() only, so we do simulate truncate(): +inline int truncate(const char *p, off_t l){ + int fd = open(p, O_WRONLY); + if (fd == -1){ + errno = EACCES; + return -1; + } + if (ftruncate(fd, l) == -1){ + close(fd); + errno = EACCES; + return -1; + } + return close(fd); +} + +#ifdef __GNUC__ +# define ___unused __attribute__((unused)) +#else +# define ___unused +#endif + +// Fake symlink handling by dummy functions: +inline int symlink(const char* path1 ___unused, const char* path2 ___unused){ + // vxWorks has no symlinks -> always return an error! + errno = EACCES; + return -1; +} + +inline ssize_t readlink(const char* path1 ___unused, char* path2 ___unused, size_t size ___unused){ + // vxWorks has no symlinks -> always return an error! + errno = EACCES; + return -1; +} + +#if (_WRS_VXWORKS_MAJOR < 7) + +inline int gettimeofday(struct timeval *tv, void * /*tzv*/) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + return 0; +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +/* + * moved to os/utils/unix/freind_h/times.h in VxWorks 7 + * to avoid conflict with MPL operator times + */ +#if (_WRS_VXWORKS_MAJOR < 7) +# ifdef __cplusplus + +// vxWorks provides neither struct tms nor function times()! +// We implement an empty dummy-function, simply setting the user +// and system time to the half of thew actual system ticks-value +// and the child user and system time to 0. +// Rather ugly but at least it suppresses compiler errors... +// Unfortunately, this of course *does* have an severe impact on +// dependant libraries, actually this is chrono only! Here it will +// not be possible to correctly use user and system times! But +// as vxWorks is lacking the ability to calculate user and system +// process times there seems to be no other possible solution. +struct tms{ + clock_t tms_utime; // User CPU time + clock_t tms_stime; // System CPU time + clock_t tms_cutime; // User CPU time of terminated child processes + clock_t tms_cstime; // System CPU time of terminated child processes +}; + + + inline clock_t times(struct tms *t){ + struct timespec ts; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); + clock_t ticks(static_cast(static_cast(ts.tv_sec) * CLOCKS_PER_SEC + + static_cast(ts.tv_nsec) * CLOCKS_PER_SEC / 1000000.0)); + t->tms_utime = ticks/2U; + t->tms_stime = ticks/2U; + t->tms_cutime = 0; // vxWorks is lacking the concept of a child process! + t->tms_cstime = 0; // -> Set the wait times for childs to 0 + return ticks; +} + + +namespace std { + using ::times; +} +# endif // __cplusplus +#endif // _WRS_VXWORKS_MAJOR < 7 + + +#ifdef __cplusplus +extern "C" void bzero (void *, size_t); // FD_ZERO uses bzero() but doesn't include strings.h + +// Put the selfmade functions into the std-namespace, just in case +namespace std { +# ifdef __RTP__ + using ::getrlimit; + using ::setrlimit; +# endif + using ::truncate; + using ::symlink; + using ::readlink; +# if (_WRS_VXWORKS_MAJOR < 7) + using ::gettimeofday; +# endif +} +#endif // __cplusplus + +// Some more macro-magic: +// vxWorks-around: Some functions are not present or broken in vxWorks +// but may be patched to life via helper macros... + +// Include signal.h which might contain a typo to be corrected here +#include + +#if (_WRS_VXWORKS_MAJOR < 7) +# define getpagesize() sysconf(_SC_PAGESIZE) // getpagesize is deprecated anyway! +inline int lstat(p, b) { return stat(p, b); } // lstat() == stat(), as vxWorks has no symlinks! +#endif + +#ifndef S_ISSOCK +# define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) // Is file a socket? +#endif +#ifndef FPE_FLTINV +# define FPE_FLTINV (FPE_FLTSUB+1) // vxWorks has no FPE_FLTINV, so define one as a dummy +#endif +#if !defined(BUS_ADRALN) && defined(BUS_ADRALNR) +# define BUS_ADRALN BUS_ADRALNR // Correct a supposed typo in vxWorks' +#endif +typedef int locale_t; // locale_t is a POSIX-extension, currently not present in vxWorks! + +// #include boilerplate code: +#include + +// vxWorks lies about XSI conformance, there is no nl_types.h: +#undef BOOST_HAS_NL_TYPES_H + +// vxWorks 7 adds C++11 support +// however it is optional, and does not match exactly the support determined +// by examining the Dinkum STL version and GCC version (or ICC and DCC) +#if !( defined( _WRS_CONFIG_LANG_LIB_CPLUS_CPLUS_USER_2011) || defined(_WRS_CONFIG_LIBCPLUS_STD)) +# define BOOST_NO_CXX11_ADDRESSOF // C11 addressof operator on memory location +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_NUMERIC_LIMITS // max_digits10 in test/../print_helper.hpp +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_STD_ALIGN + + +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST //serialization/test/test_list.cpp +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM //math/../test_data.hpp +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +#else +# ifndef BOOST_SYSTEM_NO_DEPRECATED +# define BOOST_SYSTEM_NO_DEPRECATED // workaround link error in spirit +# endif +#endif + + +// NONE is used in enums in lamda and other libraries +#undef NONE +// restrict is an iostreams class +#undef restrict +// affects some typeof tests +#undef V7 + +// use fake poll() from Unix layer in ASIO to get full functionality +// most libraries will use select() but this define allows 'iostream' functionality +// which is based on poll() only +#if (_WRS_VXWORKS_MAJOR > 6) +# ifndef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR +# define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR +# endif +#else +# define BOOST_ASIO_DISABLE_SERIAL_PORT +#endif + diff --git a/src/boost/config/platform/wasm.hpp b/src/boost/config/platform/wasm.hpp new file mode 100644 index 00000000..682b8485 --- /dev/null +++ b/src/boost/config/platform/wasm.hpp @@ -0,0 +1,23 @@ +// (C) Copyright John Maddock 2020. +// Use, modification and distribution are 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 most recent version. + +// WASM specific config options: + +#define BOOST_PLATFORM "Wasm" + +#ifdef __has_include +#if __has_include() +# define BOOST_HAS_UNISTD_H +#endif +#endif + +// boilerplate code: +#include +// +// fenv lacks the C++11 macros: +// +#define BOOST_NO_FENV_H diff --git a/src/boost/config/platform/win32.hpp b/src/boost/config/platform/win32.hpp new file mode 100644 index 00000000..450158fb --- /dev/null +++ b/src/boost/config/platform/win32.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Bill Kempf 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Rene Rivera 2005. +// Use, modification and distribution are 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 most recent version. + +// Win32 specific config options: + +#define BOOST_PLATFORM "Win32" + +// Get the information about the MinGW runtime, i.e. __MINGW32_*VERSION. +#if defined(__MINGW32__) +# include <_mingw.h> +#endif + +#if defined(__GNUC__) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +#endif + +// Default defines for BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT +// If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport), +// its boost/config/compiler/ file must define BOOST_SYMBOL_EXPORT and +// BOOST_SYMBOL_IMPORT +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __declspec(dllexport) +# define BOOST_SYMBOL_IMPORT __declspec(dllimport) +#endif + +#if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) +# define BOOST_HAS_STDINT_H +# ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS +# endif +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_UNISTD_H +#endif + +#if defined(__MINGW32__) && (__GNUC__ >= 4) +// Mingw has these functions but there are persistent problems +// with calls to these crashing, so disable for now: +//# define BOOST_HAS_EXPM1 +//# define BOOST_HAS_LOG1P +# define BOOST_HAS_GETTIMEOFDAY +#endif +// +// Win32 will normally be using native Win32 threads, +// but there is a pthread library avaliable as an option, +// we used to disable this when BOOST_DISABLE_WIN32 was +// defined but no longer - this should allow some +// files to be compiled in strict mode - while maintaining +// a consistent setting of BOOST_HAS_THREADS across +// all translation units (needed for shared_ptr etc). +// + +#ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_WINTHREADS +#endif + +// +// WinCE configuration: +// +#if defined(_WIN32_WCE) || defined(UNDER_CE) +# define BOOST_NO_ANSI_APIS +// Windows CE does not have a conforming signature for swprintf +# define BOOST_NO_SWPRINTF +#else +# define BOOST_HAS_GETSYSTEMTIMEASFILETIME +# define BOOST_HAS_THREADEX +# define BOOST_HAS_GETSYSTEMTIMEASFILETIME +#endif + +// +// Windows Runtime +// +#if defined(WINAPI_FAMILY) && \ + (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +# define BOOST_NO_ANSI_APIS +#endif + +#ifndef BOOST_DISABLE_WIN32 +// WEK: Added +#define BOOST_HAS_FTIME +#define BOOST_WINDOWS 1 + +#endif diff --git a/src/boost/config/platform/zos.hpp b/src/boost/config/platform/zos.hpp new file mode 100644 index 00000000..fa77999e --- /dev/null +++ b/src/boost/config/platform/zos.hpp @@ -0,0 +1,32 @@ +// Copyright (c) 2017 Dynatrace +// +// 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 + +// See http://www.boost.org for most recent version. + +// Platform setup for IBM z/OS. + +#define BOOST_PLATFORM "IBM z/OS" + +#include // For __UU, __C99, __TR1, ... + +#if defined(__UU) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#if defined(_OPEN_THREADS) || defined(__SUSV3_THR) +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_THREADS +#endif + +#if defined(__SUSV3) || defined(__SUSV3_THR) +# define BOOST_HAS_SCHED_YIELD +#endif + +#define BOOST_HAS_SIGACTION +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_NL_TYPES_H diff --git a/src/boost/config/pragma_message.hpp b/src/boost/config/pragma_message.hpp new file mode 100644 index 00000000..b2c5ff2e --- /dev/null +++ b/src/boost/config/pragma_message.hpp @@ -0,0 +1,31 @@ +#ifndef BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED +#define BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED + +// Copyright 2017 Peter Dimov. +// +// 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 +// +// BOOST_PRAGMA_MESSAGE("message") +// +// Expands to the equivalent of #pragma message("message") +// +// Note that this header is C compatible. + +#include + +#if defined(BOOST_DISABLE_PRAGMA_MESSAGE) +# define BOOST_PRAGMA_MESSAGE(x) +#elif defined(__INTEL_COMPILER) +# define BOOST_PRAGMA_MESSAGE(x) __pragma(message(__FILE__ "(" BOOST_STRINGIZE(__LINE__) "): note: " x)) +#elif defined(__GNUC__) +# define BOOST_PRAGMA_MESSAGE(x) _Pragma(BOOST_STRINGIZE(message(x))) +#elif defined(_MSC_VER) +# define BOOST_PRAGMA_MESSAGE(x) __pragma(message(__FILE__ "(" BOOST_STRINGIZE(__LINE__) "): note: " x)) +#else +# define BOOST_PRAGMA_MESSAGE(x) +#endif + +#endif // BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED diff --git a/src/boost/config/requires_threads.hpp b/src/boost/config/requires_threads.hpp new file mode 100644 index 00000000..c23a2ce3 --- /dev/null +++ b/src/boost/config/requires_threads.hpp @@ -0,0 +1,92 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are 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) + + +#ifndef BOOST_CONFIG_REQUIRES_THREADS_HPP +#define BOOST_CONFIG_REQUIRES_THREADS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_DISABLE_THREADS) + +// +// special case to handle versions of gcc which don't currently support threads: +// +#if defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC_MINOR__ <= 3) || !defined(BOOST_STRICT_CONFIG)) +// +// this is checked up to gcc 3.3: +// +#if defined(__sgi) || defined(__hpux) +# error "Multi-threaded programs are not supported by gcc on HPUX or Irix (last checked with gcc 3.3)" +#endif + +#endif + +# error "Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS" + +#elif !defined(BOOST_HAS_THREADS) + +# if defined __COMO__ +// Comeau C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_MT (Windows) or -D_REENTRANT (Unix)" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +#ifdef _WIN32 +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" +#else +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -openmp" +#endif + +# elif defined __GNUC__ +// GNU C++: +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" + +#elif defined __sgi +// SGI MIPSpro C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_SGI_MP_SOURCE" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread" + +#elif defined BOOST_BORLANDC +// Borland +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -tWM" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either -runtime sm, -runtime smd, -runtime dm, or -runtime dmd" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined __HP_aCC +// HP aCC +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined(__IBMCPP__) +// IBM Visual Age +# error "Compiler threading support is not turned on. Please compile the code with the xlC_r compiler" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" + +#else + +# error "Compiler threading support is not turned on. Please consult your compiler's documentation for the appropriate options to use" + +#endif // compilers + +#endif // BOOST_HAS_THREADS + +#endif // BOOST_CONFIG_REQUIRES_THREADS_HPP diff --git a/src/boost/config/stdlib/dinkumware.hpp b/src/boost/config/stdlib/dinkumware.hpp new file mode 100644 index 00000000..46ffe093 --- /dev/null +++ b/src/boost/config/stdlib/dinkumware.hpp @@ -0,0 +1,324 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Guillaume Melquiond 2003. +// Use, modification and distribution are 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 most recent version. + +// Dinkumware standard library config: + +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#error This is not the Dinkumware lib! +#endif +#endif + + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 306) + // full dinkumware 3.06 and above + // fully conforming provided the compiler supports it: +# if !(defined(_GLOBAL_USING) && (_GLOBAL_USING+0 > 0)) && !defined(BOOST_BORLANDC) && !defined(_STD) && !(defined(__ICC) && (__ICC >= 700)) // can be defined in yvals.h +# define BOOST_NO_STDC_NAMESPACE +# endif +# if !(defined(_HAS_MEMBER_TEMPLATES_REBIND) && (_HAS_MEMBER_TEMPLATES_REBIND+0 > 0)) && !(defined(_MSC_VER) && (_MSC_VER > 1300)) && defined(BOOST_MSVC) +# define BOOST_NO_STD_ALLOCATOR +# endif +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + // if this lib version is set up for vc6 then there is no std::use_facet: +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET + // C lib functions aren't in namespace std either: +# define BOOST_NO_STDC_NAMESPACE + // and nor is +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +// There's no numeric_limits support unless _LONGLONG is defined: +# if !defined(_LONGLONG) && (_CPPLIB_VER <= 310) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +// 3.06 appears to have (non-sgi versions of) & , +// and no at all +#else +# define BOOST_MSVC_STD_ITERATOR 1 +# define BOOST_NO_STD_ITERATOR +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_STD_USE_FACET +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +# define BOOST_HAS_MACRO_USE_FACET +# ifndef _CPPLIB_VER + // Updated Dinkum library defines this, and provides + // its own min and max definitions, as does MTA version. +# ifndef __MTA__ +# define BOOST_NO_STD_MIN_MAX +# endif +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +#endif + +// +// std extension namespace is stdext for vc7.1 and later, +// the same applies to other compilers that sit on top +// of vc7.1 (Intel and Comeau): +// +#if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(BOOST_BORLANDC) +# define BOOST_STD_EXTENSION_NAMESPACE stdext +#endif + + +#if (defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(BOOST_BORLANDC)) || !defined(_CPPLIB_VER) || (_CPPLIB_VER < 306) + // if we're using a dinkum lib that's + // been configured for VC6/7 then there is + // no iterator traits (true even for icl) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +#if defined(__ICL) && (__ICL < 800) && defined(_CPPLIB_VER) && (_CPPLIB_VER <= 310) +// Intel C++ chokes over any non-trivial use of +// this may be an overly restrictive define, but regex fails without it: +# define BOOST_NO_STD_LOCALE +#endif + +#if ((defined(BOOST_MSVC) && BOOST_MSVC >= 1400) || (defined(__clang__) && defined(_MSC_VER))) && (_MSC_VER < 1800) +// Fix for VC++ 8.0 on up ( I do not have a previous version to test ) +// or clang-cl. If exceptions are off you must manually include the +// header before including the header. Admittedly +// trying to use Boost libraries or the standard C++ libraries without +// exception support is not suggested but currently clang-cl ( v 3.4 ) +// does not support exceptions and must be compiled with exceptions off. +#if !_HAS_EXCEPTIONS +#include +#endif +#include +#if !_HAS_EXCEPTIONS +# define BOOST_NO_STD_TYPEINFO +#endif +#endif +#if defined(__ghs__) && !_HAS_NAMESPACE +# define BOOST_NO_STD_TYPEINFO +#endif + +// C++0x headers implemented in 520 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 520 +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_SMART_PTR +#endif + +#if ((!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE)) \ + && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 610) +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +// C++0x headers implemented in 540 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 540 +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_EXCEPTION +#endif + +// C++0x headers implemented in 610 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 610 +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ALLOCATOR +// 540 has std::align but it is not a conforming implementation +# define BOOST_NO_CXX11_STD_ALIGN +#endif + +// Before 650 std::pointer_traits has a broken rebind template +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 650 +# define BOOST_NO_CXX11_POINTER_TRAITS +#elif defined(BOOST_MSVC) && BOOST_MSVC < 1910 +# define BOOST_NO_CXX11_POINTER_TRAITS +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif (__cplusplus < 201402) && !defined(_MSC_VER) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// C++17 features +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) \ + || ((!defined(BOOST_MSVC) || (BOOST_MSVC < 1910))) && (!defined(__clang__) || !defined(_MSC_VER) || (_MSC_VER < 1929))\ + || !defined(_HAS_CXX17) || (_HAS_CXX17 == 0) +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_ITERATOR_TRAITS +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_VARIANT +# define BOOST_NO_CXX17_HDR_ANY +# define BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +# define BOOST_NO_CXX17_HDR_CHARCONV +# define BOOST_NO_CXX17_HDR_EXECUTION +# define BOOST_NO_CXX17_HDR_FILESYSTEM +#endif +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) || !defined(_HAS_CXX17) || (_HAS_CXX17 == 0) || !defined(_MSVC_STL_UPDATE) || (_MSVC_STL_UPDATE < 201709) +# define BOOST_NO_CXX17_STD_INVOKE +#endif + +// C++20 features which aren't configured in suffix.hpp correctly: +#if !defined(_MSVC_STL_UPDATE) || (_MSVC_STL_UPDATE < 202008L) || !defined(_HAS_CXX20) || (_HAS_CXX20 == 0) +# define BOOST_NO_CXX20_HDR_CONCEPTS +#endif + +#if !(!defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) || !defined(BOOST_MSVC) || (BOOST_MSVC < 1912) || !defined(_HAS_CXX17) || (_HAS_CXX17 == 0)) +// Deprecated std::iterator: +# define BOOST_NO_STD_ITERATOR +#endif + +#if defined(BOOST_INTEL) && (BOOST_INTEL <= 1400) +// Intel's compiler can't handle this header yet: +# define BOOST_NO_CXX11_HDR_ATOMIC +#endif + + +// 520..610 have std::addressof, but it doesn't support functions +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 650 +# define BOOST_NO_CXX11_ADDRESSOF +#endif + +// Bug specific to VC14, +// See https://connect.microsoft.com/VisualStudio/feedback/details/1348277/link-error-when-using-std-codecvt-utf8-utf16-char16-t +// and discussion here: http://blogs.msdn.com/b/vcblog/archive/2014/11/12/visual-studio-2015-preview-now-available.aspx?PageIndex=2 +#if defined(_CPPLIB_VER) && (_CPPLIB_VER == 650) && (!defined(_MSVC_STL_VERSION) || (_MSVC_STL_VERSION < 142)) +# define BOOST_NO_CXX11_HDR_CODECVT +#endif + +#if (_MSVC_LANG > 201700) && !defined(BOOST_NO_CXX11_HDR_CODECVT) +// +// is deprected as of C++17, and by default MSVC emits hard errors +// if you try to use it, so mark it as unavailable: +// +# define BOOST_NO_CXX11_HDR_CODECVT +#endif + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 650) +// If _HAS_AUTO_PTR_ETC is defined to 0, std::auto_ptr and std::random_shuffle are not available. +// See https://www.visualstudio.com/en-us/news/vs2015-vs.aspx#C++ +// and http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx +# if defined(_HAS_AUTO_PTR_ETC) && (_HAS_AUTO_PTR_ETC == 0) +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_CXX98_RANDOM_SHUFFLE +# define BOOST_NO_CXX98_FUNCTION_BASE +# define BOOST_NO_CXX98_BINDERS +# elif defined(_HAS_DEPRECATED_ADAPTOR_TYPEDEFS) && (_HAS_DEPRECATED_ADAPTOR_TYPEDEFS == 0) +# define BOOST_NO_CXX98_BINDERS +# endif +#endif +// +// Things deprecated in C++20: +// +#if defined(_HAS_CXX20) +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#endif + + +// +// Things not supported by the CLR: +#ifdef _M_CEE +#ifndef BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_MUTEX +#endif +#ifndef BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_ATOMIC +#endif +#ifndef BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_FUTURE +#endif +#ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +#endif +#ifndef BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_THREAD +#endif +#ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#ifndef BOOST_NO_CXX14_STD_EXCHANGE +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif +#ifndef BOOST_NO_FENV_H +# define BOOST_NO_FENV_H +#endif +#endif + +#ifdef _CPPLIB_VER +# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER +#else +# define BOOST_DINKUMWARE_STDLIB 1 +#endif + +// BOOST_MSSTL_VERSION: as _MSVC_STL_VERSION, but for earlier releases as well + +#if defined(_MSVC_STL_VERSION) // VS2017 (14.1) and above +# define BOOST_MSSTL_VERSION _MSVC_STL_VERSION + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 650 // VS2015 (14.0) +# define BOOST_MSSTL_VERSION 140 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 610 // VS2013 (12.0) +# define BOOST_MSSTL_VERSION 120 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 540 // VS2012 (11.0) +# define BOOST_MSSTL_VERSION 110 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 // VS2010 (10.0) +# define BOOST_MSSTL_VERSION 100 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 505 // VS2008SP1 (9.0) +# define BOOST_MSSTL_VERSION 91 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 503 // VS2008 (also 9.0) +# define BOOST_MSSTL_VERSION 90 + +#elif defined(_CPPLIB_VER) && _CPPLIB_VER >= 405 // VS2005 (8.0) +# define BOOST_MSSTL_VERSION 80 + +#endif + +// + +#ifdef _CPPLIB_VER +# define BOOST_STDLIB "Dinkumware standard library version " BOOST_STRINGIZE(_CPPLIB_VER) +#else +# define BOOST_STDLIB "Dinkumware standard library version 1.x" +#endif diff --git a/src/boost/config/stdlib/libcomo.hpp b/src/boost/config/stdlib/libcomo.hpp new file mode 100644 index 00000000..6a8a1619 --- /dev/null +++ b/src/boost/config/stdlib/libcomo.hpp @@ -0,0 +1,93 @@ +// (C) Copyright John Maddock 2002 - 2003. +// (C) Copyright Jens Maurer 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are 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 most recent version. + +// Comeau STL: + +#if !defined(__LIBCOMO__) +# include +# if !defined(__LIBCOMO__) +# error "This is not the Comeau STL!" +# endif +#endif + +// +// std::streambuf is non-standard +// NOTE: versions of libcomo prior to beta28 have octal version numbering, +// e.g. version 25 is 21 (dec) +#if __LIBCOMO_VERSION__ <= 22 +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if (__LIBCOMO_VERSION__ <= 31) && defined(_WIN32) +#define BOOST_NO_SWPRINTF +#endif + +#if __LIBCOMO_VERSION__ >= 31 +# define BOOST_HAS_HASH +# define BOOST_HAS_SLIST +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_EXCEPTION +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +#define BOOST_STDLIB "Comeau standard library " BOOST_STRINGIZE(__LIBCOMO_VERSION__) diff --git a/src/boost/config/stdlib/libcpp.hpp b/src/boost/config/stdlib/libcpp.hpp new file mode 100644 index 00000000..0e9f2445 --- /dev/null +++ b/src/boost/config/stdlib/libcpp.hpp @@ -0,0 +1,180 @@ +// (C) Copyright Christopher Jefferson 2011. +// Use, modification and distribution are 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 most recent version. + +// config for libc++ +// Might need more in here later. + +#if !defined(_LIBCPP_VERSION) +# include +# if !defined(_LIBCPP_VERSION) +# error "This is not libc++!" +# endif +#endif + +#define BOOST_STDLIB "libc++ version " BOOST_STRINGIZE(_LIBCPP_VERSION) + +#define BOOST_HAS_THREADS + +#ifdef _LIBCPP_HAS_NO_VARIADICS +# define BOOST_NO_CXX11_HDR_TUPLE +#endif + +// BOOST_NO_CXX11_ALLOCATOR should imply no support for the C++11 +// allocator model. The C++11 allocator model requires a conforming +// std::allocator_traits which is only possible with C++11 template +// aliases since members rebind_alloc and rebind_traits require it. +#if defined(_LIBCPP_HAS_NO_TEMPLATE_ALIASES) +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +#endif + +#if __cplusplus < 201103 +// +// These two appear to be somewhat useable in C++03 mode, there may be others... +// +//# define BOOST_NO_CXX11_HDR_ARRAY +//# define BOOST_NO_CXX11_HDR_FORWARD_LIST + +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_EXCEPTION +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_FUTURE +#elif _LIBCPP_VERSION < 3700 +// +// These appear to be unusable/incomplete so far: +// +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_FUTURE +#endif + + +#if _LIBCPP_VERSION < 3700 +// libc++ uses a non-standard messages_base +#define BOOST_NO_STD_MESSAGES +#endif + +// C++14 features +#if (_LIBCPP_VERSION < 3700) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// C++17 features +#if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_VARIANT +#endif +#if (_LIBCPP_VERSION > 4000) && (__cplusplus > 201402L) && !defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) +# define BOOST_NO_AUTO_PTR +#endif +#if (_LIBCPP_VERSION > 4000) && (__cplusplus > 201402L) && !defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) +# define BOOST_NO_CXX98_RANDOM_SHUFFLE +#endif +#if (_LIBCPP_VERSION > 4000) && (__cplusplus > 201402L) && !defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) +# define BOOST_NO_CXX98_BINDERS +#endif + +#if defined(__cplusplus) && defined(__has_include) +#if __has_include() +#include + +#if !defined(__cpp_lib_execution) || (__cpp_lib_execution < 201603L) +# define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#if !defined(__cpp_lib_invoke) || (__cpp_lib_invoke < 201411L) +#define BOOST_NO_CXX17_STD_INVOKE +#endif + +#if(_LIBCPP_VERSION < 9000) +// as_writable_bytes is missing. +# define BOOST_NO_CXX20_HDR_SPAN +#endif + +#else +#define BOOST_NO_CXX17_STD_INVOKE // Invoke support is incomplete (no invoke_result) +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#else +#define BOOST_NO_CXX17_STD_INVOKE // Invoke support is incomplete (no invoke_result) +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif + +#if _LIBCPP_VERSION < 10000 // What's the correct version check here? +#define BOOST_NO_CXX17_ITERATOR_TRAITS +#endif + +#if (_LIBCPP_VERSION <= 1101) && !defined(BOOST_NO_CXX11_THREAD_LOCAL) +// This is a bit of a sledgehammer, because really it's just libc++abi that has no +// support for thread_local, leading to linker errors such as +// "undefined reference to `__cxa_thread_atexit'". It is fixed in the +// most recent releases of libc++abi though... +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if defined(__linux__) && (_LIBCPP_VERSION < 6000) && !defined(BOOST_NO_CXX11_THREAD_LOCAL) +// After libc++-dev is installed on Trusty, clang++-libc++ almost works, +// except uses of `thread_local` fail with undefined reference to +// `__cxa_thread_atexit`. +// +// clang's libc++abi provides an implementation by deferring to the glibc +// implementation, which may or may not be available (it is not on Trusty). +// clang 4's libc++abi will provide an implementation if one is not in glibc +// though, so thread local support should work with clang 4 and above as long +// as libc++abi is linked in. +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus <= 201103 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +#if !defined(BOOST_NO_CXX14_HDR_SHARED_MUTEX) && (_LIBCPP_VERSION < 5000) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +#if _LIBCPP_VERSION >= 15000 +// +// Unary function is now deprecated in C++11 and later: +// +#if __cplusplus >= 201103L +#define BOOST_NO_CXX98_FUNCTION_BASE +#endif +#endif + +// --- end --- diff --git a/src/boost/config/stdlib/libstdcpp3.hpp b/src/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 00000000..ad70936d --- /dev/null +++ b/src/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,482 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are 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 most recent version. + +// config for libstdc++ v3 +// not much to go in here: + +#define BOOST_GNU_STDLIB 1 + +#ifdef __GLIBCXX__ +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__) +#else +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__) +#endif + +#if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if defined(__osf__) && !defined(_REENTRANT) \ + && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) ) +// GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + +#ifdef __GLIBCXX__ // gcc 3.4 and greater: +# if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \ + || defined(_GLIBCXX__PTHREADS) \ + || defined(_GLIBCXX_HAS_GTHREADS) \ + || defined(_WIN32) \ + || defined(_AIX) \ + || defined(__HAIKU__) + // + // If the std lib has thread support turned on, then turn it on in Boost + // as well. We do this because some gcc-3.4 std lib headers define _REENTANT + // while others do not... + // +# define BOOST_HAS_THREADS +# else +# define BOOST_DISABLE_THREADS +# endif +#elif defined(__GLIBCPP__) \ + && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \ + && !defined(_GLIBCPP__PTHREADS) + // disable thread support if the std lib was built single threaded: +# define BOOST_DISABLE_THREADS +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT) +// linux on arm apparently doesn't define _REENTRANT +// so just turn on threading support whenever the std lib is thread safe: +# define BOOST_HAS_THREADS +#endif + +#if !defined(_GLIBCPP_USE_LONG_LONG) \ + && !defined(_GLIBCXX_USE_LONG_LONG)\ + && defined(BOOST_HAS_LONG_LONG) +// May have been set by compiler/*.hpp, but "long long" without library +// support is useless. +# undef BOOST_HAS_LONG_LONG +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +#ifndef __VXWORKS__ // VxWorks uses Dinkum, not GNU STL with GCC +#if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0 +# define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx +# define BOOST_HAS_SLIST +# define BOOST_HAS_HASH +# define BOOST_SLIST_HEADER +# if !defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# else +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# endif +#endif +#endif + +#if defined(__has_include) +#if defined(BOOST_HAS_HASH) +#if !__has_include(BOOST_HASH_SET_HEADER) || (__GNUC__ >= 10) +#undef BOOST_HAS_HASH +#undef BOOST_HAS_SET_HEADER +#undef BOOST_HAS_MAP_HEADER +#endif +#if !__has_include(BOOST_SLIST_HEADER) +#undef BOOST_HAS_SLIST +#undef BOOST_HAS_SLIST_HEADER +#endif +#endif +#endif + +// +// Decide whether we have C++11 support turned on: +// +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103) +# define BOOST_LIBSTDCXX11 +#endif + +// +// Decide which version of libstdc++ we have, normally +// libstdc++ C++0x support is detected via __GNUC__, __GNUC_MINOR__, and possibly +// __GNUC_PATCHLEVEL__ at the suggestion of Jonathan Wakely, one of the libstdc++ +// developers. He also commented: +// +// "I'm not sure how useful __GLIBCXX__ is for your purposes, for instance in +// GCC 4.2.4 it is set to 20080519 but in GCC 4.3.0 it is set to 20080305. +// Although 4.3.0 was released earlier than 4.2.4, it has better C++0x support +// than any release in the 4.2 series." +// +// Another resource for understanding libstdc++ features is: +// http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#manual.intro.status.standard.200x +// +// However, using the GCC version number fails when the compiler is clang since this +// only ever claims to emulate GCC-4.2, see https://svn.boost.org/trac/boost/ticket/7473 +// for a long discussion on this issue. What we can do though is use clang's __has_include +// to detect the presence of a C++11 header that was introduced with a specific GCC release. +// We still have to be careful though as many such headers were buggy and/or incomplete when +// first introduced, so we only check for headers that were fully featured from day 1, and then +// use that to infer the underlying GCC version: +// +#ifdef __clang__ + +#ifdef _GLIBCXX_RELEASE +# define BOOST_LIBSTDCXX_VERSION (_GLIBCXX_RELEASE * 10000 + 100) +#else +// +// We figure out which gcc version issued this std lib +// by checking which headers are available: +// +#if __has_include() +# define BOOST_LIBSTDCXX_VERSION 120100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 110100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 100100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 90100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 80100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 70100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 60100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 50100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40900 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40800 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40700 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40600 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40500 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40400 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40300 +#endif +#endif +// +// If BOOST_HAS_FLOAT128 is set, now that we know the std lib is libstdc++3, check to see if the std lib is +// configured to support this type. If not disable it: +// +#if defined(BOOST_HAS_FLOAT128) && !defined(_GLIBCXX_USE_FLOAT128) +# undef BOOST_HAS_FLOAT128 +#endif + +#if (BOOST_LIBSTDCXX_VERSION >= 100000) && defined(BOOST_HAS_HASH) +// +// hash_set/hash_map deprecated and have terminal bugs: +// +#undef BOOST_HAS_HASH +#undef BOOST_HAS_SET_HEADER +#undef BOOST_HAS_MAP_HEADER +#endif + + +#if (BOOST_LIBSTDCXX_VERSION >= 100000) && defined(BOOST_HAS_HASH) +// +// hash_set/hash_map deprecated and have terminal bugs: +// +#undef BOOST_HAS_HASH +#undef BOOST_HAS_SET_HEADER +#undef BOOST_HAS_MAP_HEADER +#endif + + +#if (BOOST_LIBSTDCXX_VERSION < 50100) +// libstdc++ does not define this function as it's deprecated in C++11, but clang still looks for it, +// defining it here is a terrible cludge, but should get things working: +extern "C" char *gets (char *__s); +#endif +// +// clang is unable to parse some GCC headers, add those workarounds here: +// +#if BOOST_LIBSTDCXX_VERSION < 50000 +# define BOOST_NO_CXX11_HDR_REGEX +#endif +// +// GCC 4.7.x has no __cxa_thread_atexit which +// thread_local objects require for cleanup: +// +#if BOOST_LIBSTDCXX_VERSION < 40800 +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif +// +// Early clang versions can handle , not exactly sure which versions +// but certainly up to clang-3.8 and gcc-4.6: +// +#if (__clang_major__ < 5) +# if BOOST_LIBSTDCXX_VERSION < 40800 +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CHRONO +# endif +#endif + +// +// GCC 4.8 and 9 add working versions of and respectively. +// However, we have no test for these as the headers were present but broken +// in early GCC versions. +// +#endif + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) && (__cplusplus >= 201103L) +// +// Oracle Solaris compiler uses it's own verison of libstdc++ but doesn't +// set __GNUC__ +// +#if __SUNPRO_CC >= 0x5140 +#define BOOST_LIBSTDCXX_VERSION 50100 +#else +#define BOOST_LIBSTDCXX_VERSION 40800 +#endif +#endif + +#if !defined(BOOST_LIBSTDCXX_VERSION) +# define BOOST_LIBSTDCXX_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +// std::auto_ptr isn't provided with _GLIBCXX_DEPRECATED=0 (GCC 4.5 and earlier) +// or _GLIBCXX_USE_DEPRECATED=0 (GCC 4.6 and later). +#if defined(BOOST_LIBSTDCXX11) +# if BOOST_LIBSTDCXX_VERSION < 40600 +# if !_GLIBCXX_DEPRECATED +# define BOOST_NO_AUTO_PTR +# endif +# elif !defined(_GLIBCXX_USE_DEPRECATED) || !_GLIBCXX_USE_DEPRECATED +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_CXX98_BINDERS +# endif +#endif + +// C++0x headers in GCC 4.3.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40300) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +#endif + +// C++0x headers in GCC 4.4.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40400) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_EXCEPTION +#else +# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG +# define BOOST_HAS_TR1_COMPLEX_OVERLOADS +#endif + +// C++0x features in GCC 4.5.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40500) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_RANDOM +#endif + +// C++0x features in GCC 4.6.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40600) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX17_ITERATOR_TRAITS +#endif + +// C++0x features in GCC 4.7.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40700) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to 4.7, "steady_clock" is spelled "monotonic_clock" +// so 4.7.0 is the first truly conforming one. +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +#endif +// C++0x features in GCC 4.8.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40800) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to gcc 4.8 it was largely unimplemented for many types: +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_THREAD +#endif +// C++0x features in GCC 4.9.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +// Although is present and compilable against, the actual implementation is not functional +// even for the simplest patterns such as "\d" or "[0-9]". This is the case at least in gcc up to 4.8, inclusively. +# define BOOST_NO_CXX11_HDR_REGEX +#endif +#if (BOOST_LIBSTDCXX_VERSION < 40900) || (__cplusplus <= 201103) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +// +// C++0x features in GCC 5.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 50100) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_STD_ALIGN +#endif + +// +// C++17 features in GCC 7.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_VARIANT +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus <= 201103 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +// +// has a dependency to Intel's thread building blocks: +// unless these are installed seperately, including leads +// to inscrutable errors inside libstdc++'s own headers. +// +#if (BOOST_LIBSTDCXX_VERSION < 100100) +#if !__has_include() +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#endif +#elif __cplusplus < 201402 || (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +#if BOOST_LIBSTDCXX_VERSION < 100100 +// +// The header may be present but is incomplete: +// +# define BOOST_NO_CXX17_HDR_CHARCONV +#endif + +#if BOOST_LIBSTDCXX_VERSION < 110000 +// +// Header may be present but lacks std::bit_cast: +// +#define BOOST_NO_CXX20_HDR_BIT +#endif + +#if BOOST_LIBSTDCXX_VERSION >= 120000 +// +// Unary function is now deprecated in C++11 and later: +// +#if __cplusplus >= 201103L +#define BOOST_NO_CXX98_FUNCTION_BASE +#endif +#endif + +#ifndef __cpp_impl_coroutine +# define BOOST_NO_CXX20_HDR_COROUTINE +#endif + +// +// These next defines are mostly for older clang versions with a newer libstdc++ : +// +#if !defined(__cpp_lib_concepts) +#if !defined(BOOST_NO_CXX20_HDR_COMPARE) +# define BOOST_NO_CXX20_HDR_COMPARE +#endif +#if !defined(BOOST_NO_CXX20_HDR_CONCEPTS) +# define BOOST_NO_CXX20_HDR_CONCEPTS +#endif +#if !defined(BOOST_NO_CXX20_HDR_SPAN) +# define BOOST_NO_CXX20_HDR_SPAN +#endif +#if !defined(BOOST_NO_CXX20_HDR_RANGES) +# define BOOST_NO_CXX20_HDR_RANGES +#endif +#endif + +#if defined(__clang__) +#if (__clang_major__ < 11) && !defined(BOOST_NO_CXX20_HDR_RANGES) +# define BOOST_NO_CXX20_HDR_RANGES +#endif +#if (__clang_major__ < 10) && (BOOST_LIBSTDCXX_VERSION >= 110000) && !defined(BOOST_NO_CXX11_HDR_CHRONO) +// Old clang can't parse : +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +#endif +#endif + +#if defined(__clang__) && (BOOST_LIBSTDCXX_VERSION < 40300) && !defined(BOOST_NO_CXX11_NULLPTR) +# define BOOST_NO_CXX11_NULLPTR +#endif +#if defined(__clang__) && (BOOST_LIBSTDCXX_VERSION < 40300) && defined(BOOST_HAS_INT128) && defined(__APPLE_CC__) +#undef BOOST_HAS_INT128 +#endif + +// +// Headers not present on Solaris with the Oracle compiler: +#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140) +#define BOOST_NO_CXX11_HDR_FUTURE +#define BOOST_NO_CXX11_HDR_FORWARD_LIST +#define BOOST_NO_CXX11_HDR_ATOMIC +// shared_ptr is present, but is not convertible to bool +// which causes all kinds of problems especially in Boost.Thread +// but probably elsewhere as well. +#define BOOST_NO_CXX11_SMART_PTR +#endif + +#if (!defined(_GLIBCXX_HAS_GTHREADS) || !defined(_GLIBCXX_USE_C99_STDINT_TR1)) + // Headers not always available: +# ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# endif +# ifndef BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_MUTEX +# endif +# ifndef BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_THREAD +# endif +# ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +# endif +#endif + +#if (!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK) || (_GTHREAD_USE_MUTEX_TIMEDLOCK == 0)) && !defined(BOOST_NO_CXX11_HDR_MUTEX) && (__GNUC__ < 6) +// Timed mutexes are not always available: +# define BOOST_NO_CXX11_HDR_MUTEX +#endif + +// --- end --- diff --git a/src/boost/config/stdlib/modena.hpp b/src/boost/config/stdlib/modena.hpp new file mode 100644 index 00000000..31a26c85 --- /dev/null +++ b/src/boost/config/stdlib/modena.hpp @@ -0,0 +1,79 @@ +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are 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 most recent version. + +// Modena C++ standard library (comes with KAI C++) + +#if !defined(MSIPL_COMPILE_H) +# include +# if !defined(__MSIPL_COMPILE_H) +# error "This is not the Modena C++ library!" +# endif +#endif + +#ifndef MSIPL_NL_TYPES +#define BOOST_NO_STD_MESSAGES +#endif + +#ifndef MSIPL_WCHART +#define BOOST_NO_STD_WSTRING +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "Modena C++ standard library" + + + + + diff --git a/src/boost/config/stdlib/msl.hpp b/src/boost/config/stdlib/msl.hpp new file mode 100644 index 00000000..f2f82598 --- /dev/null +++ b/src/boost/config/stdlib/msl.hpp @@ -0,0 +1,98 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// Use, modification and distribution are 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 most recent version. + +// Metrowerks standard library: + +#ifndef __MSL_CPP__ +# include +# ifndef __MSL_CPP__ +# error This is not the MSL standard library! +# endif +#endif + +#if __MSL_CPP__ >= 0x6000 // Pro 6 +# define BOOST_HAS_HASH +# define BOOST_STD_EXTENSION_NAMESPACE Metrowerks +#endif +#define BOOST_HAS_SLIST + +#if __MSL_CPP__ < 0x6209 +# define BOOST_NO_STD_MESSAGES +#endif + +// check C lib version for +#include + +#if defined(__MSL__) && (__MSL__ >= 0x5000) +# define BOOST_HAS_STDINT_H +# if !defined(__PALMOS_TRAPS__) +# define BOOST_HAS_UNISTD_H +# endif + // boilerplate code: +# include +#endif + +#if defined(_MWMT) || _MSL_THREADSAFE +# define BOOST_HAS_THREADS +#endif + +#ifdef _MSL_NO_EXPLICIT_FUNC_TEMPLATE_ARG +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__) diff --git a/src/boost/config/stdlib/roguewave.hpp b/src/boost/config/stdlib/roguewave.hpp new file mode 100644 index 00000000..03a65768 --- /dev/null +++ b/src/boost/config/stdlib/roguewave.hpp @@ -0,0 +1,208 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2003. +// (C) Copyright Boris Gubenko 2007. +// Use, modification and distribution are 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 most recent version. + +// Rogue Wave std lib: + +#define BOOST_RW_STDLIB 1 + +#if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# include +# if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# error This is not the Rogue Wave standard library +# endif +#endif +// +// figure out a consistent version number: +// +#ifndef _RWSTD_VER +# define BOOST_RWSTD_VER 0x010000 +#elif _RWSTD_VER < 0x010000 +# define BOOST_RWSTD_VER (_RWSTD_VER << 8) +#else +# define BOOST_RWSTD_VER _RWSTD_VER +#endif + +#ifndef _RWSTD_VER +# define BOOST_STDLIB "Rogue Wave standard library version (Unknown version)" +#elif _RWSTD_VER < 0x04010200 + # define BOOST_STDLIB "Rogue Wave standard library version " BOOST_STRINGIZE(_RWSTD_VER) +#else +# ifdef _RWSTD_VER_STR +# define BOOST_STDLIB "Apache STDCXX standard library version " _RWSTD_VER_STR +# else +# define BOOST_STDLIB "Apache STDCXX standard library version " BOOST_STRINGIZE(_RWSTD_VER) +# endif +#endif + +// +// Prior to version 2.2.0 the primary template for std::numeric_limits +// does not have compile time constants, even though specializations of that +// template do: +// +#if BOOST_RWSTD_VER < 0x020200 +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// Sun CC 5.5 patch 113817-07 adds long long specialization, but does not change the +// library version number (http://sunsolve6.sun.com/search/document.do?assetkey=1-21-113817): +#if BOOST_RWSTD_VER <= 0x020101 && (!defined(__SUNPRO_CC) || (__SUNPRO_CC < 0x550)) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// Borland version of numeric_limits lacks __int64 specialisation: +// +#ifdef BOOST_BORLANDC +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// No std::iterator if it can't figure out default template args: +// +#if defined(_RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || defined(RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// No iterator traits without partial specialization: +// +#if defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) || defined(RWSTD_NO_CLASS_PARTIAL_SPEC) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// Prior to version 2.0, std::auto_ptr was buggy, and there were no +// new-style iostreams, and no conformant std::allocator: +// +#if (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_STRINGSTREAM +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STD_LOCALE +#endif + +// +// No template iterator constructors without member template support: +// +#if defined(RWSTD_NO_MEMBER_TEMPLATES) || defined(_RWSTD_NO_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +#endif + +// +// RW defines _RWSTD_ALLOCATOR if the allocator is conformant and in use +// (the or _HPACC_ part is a hack - the library seems to define _RWSTD_ALLOCATOR +// on HP aCC systems even though the allocator is in fact broken): +// +#if !defined(_RWSTD_ALLOCATOR) || (defined(__HP_aCC) && __HP_aCC <= 33100) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If we have a std::locale, we still may not have std::use_facet: +// +#if defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined(BOOST_NO_STD_LOCALE) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// +// There's no std::distance prior to version 2, or without +// partial specialization support: +// +#if (BOOST_RWSTD_VER < 0x020000) || defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + #define BOOST_NO_STD_DISTANCE +#endif + +// +// Some versions of the rogue wave library don't have assignable +// OutputIterators: +// +#if BOOST_RWSTD_VER < 0x020100 +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +#endif + +// +// Disable BOOST_HAS_LONG_LONG when the library has no support for it. +// +#if !defined(_RWSTD_LONG_LONG) && defined(BOOST_HAS_LONG_LONG) +# undef BOOST_HAS_LONG_LONG +#endif + +// +// check that on HP-UX, the proper RW library is used +// +#if defined(__HP_aCC) && !defined(_HP_NAMESPACE_STD) +# error "Boost requires Standard RW library. Please compile and link with -AA" +#endif + +// +// Define macros specific to RW V2.2 on HP-UX +// +#if defined(__HP_aCC) && (BOOST_RWSTD_VER == 0x02020100) +# ifndef __HP_TC1_MAKE_PAIR +# define __HP_TC1_MAKE_PAIR +# endif +# ifndef _HP_INSTANTIATE_STD2_VL +# define _HP_INSTANTIATE_STD2_VL +# endif +#endif + +#if _RWSTD_VER < 0x05000000 +# define BOOST_NO_CXX11_HDR_ARRAY +#endif +// type_traits header is incomplete: +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +// +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS diff --git a/src/boost/config/stdlib/sgi.hpp b/src/boost/config/stdlib/sgi.hpp new file mode 100644 index 00000000..c49957ce --- /dev/null +++ b/src/boost/config/stdlib/sgi.hpp @@ -0,0 +1,168 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are 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 most recent version. + +// generic SGI STL: + +#if !defined(__STL_CONFIG_H) +# include +# if !defined(__STL_CONFIG_H) +# error "This is not the SGI STL!" +# endif +#endif + +// +// No std::iterator traits without partial specialisation: +// +#if !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No std::stringstream with gcc < 3 +// +#if defined(__GNUC__) && (__GNUC__ < 3) && \ + ((__GNUC_MINOR__ < 95) || (__GNUC_MINOR__ == 96)) && \ + !defined(__STL_USE_NEW_IOSTREAMS) || \ + defined(__APPLE_CC__) + // Note that we only set this for GNU C++ prior to 2.95 since the + // latest patches for that release do contain a minimal + // If you are running a 2.95 release prior to 2.95.3 then this will need + // setting, but there is no way to detect that automatically (other + // than by running the configure script). + // Also, the unofficial GNU C++ 2.96 included in RedHat 7.1 doesn't + // have . +# define BOOST_NO_STRINGSTREAM +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + + +// +// Assume no std::locale without own iostreams (this may be an +// incorrect assumption in some cases): +// +#if !defined(__SGI_STL_OWN_IOSTREAMS) && !defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// Original native SGI streams have non-standard std::messages facet: +// +#if defined(__sgi) && (_COMPILER_VERSION <= 650) && !defined(__SGI_STL_OWN_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// SGI's new iostreams have missing "const" in messages<>::open +// +#if defined(__sgi) && (_COMPILER_VERSION <= 740) && defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_MESSAGES +#endif + +// +// No template iterator constructors, or std::allocator +// without member templates: +// +#if !defined(__STL_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST + +// +// If this is GNU libstdc++2, then no and no std::wstring: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) +# include +# if defined(__BASTRING__) +# define BOOST_NO_LIMITS +// Note: will provide compile-time constants +# undef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_STD_WSTRING +# endif +#endif + +// +// There is no standard iterator unless we have namespace support: +// +#if !defined(__STL_USE_NAMESPACES) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "SGI standard library" diff --git a/src/boost/config/stdlib/stlport.hpp b/src/boost/config/stdlib/stlport.hpp new file mode 100644 index 00000000..38bc763f --- /dev/null +++ b/src/boost/config/stdlib/stlport.hpp @@ -0,0 +1,258 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are 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 most recent version. + +// STLPort standard library config: + +#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# include +# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# error "This is not STLPort!" +# endif +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +// +// __STL_STATIC_CONST_INIT_BUG implies BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +// for versions prior to 4.1(beta) +// +#if (defined(__STL_STATIC_CONST_INIT_BUG) || defined(_STLP_STATIC_CONST_INIT_BUG)) && (__SGI_STL_PORT <= 0x400) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// +// If STLport thinks that there is no partial specialisation, then there is no +// std::iterator traits: +// +#if !(defined(_STLP_CLASS_PARTIAL_SPECIALIZATION) || defined(__STL_CLASS_PARTIAL_SPECIALIZATION)) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No new style iostreams on GCC without STLport's iostreams enabled: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) && !(defined(__SGI_STL_OWN_IOSTREAMS) || defined(_STLP_OWN_IOSTREAMS)) +# define BOOST_NO_STRINGSTREAM +#endif + +// +// No new iostreams implies no std::locale, and no std::stringstream: +// +#if defined(__STL_NO_IOSTREAMS) || defined(__STL_NO_NEW_IOSTREAMS) || defined(_STLP_NO_IOSTREAMS) || defined(_STLP_NO_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +#endif + +// +// If the streams are not native, and we have a "using ::x" compiler bug +// then the io stream facets are not available in namespace std:: +// +#ifdef _STLPORT_VERSION +# if !(_STLPORT_VERSION >= 0x500) && !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(BOOST_BORLANDC) +# define BOOST_NO_STD_LOCALE +# endif +#else +# if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(BOOST_BORLANDC) +# define BOOST_NO_STD_LOCALE +# endif +#endif + +#if defined(_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x520) +# define BOOST_HAS_TR1_UNORDERED_SET +# define BOOST_HAS_TR1_UNORDERED_MAP +#endif +// +// Without member template support enabled, their are no template +// iterate constructors, and no std::allocator: +// +#if !(defined(__STL_MEMBER_TEMPLATES) || defined(_STLP_MEMBER_TEMPLATES)) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif +// +// however we always have at least a partial allocator: +// +#define BOOST_HAS_PARTIAL_STD_ALLOCATOR + +#if !defined(_STLP_MEMBER_TEMPLATE_CLASSES) || defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) +# define BOOST_NO_STD_ALLOCATOR +#endif + +#if defined(_STLP_NO_MEMBER_TEMPLATE_KEYWORD) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If STLport thinks there is no wchar_t at all, then we have to disable +// the support for the relevant specilazations of std:: templates. +// +#if !defined(_STLP_HAS_WCHAR_T) && !defined(_STLP_WCHAR_T_IS_USHORT) +# ifndef BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTRING +# endif +# ifndef BOOST_NO_STD_WSTREAMBUF +# define BOOST_NO_STD_WSTREAMBUF +# endif +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#ifndef _STLP_NO_EXTENSIONS +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST +#endif + +// +// STLport does a good job of importing names into namespace std::, +// but doesn't always get them all, define BOOST_NO_STDC_NAMESPACE, since our +// workaround does not conflict with STLports: +// +// +// Harold Howe says: +// Borland switched to STLport in BCB6. Defining BOOST_NO_STDC_NAMESPACE with +// BCB6 does cause problems. If we detect C++ Builder, then don't define +// BOOST_NO_STDC_NAMESPACE +// +#if !defined(BOOST_BORLANDC) && !defined(__DMC__) +// +// If STLport is using it's own namespace, and the real names are in +// the global namespace, then we duplicate STLport's using declarations +// (by defining BOOST_NO_STDC_NAMESPACE), we do this because STLport doesn't +// necessarily import all the names we need into namespace std:: +// +# if (defined(__STL_IMPORT_VENDOR_CSTD) \ + || defined(__STL_USE_OWN_NAMESPACE) \ + || defined(_STLP_IMPORT_VENDOR_CSTD) \ + || defined(_STLP_USE_OWN_NAMESPACE)) \ + && (defined(__STL_VENDOR_GLOBAL_CSTD) || defined (_STLP_VENDOR_GLOBAL_CSTD)) +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +#elif defined(BOOST_BORLANDC) && BOOST_BORLANDC < 0x560 +// STLport doesn't import std::abs correctly: +#include +namespace std { using ::abs; } +// and strcmp/strcpy don't get imported either ('cos they are macros) +#include +#ifdef strcpy +# undef strcpy +#endif +#ifdef strcmp +# undef strcmp +#endif +#ifdef _STLP_VENDOR_CSTD +namespace std{ using _STLP_VENDOR_CSTD::strcmp; using _STLP_VENDOR_CSTD::strcpy; } +#endif +#endif + +// +// std::use_facet may be non-standard, uses a class instead: +// +#if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) || defined(_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_STLP_USE_FACET +#endif + +// +// If STLport thinks there are no wide functions, etc. is not working; but +// only if BOOST_NO_STDC_NAMESPACE is not defined (if it is then we do the import +// into std:: ourselves). +// +#if defined(_STLP_NO_NATIVE_WIDE_FUNCTIONS) && !defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +#endif + +// +// If STLport for some reason was configured so that it thinks that wchar_t +// is not an intrinsic type, then we have to disable the support for it as +// well (we would be missing required specializations otherwise). +// +#if !defined( _STLP_HAS_WCHAR_T) || defined(_STLP_WCHAR_T_IS_USHORT) +# undef BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// Borland ships a version of STLport with C++ Builder 6 that lacks +// hashtables and the like: +// +#if defined(BOOST_BORLANDC) && (BOOST_BORLANDC == 0x560) +# undef BOOST_HAS_HASH +#endif + +// +// gcc-2.95.3/STLPort does not like the using declarations we use to get ADL with std::min/max +// +#if defined(__GNUC__) && (__GNUC__ < 3) +# include // for std::min and std::max +# define BOOST_USING_STD_MIN() ((void)0) +# define BOOST_USING_STD_MAX() ((void)0) +namespace boost { using std::min; using std::max; } +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT) diff --git a/src/boost/config/stdlib/vacpp.hpp b/src/boost/config/stdlib/vacpp.hpp new file mode 100644 index 00000000..b14dd655 --- /dev/null +++ b/src/boost/config/stdlib/vacpp.hpp @@ -0,0 +1,74 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are 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 most recent version. + +#if __IBMCPP__ <= 501 +# define BOOST_NO_STD_ALLOCATOR +#endif + +#define BOOST_HAS_MACRO_USE_FACET +#define BOOST_NO_STD_MESSAGES + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RANDOM +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_REGEX +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_STD_ALIGN +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX11_HDR_EXCEPTION + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus < 201402 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#else +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// C++14 features +# define BOOST_NO_CXX14_STD_EXCHANGE + +// C++17 features +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_ITERATOR_TRAITS + +#define BOOST_STDLIB "Visual Age default standard library" diff --git a/src/boost/config/stdlib/xlcpp_zos.hpp b/src/boost/config/stdlib/xlcpp_zos.hpp new file mode 100644 index 00000000..a5e02fd8 --- /dev/null +++ b/src/boost/config/stdlib/xlcpp_zos.hpp @@ -0,0 +1,61 @@ +// Copyright (c) 2017 Dynatrace +// +// 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 + +// See http://www.boost.org for most recent version. + +// Standard library setup for IBM z/OS XL C/C++ compiler. + +// Oldest library version currently supported is 2.1 (V2R1) +#if __TARGET_LIB__ < 0x42010000 +# error "Library version not supported or configured - please reconfigure" +#endif + +#if __TARGET_LIB__ > 0x42010000 +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown library version - please run the configure tests and report the results" +# endif +#endif + +#define BOOST_STDLIB "IBM z/OS XL C/C++ standard library" + +#define BOOST_HAS_MACRO_USE_FACET + +#define BOOST_NO_CXX11_HDR_TYPE_TRAITS +#define BOOST_NO_CXX11_HDR_INITIALIZER_LIST + +#define BOOST_NO_CXX11_ADDRESSOF +#define BOOST_NO_CXX11_SMART_PTR +#define BOOST_NO_CXX11_ATOMIC_SMART_PTR +#define BOOST_NO_CXX11_NUMERIC_LIMITS +#define BOOST_NO_CXX11_ALLOCATOR +#define BOOST_NO_CXX11_POINTER_TRAITS +#define BOOST_NO_CXX11_HDR_FUNCTIONAL +#define BOOST_NO_CXX11_HDR_UNORDERED_SET +#define BOOST_NO_CXX11_HDR_UNORDERED_MAP +#define BOOST_NO_CXX11_HDR_TYPEINDEX +#define BOOST_NO_CXX11_HDR_TUPLE +#define BOOST_NO_CXX11_HDR_THREAD +#define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +#define BOOST_NO_CXX11_HDR_REGEX +#define BOOST_NO_CXX11_HDR_RATIO +#define BOOST_NO_CXX11_HDR_RANDOM +#define BOOST_NO_CXX11_HDR_MUTEX +#define BOOST_NO_CXX11_HDR_FUTURE +#define BOOST_NO_CXX11_HDR_FORWARD_LIST +#define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +#define BOOST_NO_CXX11_HDR_CODECVT +#define BOOST_NO_CXX11_HDR_CHRONO +#define BOOST_NO_CXX11_HDR_ATOMIC +#define BOOST_NO_CXX11_HDR_ARRAY +#define BOOST_NO_CXX11_HDR_EXCEPTION +#define BOOST_NO_CXX11_STD_ALIGN + +#define BOOST_NO_CXX14_STD_EXCHANGE +#define BOOST_NO_CXX14_HDR_SHARED_MUTEX + +#define BOOST_NO_CXX17_STD_INVOKE +#define BOOST_NO_CXX17_STD_APPLY +#define BOOST_NO_CXX17_ITERATOR_TRAITS diff --git a/src/boost/config/user.hpp b/src/boost/config/user.hpp new file mode 100644 index 00000000..8160fcae --- /dev/null +++ b/src/boost/config/user.hpp @@ -0,0 +1,133 @@ +// boost/config/user.hpp ---------------------------------------------------// + +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are 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) + +// Do not check in modified versions of this file, +// This file may be customized by the end user, but not by boost. + +// +// Use this file to define a site and compiler specific +// configuration policy: +// + +// define this to locate a compiler config file: +// #define BOOST_COMPILER_CONFIG + +// define this to locate a stdlib config file: +// #define BOOST_STDLIB_CONFIG + +// define this to locate a platform config file: +// #define BOOST_PLATFORM_CONFIG + +// define this to disable compiler config, +// use if your compiler config has nothing to set: +// #define BOOST_NO_COMPILER_CONFIG + +// define this to disable stdlib config, +// use if your stdlib config has nothing to set: +// #define BOOST_NO_STDLIB_CONFIG + +// define this to disable platform config, +// use if your platform config has nothing to set: +// #define BOOST_NO_PLATFORM_CONFIG + +// define this to disable all config options, +// excluding the user config. Use if your +// setup is fully ISO compliant, and has no +// useful extensions, or for autoconf generated +// setups: +// #define BOOST_NO_CONFIG + +// define this to make the config "optimistic" +// about unknown compiler versions. Normally +// unknown compiler versions are assumed to have +// all the defects of the last known version, however +// setting this flag, causes the config to assume +// that unknown compiler versions are fully conformant +// with the standard: +// #define BOOST_STRICT_CONFIG + +// define this to cause the config to halt compilation +// with an #error if it encounters anything unknown -- +// either an unknown compiler version or an unknown +// compiler/platform/library: +// #define BOOST_ASSERT_CONFIG + + +// define if you want to disable threading support, even +// when available: +// #define BOOST_DISABLE_THREADS + +// define when you want to disable Win32 specific features +// even when available: +// #define BOOST_DISABLE_WIN32 + +// BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any +// prefix/suffix headers that normally control things like struct +// packing and alignment. +// #define BOOST_DISABLE_ABI_HEADERS + +// BOOST_ABI_PREFIX: A prefix header to include in place of whatever +// boost.config would normally select, any replacement should set up +// struct packing and alignment options as required. +// #define BOOST_ABI_PREFIX my-header-name + +// BOOST_ABI_SUFFIX: A suffix header to include in place of whatever +// boost.config would normally select, any replacement should undo +// the effects of the prefix header. +// #define BOOST_ABI_SUFFIX my-header-name + +// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, +// to be linked as dll's rather than static libraries on Microsoft Windows +// (this macro is used to turn on __declspec(dllimport) modifiers, so that +// the compiler knows which symbols to look for in a dll rather than in a +// static library). Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), in these cases this +// macro has no effect. +// #define BOOST_ALL_DYN_LINK + +// BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll +// rather than a static library on Microsoft Windows: replace the WHATEVER +// part of the macro name with the name of the library that you want to +// dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or +// BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) +// modifiers, so that the compiler knows which symbols to look for in a dll +// rather than in a static library). +// Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), +// in these cases this macro is unsupported. +// #define BOOST_WHATEVER_DYN_LINK + +// BOOST_ALL_NO_LIB: Tells the config system not to automatically select +// which libraries to link against. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, +// simply by the act of including one of that library's headers. +// This macro turns that feature off. +// #define BOOST_ALL_NO_LIB + +// BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically +// select which library to link against for library "whatever", +// replace WHATEVER in the macro name with the name of the library; +// for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, simply +// by the act of including one of that library's headers. This macro turns +// that feature off. +// #define BOOST_WHATEVER_NO_LIB + +// BOOST_LIB_BUILDID: Set to the same value as the value passed to Boost.Build's +// --buildid command line option. For example if you built using: +// +// bjam address-model=64 --buildid=amd64 +// +// then compile your code with: +// +// -DBOOST_LIB_BUILDID = amd64 +// +// to ensure the correct libraries are selected at link time. +// #define BOOST_LIB_BUILDID amd64 + diff --git a/src/boost/config/warning_disable.hpp b/src/boost/config/warning_disable.hpp new file mode 100644 index 00000000..fea8e829 --- /dev/null +++ b/src/boost/config/warning_disable.hpp @@ -0,0 +1,47 @@ +// Copyright John Maddock 2008 +// 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) +// +// This file exists to turn off some overly-pedantic warning emitted +// by certain compilers. You should include this header only in: +// +// * A test case, before any other headers, or, +// * A library source file before any other headers. +// +// IT SHOULD NOT BE INCLUDED BY ANY BOOST HEADER. +// +// YOU SHOULD NOT INCLUDE IT IF YOU CAN REASONABLY FIX THE WARNING. +// +// The only warnings disabled here are those that are: +// +// * Quite unreasonably pedantic. +// * Generally only emitted by a single compiler. +// * Can't easily be fixed: for example if the vendors own std lib +// code emits these warnings! +// +// Note that THIS HEADER MUST NOT INCLUDE ANY OTHER HEADERS: +// not even std library ones! Doing so may turn the warning +// off too late to be of any use. For example the VC++ C4996 +// warning can be emitted from if that header is included +// before or by this one :-( +// + +#ifndef BOOST_CONFIG_WARNING_DISABLE_HPP +#define BOOST_CONFIG_WARNING_DISABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + // Error 'function': was declared deprecated + // http://msdn2.microsoft.com/en-us/library/ttcz0bys(VS.80).aspx + // This error is emitted when you use some perfectly conforming + // std lib functions in a perfectly correct way, and also by + // some of Microsoft's own std lib code ! +# pragma warning(disable:4996) +#endif +#if defined(__INTEL_COMPILER) || defined(__ICL) + // As above: gives warning when a "deprecated" + // std library function is encountered. +# pragma warning(disable:1786) +#endif + +#endif // BOOST_CONFIG_WARNING_DISABLE_HPP diff --git a/src/boost/config/workaround.hpp b/src/boost/config/workaround.hpp new file mode 100644 index 00000000..688f9636 --- /dev/null +++ b/src/boost/config/workaround.hpp @@ -0,0 +1,305 @@ +// Copyright David Abrahams 2002. +// 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) +#ifndef BOOST_CONFIG_WORKAROUND_HPP +#define BOOST_CONFIG_WORKAROUND_HPP + +// Compiler/library version workaround macro +// +// Usage: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// // workaround for eVC4 and VC6 +// ... // workaround code here +// #endif +// +// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the +// first argument must be undefined or expand to a numeric +// value. The above expands to: +// +// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 +// +// When used for workarounds that apply to the latest known version +// and all earlier versions of a compiler, the following convention +// should be observed: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) +// +// The version number in this case corresponds to the last version in +// which the workaround was known to have been required. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro +// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates +// the workaround for any version of the compiler. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or +// error will be issued if the compiler version exceeds the argument +// to BOOST_TESTED_AT(). This can be used to locate workarounds which +// may be obsoleted by newer versions. + +#ifndef BOOST_STRICT_CONFIG + +#include + +#ifndef __BORLANDC__ +#define __BORLANDC___WORKAROUND_GUARD 1 +#else +#define __BORLANDC___WORKAROUND_GUARD 0 +#endif +#ifndef __CODEGEARC__ +#define __CODEGEARC___WORKAROUND_GUARD 1 +#else +#define __CODEGEARC___WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_BORLANDC +#define BOOST_BORLANDC_WORKAROUND_GUARD 1 +#else +#define BOOST_BORLANDC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_CODEGEARC +#define BOOST_CODEGEARC_WORKAROUND_GUARD 1 +#else +#define BOOST_CODEGEARC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_EMBTC +#define BOOST_EMBTC_WORKAROUND_GUARD 1 +#else +#define BOOST_EMBTC_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_VER +#define _MSC_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_VER_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_FULL_VER +#define _MSC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC +#define BOOST_MSVC_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC_FULL_VER +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC__ +#define __GNUC___WORKAROUND_GUARD 1 +#else +#define __GNUC___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_MINOR__ +#define __GNUC_MINOR___WORKAROUND_GUARD 1 +#else +#define __GNUC_MINOR___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_PATCHLEVEL__ +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1 +#else +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_GCC +#define BOOST_GCC_WORKAROUND_GUARD 1 +#define BOOST_GCC_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_GCC_WORKAROUND_GUARD 0 +#define BOOST_GCC_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_XLCPP_ZOS +#define BOOST_XLCPP_ZOS_WORKAROUND_GUARD 1 +#else +#define BOOST_XLCPP_ZOS_WORKAROUND_GUARD 0 +#endif +#ifndef __IBMCPP__ +#define __IBMCPP___WORKAROUND_GUARD 1 +#else +#define __IBMCPP___WORKAROUND_GUARD 0 +#endif +#ifndef __SUNPRO_CC +#define __SUNPRO_CC_WORKAROUND_GUARD 1 +#else +#define __SUNPRO_CC_WORKAROUND_GUARD 0 +#endif +#ifndef __DECCXX_VER +#define __DECCXX_VER_WORKAROUND_GUARD 1 +#else +#define __DECCXX_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __MWERKS__ +#define __MWERKS___WORKAROUND_GUARD 1 +#else +#define __MWERKS___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG__ +#define __EDG___WORKAROUND_GUARD 1 +#else +#define __EDG___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG_VERSION__ +#define __EDG_VERSION___WORKAROUND_GUARD 1 +#else +#define __EDG_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __HP_aCC +#define __HP_aCC_WORKAROUND_GUARD 1 +#else +#define __HP_aCC_WORKAROUND_GUARD 0 +#endif +#ifndef __hpxstd98 +#define __hpxstd98_WORKAROUND_GUARD 1 +#else +#define __hpxstd98_WORKAROUND_GUARD 0 +#endif +#ifndef _CRAYC +#define _CRAYC_WORKAROUND_GUARD 1 +#else +#define _CRAYC_WORKAROUND_GUARD 0 +#endif +#ifndef __DMC__ +#define __DMC___WORKAROUND_GUARD 1 +#else +#define __DMC___WORKAROUND_GUARD 0 +#endif +#ifndef MPW_CPLUS +#define MPW_CPLUS_WORKAROUND_GUARD 1 +#else +#define MPW_CPLUS_WORKAROUND_GUARD 0 +#endif +#ifndef __COMO__ +#define __COMO___WORKAROUND_GUARD 1 +#else +#define __COMO___WORKAROUND_GUARD 0 +#endif +#ifndef __COMO_VERSION__ +#define __COMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __COMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __INTEL_COMPILER +#define __INTEL_COMPILER_WORKAROUND_GUARD 1 +#else +#define __INTEL_COMPILER_WORKAROUND_GUARD 0 +#endif +#ifndef __ICL +#define __ICL_WORKAROUND_GUARD 1 +#else +#define __ICL_WORKAROUND_GUARD 0 +#endif +#ifndef _COMPILER_VERSION +#define _COMPILER_VERSION_WORKAROUND_GUARD 1 +#else +#define _COMPILER_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef __clang_major__ +#define __clang_major___WORKAROUND_GUARD 1 +#else +#define __clang_major___WORKAROUND_GUARD 0 +#endif + +#ifndef _RWSTD_VER +#define _RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define _RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_RWSTD_VER +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GLIBCPP__ +#define __GLIBCPP___WORKAROUND_GUARD 1 +#else +#define __GLIBCPP___WORKAROUND_GUARD 0 +#endif +#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1 +#else +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0 +#endif +#ifndef __SGI_STL_PORT +#define __SGI_STL_PORT_WORKAROUND_GUARD 1 +#else +#define __SGI_STL_PORT_WORKAROUND_GUARD 0 +#endif +#ifndef _STLPORT_VERSION +#define _STLPORT_VERSION_WORKAROUND_GUARD 1 +#else +#define _STLPORT_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef __LIBCOMO_VERSION__ +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef _CPPLIB_VER +#define _CPPLIB_VER_WORKAROUND_GUARD 1 +#else +#define _CPPLIB_VER_WORKAROUND_GUARD 0 +#endif + +#ifndef BOOST_INTEL_CXX_VERSION +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL_WIN +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_DINKUMWARE_STDLIB +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1 +#else +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL +#define BOOST_INTEL_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_CLANG_VERSION +#define BOOST_CLANG_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_CLANG_VERSION_WORKAROUND_GUARD 0 +#endif + +// Always define to zero, if it's used it'll be defined my MPL: +#define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0 + +#define BOOST_WORKAROUND(symbol, test) \ + ((symbol ## _WORKAROUND_GUARD + 0 == 0) && \ + (symbol != 0) && (1 % (( (symbol test) ) + 1))) +// ^ ^ ^ ^ +// The extra level of parenthesis nesting above, along with the +// BOOST_OPEN_PAREN indirection below, is required to satisfy the +// broken preprocessor in MWCW 8.3 and earlier. +// +// The basic mechanism works as follows: +// (symbol test) + 1 => if (symbol test) then 2 else 1 +// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 +// +// The complication with % is for cooperation with BOOST_TESTED_AT(). +// When "test" is BOOST_TESTED_AT(x) and +// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, +// +// symbol test => if (symbol <= x) then 1 else -1 +// (symbol test) + 1 => if (symbol <= x) then 2 else 0 +// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero +// + +#ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_OPEN_PAREN ( +# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1 +#else +# define BOOST_TESTED_AT(value) != ((value)-(value)) +#endif + +#else + +#define BOOST_WORKAROUND(symbol, test) 0 + +#endif + +#endif // BOOST_CONFIG_WORKAROUND_HPP diff --git a/src/boost/container_hash/detail/hash_integral.hpp b/src/boost/container_hash/detail/hash_integral.hpp new file mode 100644 index 00000000..3b0be63f --- /dev/null +++ b/src/boost/container_hash/detail/hash_integral.hpp @@ -0,0 +1,146 @@ +// Copyright 2021-2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP +#define BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP + +#include +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +// libstdc++ doesn't provide support for __int128 in the standard traits + +template struct is_integral: public std::is_integral +{ +}; + +template struct is_unsigned: public std::is_unsigned +{ +}; + +template struct make_unsigned: public std::make_unsigned +{ +}; + +#if defined(__SIZEOF_INT128__) + +template<> struct is_integral<__int128_t>: public std::true_type +{ +}; + +template<> struct is_integral<__uint128_t>: public std::true_type +{ +}; + +template<> struct is_unsigned<__int128_t>: public std::false_type +{ +}; + +template<> struct is_unsigned<__uint128_t>: public std::true_type +{ +}; + +template<> struct make_unsigned<__int128_t> +{ + typedef __uint128_t type; +}; + +template<> struct make_unsigned<__uint128_t> +{ + typedef __uint128_t type; +}; + +#endif + +template sizeof(std::size_t)), + bool is_unsigned = is_unsigned::value, + std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT, + std::size_t type_bits = sizeof(T) * CHAR_BIT> +struct hash_integral_impl; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + return static_cast( v ); + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + typedef typename make_unsigned::type U; + + if( v >= 0 ) + { + return hash_integral_impl::fn( static_cast( v ) ); + } + else + { + return ~hash_integral_impl::fn( static_cast( ~static_cast( v ) ) ); + } + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v & 0xFFFFFFFF ) + hash_detail::hash_mix( seed ); + + return seed; + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 96 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v >> 32 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v ) + hash_detail::hash_mix( seed ); + + return seed; + } +}; + +template struct hash_integral_impl +{ + static std::size_t fn( T v ) + { + std::size_t seed = 0; + + seed = static_cast( v >> 64 ) + hash_detail::hash_mix( seed ); + seed = static_cast( v ) + hash_detail::hash_mix( seed ); + + return seed; + } +}; + +} // namespace hash_detail + +template +typename std::enable_if::value, std::size_t>::type + hash_value( T v ) +{ + return hash_detail::hash_integral_impl::fn( v ); +} + +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP diff --git a/src/boost/container_hash/detail/hash_mix.hpp b/src/boost/container_hash/detail/hash_mix.hpp new file mode 100644 index 00000000..088dd75d --- /dev/null +++ b/src/boost/container_hash/detail/hash_mix.hpp @@ -0,0 +1,113 @@ +// Copyright 2022 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_MIX_HPP +#define BOOST_HASH_DETAIL_HASH_MIX_HPP + +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct hash_mix_impl; + +// hash_mix for 64 bit size_t +// +// The general "xmxmx" form of state of the art 64 bit mixers originates +// from Murmur3 by Austin Appleby, which uses the following function as +// its "final mix": +// +// k ^= k >> 33; +// k *= 0xff51afd7ed558ccd; +// k ^= k >> 33; +// k *= 0xc4ceb9fe1a85ec53; +// k ^= k >> 33; +// +// (https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp) +// +// It has subsequently been improved multiple times by different authors +// by changing the constants. The most well known improvement is the +// so-called "variant 13" function by David Stafford: +// +// k ^= k >> 30; +// k *= 0xbf58476d1ce4e5b9; +// k ^= k >> 27; +// k *= 0x94d049bb133111eb; +// k ^= k >> 31; +// +// (https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html) +// +// This mixing function is used in the splitmix64 RNG: +// http://xorshift.di.unimi.it/splitmix64.c +// +// We use Jon Maiga's implementation from +// http://jonkagstrom.com/mx3/mx3_rev2.html +// +// x ^= x >> 32; +// x *= 0xe9846af9b1a615d; +// x ^= x >> 32; +// x *= 0xe9846af9b1a615d; +// x ^= x >> 28; +// +// An equally good alternative is Pelle Evensen's Moremur: +// +// x ^= x >> 27; +// x *= 0x3C79AC492BA7B653; +// x ^= x >> 33; +// x *= 0x1C69B3F74AC4AE35; +// x ^= x >> 27; +// +// (https://mostlymangling.blogspot.com/2019/12/stronger-better-morer-moremur-better.html) + +template<> struct hash_mix_impl<64> +{ + inline static std::uint64_t fn( std::uint64_t x ) + { + std::uint64_t const m = 0xe9846af9b1a615d; + + x ^= x >> 32; + x *= m; + x ^= x >> 32; + x *= m; + x ^= x >> 28; + + return x; + } +}; + +// hash_mix for 32 bit size_t +// +// We use the "best xmxmx" implementation from +// https://github.com/skeeto/hash-prospector/issues/19 + +template<> struct hash_mix_impl<32> +{ + inline static std::uint32_t fn( std::uint32_t x ) + { + std::uint32_t const m1 = 0x21f0aaad; + std::uint32_t const m2 = 0x735a2d97; + + x ^= x >> 16; + x *= m1; + x ^= x >> 15; + x *= m2; + x ^= x >> 15; + + return x; + } +}; + +inline std::size_t hash_mix( std::size_t v ) +{ + return hash_mix_impl::fn( v ); +} + +} // namespace hash_detail +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_MIX_HPP diff --git a/src/boost/container_hash/detail/hash_range.hpp b/src/boost/container_hash/detail/hash_range.hpp new file mode 100644 index 00000000..74bfe384 --- /dev/null +++ b/src/boost/container_hash/detail/hash_range.hpp @@ -0,0 +1,408 @@ +// Copyright 2022 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_RANGE_HPP +#define BOOST_HASH_DETAIL_HASH_RANGE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct is_char_type: public std::false_type {}; + +#if CHAR_BIT == 8 + +template<> struct is_char_type: public std::true_type {}; +template<> struct is_char_type: public std::true_type {}; +template<> struct is_char_type: public std::true_type {}; + +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L +template<> struct is_char_type: public std::true_type {}; +#endif + +#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L +template<> struct is_char_type: public std::true_type {}; +#endif + +#endif + +// generic version + +template +inline typename std::enable_if< + !is_char_type::value_type>::value, +std::size_t >::type + hash_range( std::size_t seed, It first, It last ) +{ + for( ; first != last; ++first ) + { + hash_combine::value_type>( seed, *first ); + } + + return seed; +} + +// specialized char[] version, 32 bit + +template inline std::uint32_t read32le( It p ) +{ + // clang 5+, gcc 5+ figure out this pattern and use a single mov on x86 + // gcc on s390x and power BE even knows how to use load-reverse + + std::uint32_t w = + static_cast( static_cast( p[0] ) ) | + static_cast( static_cast( p[1] ) ) << 8 | + static_cast( static_cast( p[2] ) ) << 16 | + static_cast( static_cast( p[3] ) ) << 24; + + return w; +} + +#if defined(_MSC_VER) && !defined(__clang__) + +template inline std::uint32_t read32le( T* p ) +{ + std::uint32_t w; + + std::memcpy( &w, p, 4 ); + return w; +} + +#endif + +inline std::uint64_t mul32( std::uint32_t x, std::uint32_t y ) +{ + return static_cast( x ) * y; +} + +template +inline typename std::enable_if< + is_char_type::value_type>::value && + std::is_same::iterator_category, std::random_access_iterator_tag>::value && + std::numeric_limits::digits <= 32, +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + It p = first; + std::size_t n = static_cast( last - first ); + + std::uint32_t const q = 0x9e3779b9U; + std::uint32_t const k = 0xe35e67b1U; // q * q + + std::uint64_t h = mul32( static_cast( seed ) + q, k ); + std::uint32_t w = static_cast( h & 0xFFFFFFFF ); + + h ^= n; + + while( n >= 4 ) + { + std::uint32_t v1 = read32le( p ); + + w += q; + h ^= mul32( v1 + w, k ); + + p += 4; + n -= 4; + } + + { + std::uint32_t v1 = 0; + + if( n >= 1 ) + { + std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2 + std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1 + + v1 = + static_cast( static_cast( p[ static_cast( x1 ) ] ) ) << x1 * 8 | + static_cast( static_cast( p[ static_cast( x2 ) ] ) ) << x2 * 8 | + static_cast( static_cast( p[ 0 ] ) ); + } + + w += q; + h ^= mul32( v1 + w, k ); + } + + w += q; + h ^= mul32( static_cast( h & 0xFFFFFFFF ) + w, static_cast( h >> 32 ) + w + k ); + + return static_cast( h & 0xFFFFFFFF ) ^ static_cast( h >> 32 ); +} + +template +inline typename std::enable_if< + is_char_type::value_type>::value && + !std::is_same::iterator_category, std::random_access_iterator_tag>::value && + std::numeric_limits::digits <= 32, +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + std::size_t n = 0; + + std::uint32_t const q = 0x9e3779b9U; + std::uint32_t const k = 0xe35e67b1U; // q * q + + std::uint64_t h = mul32( static_cast( seed ) + q, k ); + std::uint32_t w = static_cast( h & 0xFFFFFFFF ); + + std::uint32_t v1 = 0; + + for( ;; ) + { + v1 = 0; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ); + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 8; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 16; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 24; + ++first; + ++n; + + w += q; + h ^= mul32( v1 + w, k ); + } + + h ^= n; + + w += q; + h ^= mul32( v1 + w, k ); + + w += q; + h ^= mul32( static_cast( h & 0xFFFFFFFF ) + w, static_cast( h >> 32 ) + w + k ); + + return static_cast( h & 0xFFFFFFFF ) ^ static_cast( h >> 32 ); +} + +// specialized char[] version, 64 bit + +template inline std::uint64_t read64le( It p ) +{ + std::uint64_t w = + static_cast( static_cast( p[0] ) ) | + static_cast( static_cast( p[1] ) ) << 8 | + static_cast( static_cast( p[2] ) ) << 16 | + static_cast( static_cast( p[3] ) ) << 24 | + static_cast( static_cast( p[4] ) ) << 32 | + static_cast( static_cast( p[5] ) ) << 40 | + static_cast( static_cast( p[6] ) ) << 48 | + static_cast( static_cast( p[7] ) ) << 56; + + return w; +} + +#if defined(_MSC_VER) && !defined(__clang__) + +template inline std::uint64_t read64le( T* p ) +{ + std::uint64_t w; + + std::memcpy( &w, p, 8 ); + return w; +} + +#endif + +template +inline typename std::enable_if< + is_char_type::value_type>::value && + std::is_same::iterator_category, std::random_access_iterator_tag>::value && + (std::numeric_limits::digits > 32), +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + It p = first; + std::size_t n = static_cast( last - first ); + + std::uint64_t const q = 0x9e3779b97f4a7c15; + std::uint64_t const k = 0xdf442d22ce4859b9; // q * q + + std::uint64_t w = mulx( seed + q, k ); + std::uint64_t h = w ^ n; + + while( n >= 8 ) + { + std::uint64_t v1 = read64le( p ); + + w += q; + h ^= mulx( v1 + w, k ); + + p += 8; + n -= 8; + } + + { + std::uint64_t v1 = 0; + + if( n >= 4 ) + { + v1 = static_cast( read32le( p + static_cast( n - 4 ) ) ) << ( n - 4 ) * 8 | read32le( p ); + } + else if( n >= 1 ) + { + std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2 + std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1 + + v1 = + static_cast( static_cast( p[ static_cast( x1 ) ] ) ) << x1 * 8 | + static_cast( static_cast( p[ static_cast( x2 ) ] ) ) << x2 * 8 | + static_cast( static_cast( p[ 0 ] ) ); + } + + w += q; + h ^= mulx( v1 + w, k ); + } + + return mulx( h + w, k ); +} + +template +inline typename std::enable_if< + is_char_type::value_type>::value && + !std::is_same::iterator_category, std::random_access_iterator_tag>::value && + (std::numeric_limits::digits > 32), +std::size_t>::type + hash_range( std::size_t seed, It first, It last ) +{ + std::size_t n = 0; + + std::uint64_t const q = 0x9e3779b97f4a7c15; + std::uint64_t const k = 0xdf442d22ce4859b9; // q * q + + std::uint64_t w = mulx( seed + q, k ); + std::uint64_t h = w; + + std::uint64_t v1 = 0; + + for( ;; ) + { + v1 = 0; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ); + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 8; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 16; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 24; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 32; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 40; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 48; + ++first; + ++n; + + if( first == last ) + { + break; + } + + v1 |= static_cast( static_cast( *first ) ) << 56; + ++first; + ++n; + + w += q; + h ^= mulx( v1 + w, k ); + } + + h ^= n; + + w += q; + h ^= mulx( v1 + w, k ); + + return mulx( h + w, k ); +} + +} // namespace hash_detail +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_RANGE_HPP diff --git a/src/boost/container_hash/detail/hash_tuple_like.hpp b/src/boost/container_hash/detail/hash_tuple_like.hpp new file mode 100644 index 00000000..c7f881c1 --- /dev/null +++ b/src/boost/container_hash/detail/hash_tuple_like.hpp @@ -0,0 +1,62 @@ +// Copyright 2005-2009 Daniel James. +// Copyright 2021 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP +#define BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template +inline +typename std::enable_if<(I == std::tuple_size::value), void>::type + hash_combine_tuple_like( std::size_t&, T const& ) +{ +} + +template +inline +typename std::enable_if<(I < std::tuple_size::value), void>::type + hash_combine_tuple_like( std::size_t& seed, T const& v ) +{ + using std::get; + boost::hash_combine( seed, get( v ) ); + + boost::hash_detail::hash_combine_tuple_like( seed, v ); +} + +template +inline std::size_t hash_tuple_like( T const& v ) +{ + std::size_t seed = 0; + + boost::hash_detail::hash_combine_tuple_like<0>( seed, v ); + + return seed; +} + +} // namespace hash_detail + +template +inline +typename std::enable_if< + container_hash::is_tuple_like::value && !container_hash::is_range::value, +std::size_t>::type + hash_value( T const& v ) +{ + return boost::hash_detail::hash_tuple_like( v ); +} + +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP diff --git a/src/boost/container_hash/detail/mulx.hpp b/src/boost/container_hash/detail/mulx.hpp new file mode 100644 index 00000000..a99a7dd3 --- /dev/null +++ b/src/boost/container_hash/detail/mulx.hpp @@ -0,0 +1,79 @@ +// Copyright 2022, 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_DETAIL_MULX_HPP +#define BOOST_HASH_DETAIL_MULX_HPP + +#include +#if defined(_MSC_VER) +# include +#endif + +namespace boost +{ +namespace hash_detail +{ + +#if defined(_MSC_VER) && defined(_M_X64) && !defined(__clang__) + +__forceinline std::uint64_t mulx( std::uint64_t x, std::uint64_t y ) +{ + std::uint64_t r2; + std::uint64_t r = _umul128( x, y, &r2 ); + return r ^ r2; +} + +#elif defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) + +__forceinline std::uint64_t mulx( std::uint64_t x, std::uint64_t y ) +{ + std::uint64_t r = x * y; + std::uint64_t r2 = __umulh( x, y ); + return r ^ r2; +} + +#elif defined(__SIZEOF_INT128__) + +inline std::uint64_t mulx( std::uint64_t x, std::uint64_t y ) +{ + __uint128_t r = static_cast<__uint128_t>( x ) * y; + return static_cast( r ) ^ static_cast( r >> 64 ); +} + +#else + +inline std::uint64_t mulx( std::uint64_t x, std::uint64_t y ) +{ + std::uint64_t x1 = static_cast( x ); + std::uint64_t x2 = x >> 32; + + std::uint64_t y1 = static_cast( y ); + std::uint64_t y2 = y >> 32; + + std::uint64_t r3 = x2 * y2; + + std::uint64_t r2a = x1 * y2; + + r3 += r2a >> 32; + + std::uint64_t r2b = x2 * y1; + + r3 += r2b >> 32; + + std::uint64_t r1 = x1 * y1; + + std::uint64_t r2 = (r1 >> 32) + static_cast( r2a ) + static_cast( r2b ); + + r1 = (r2 << 32) + static_cast( r1 ); + r3 += r2 >> 32; + + return r1 ^ r3; +} + +#endif + +} // namespace hash_detail +} // namespace boost + +#endif // #ifndef BOOST_HASH_DETAIL_MULX_HPP diff --git a/src/boost/container_hash/hash.hpp b/src/boost/container_hash/hash.hpp new file mode 100644 index 00000000..8305a22c --- /dev/null +++ b/src/boost/container_hash/hash.hpp @@ -0,0 +1,576 @@ +// Copyright 2005-2014 Daniel James. +// Copyright 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP +#define BOOST_FUNCTIONAL_HASH_HASH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_DESCRIBE_CXX14) +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_SMART_PTR) +# include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) +#include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) +#include +#endif + +#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL) +#include +#endif + +#if !defined(BOOST_NO_CXX17_HDR_VARIANT) +#include +#endif + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) +# include +#endif + +namespace boost +{ + + // + // boost::hash_value + // + + // integral types + // in detail/hash_integral.hpp + + // enumeration types + + template + typename std::enable_if::value, std::size_t>::type + hash_value( T v ) + { + // This should in principle return the equivalent of + // + // boost::hash_value( to_underlying(v) ); + // + // However, the C++03 implementation of underlying_type, + // + // conditional, make_signed, make_unsigned>::type::type + // + // generates a legitimate -Wconversion warning in is_signed, + // because -1 is not a valid enum value when all the enumerators + // are nonnegative. + // + // So the legacy implementation will have to do for now. + + return static_cast( v ); + } + + // floating point types + + namespace hash_detail + { + template::digits> + struct hash_float_impl; + + // float + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + std::uint32_t w; + std::memcpy( &w, &v, sizeof( v ) ); + + return w; + } + }; + + // double + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + std::uint64_t w; + std::memcpy( &w, &v, sizeof( v ) ); + + return hash_value( w ); + } + }; + + // 80 bit long double in 12 bytes + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + std::uint64_t w[ 2 ] = {}; + std::memcpy( &w, &v, 80 / CHAR_BIT ); + + std::size_t seed = 0; + + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + + return seed; + } + }; + + // 80 bit long double in 16 bytes + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + std::uint64_t w[ 2 ] = {}; + std::memcpy( &w, &v, 80 / CHAR_BIT ); + + std::size_t seed = 0; + + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + + return seed; + } + }; + + // 128 bit long double + template struct hash_float_impl + { + static std::size_t fn( T v ) + { + std::uint64_t w[ 2 ]; + std::memcpy( &w, &v, sizeof( v ) ); + + std::size_t seed = 0; + +#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ + + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + +#else + + seed = hash_value( w[0] ) + hash_detail::hash_mix( seed ); + seed = hash_value( w[1] ) + hash_detail::hash_mix( seed ); + +#endif + return seed; + } + }; + + } // namespace hash_detail + + template + typename std::enable_if::value, std::size_t>::type + hash_value( T v ) + { + return boost::hash_detail::hash_float_impl::fn( v + 0 ); + } + + // pointer types + + // `x + (x >> 3)` adjustment by Alberto Barbati and Dave Harris. + template std::size_t hash_value( T* const& v ) + { + std::uintptr_t x = reinterpret_cast( v ); + return boost::hash_value( x + (x >> 3) ); + } + + // array types + + template + inline std::size_t hash_value( T const (&x)[ N ] ) + { + return boost::hash_range( x, x + N ); + } + + template + inline std::size_t hash_value( T (&x)[ N ] ) + { + return boost::hash_range( x, x + N ); + } + + // complex + + template + std::size_t hash_value( std::complex const& v ) + { + std::size_t re = boost::hash()( v.real() ); + std::size_t im = boost::hash()( v.imag() ); + + return re + hash_detail::hash_mix( im ); + } + + // pair + + template + std::size_t hash_value( std::pair const& v ) + { + std::size_t seed = 0; + + boost::hash_combine( seed, v.first ); + boost::hash_combine( seed, v.second ); + + return seed; + } + + // ranges (list, set, deque...) + + template + typename std::enable_if::value && !container_hash::is_contiguous_range::value && !container_hash::is_unordered_range::value, std::size_t>::type + hash_value( T const& v ) + { + return boost::hash_range( v.begin(), v.end() ); + } + + // contiguous ranges (string, vector, array) + + template + typename std::enable_if::value, std::size_t>::type + hash_value( T const& v ) + { + return boost::hash_range( v.data(), v.data() + v.size() ); + } + + // unordered ranges (unordered_set, unordered_map) + + template + typename std::enable_if::value, std::size_t>::type + hash_value( T const& v ) + { + return boost::hash_unordered_range( v.begin(), v.end() ); + } + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ( \ + ( defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142 ) || \ + ( !defined(_MSVC_STL_VERSION) && defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 ) ) + + // resolve ambiguity with unconstrained stdext::hash_value in :-/ + + template class L, class... T> + typename std::enable_if>::value && !container_hash::is_contiguous_range>::value && !container_hash::is_unordered_range>::value, std::size_t>::type + hash_value( L const& v ) + { + return boost::hash_range( v.begin(), v.end() ); + } + + // contiguous ranges (string, vector, array) + + template class L, class... T> + typename std::enable_if>::value, std::size_t>::type + hash_value( L const& v ) + { + return boost::hash_range( v.data(), v.data() + v.size() ); + } + + template class L, class T, std::size_t N> + typename std::enable_if>::value, std::size_t>::type + hash_value( L const& v ) + { + return boost::hash_range( v.data(), v.data() + v.size() ); + } + + // unordered ranges (unordered_set, unordered_map) + + template class L, class... T> + typename std::enable_if>::value, std::size_t>::type + hash_value( L const& v ) + { + return boost::hash_unordered_range( v.begin(), v.end() ); + } + +#endif + + // described classes + +#if defined(BOOST_DESCRIBE_CXX14) + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(push) +# pragma warning(disable: 4100) // unreferenced formal parameter +#endif + + template + typename std::enable_if::value, std::size_t>::type + hash_value( T const& v ) + { + static_assert( !std::is_union::value, "described unions are not supported" ); + + std::size_t r = 0; + + using Bd = describe::describe_bases; + + mp11::mp_for_each([&](auto D){ + + using B = typename decltype(D)::type; + boost::hash_combine( r, (B const&)v ); + + }); + + using Md = describe::describe_members; + + mp11::mp_for_each([&](auto D){ + + boost::hash_combine( r, v.*D.pointer ); + + }); + + return r; + } + +#if defined(_MSC_VER) && _MSC_VER == 1900 +# pragma warning(pop) +#endif + +#endif + + // std::unique_ptr, std::shared_ptr + +#if !defined(BOOST_NO_CXX11_SMART_PTR) + + template + std::size_t hash_value( std::shared_ptr const& x ) + { + return boost::hash_value( x.get() ); + } + + template + std::size_t hash_value( std::unique_ptr const& x ) + { + return boost::hash_value( x.get() ); + } + +#endif + + // std::type_index + +#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) + + inline std::size_t hash_value( std::type_index const& v ) + { + return v.hash_code(); + } + +#endif + + // std::error_code, std::error_condition + +#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) + + inline std::size_t hash_value( std::error_code const& v ) + { + std::size_t seed = 0; + + boost::hash_combine( seed, v.value() ); + boost::hash_combine( seed, &v.category() ); + + return seed; + } + + inline std::size_t hash_value( std::error_condition const& v ) + { + std::size_t seed = 0; + + boost::hash_combine( seed, v.value() ); + boost::hash_combine( seed, &v.category() ); + + return seed; + } + +#endif + + // std::nullptr_t + +#if !defined(BOOST_NO_CXX11_NULLPTR) + + template + typename std::enable_if::value, std::size_t>::type + hash_value( T const& /*v*/ ) + { + return boost::hash_value( static_cast( nullptr ) ); + } + +#endif + + // std::optional + +#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL) + + template + std::size_t hash_value( std::optional const& v ) + { + if( !v ) + { + // Arbitrary value for empty optional. + return 0x12345678; + } + else + { + return boost::hash()(*v); + } + } + +#endif + + // std::variant + +#if !defined(BOOST_NO_CXX17_HDR_VARIANT) + + inline std::size_t hash_value( std::monostate ) + { + return 0x87654321; + } + + template + std::size_t hash_value( std::variant const& v ) + { + std::size_t seed = 0; + + hash_combine( seed, v.index() ); + std::visit( [&seed](auto&& x) { hash_combine(seed, x); }, v ); + + return seed; + } + +#endif + + // + // boost::hash_combine + // + + template + inline void hash_combine( std::size_t& seed, T const& v ) + { + seed = boost::hash_detail::hash_mix( seed + 0x9e3779b9 + boost::hash()( v ) ); + } + + // + // boost::hash_range + // + + template + inline void hash_range( std::size_t& seed, It first, It last ) + { + seed = hash_detail::hash_range( seed, first, last ); + } + + template + inline std::size_t hash_range( It first, It last ) + { + std::size_t seed = 0; + + hash_range( seed, first, last ); + + return seed; + } + + // + // boost::hash_unordered_range + // + + template + inline void hash_unordered_range( std::size_t& seed, It first, It last ) + { + std::size_t r = 0; + std::size_t const s2( seed ); + + for( ; first != last; ++first ) + { + std::size_t s3( s2 ); + + hash_combine::value_type>( s3, *first ); + + r += s3; + } + + seed += r; + } + + template + inline std::size_t hash_unordered_range( It first, It last ) + { + std::size_t seed = 0; + + hash_unordered_range( seed, first, last ); + + return seed; + } + + // + // boost::hash + // + + template struct hash + { + typedef T argument_type; + typedef std::size_t result_type; + + std::size_t operator()( T const& val ) const + { + return hash_value( val ); + } + }; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ( \ + ( defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142 ) || \ + ( !defined(_MSVC_STL_VERSION) && defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 ) ) + + // Dinkumware has stdext::hash_value for basic_string in :-/ + + template struct hash< std::basic_string > + { + typedef std::basic_string argument_type; + typedef std::size_t result_type; + + std::size_t operator()( std::basic_string const& val ) const + { + return boost::hash_value( val ); + } + }; + +#endif + + // boost::unordered::hash_is_avalanching + + namespace unordered + { + template struct hash_is_avalanching; + template struct hash_is_avalanching< boost::hash< std::basic_string > >: std::is_integral {}; + +#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) + + template struct hash_is_avalanching< boost::hash< std::basic_string_view > >: std::is_integral {}; + +#endif + } // namespace unordered + +} // namespace boost + +#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP diff --git a/src/boost/container_hash/hash_fwd.hpp b/src/boost/container_hash/hash_fwd.hpp new file mode 100644 index 00000000..32388ac5 --- /dev/null +++ b/src/boost/container_hash/hash_fwd.hpp @@ -0,0 +1,37 @@ +// Copyright 2005-2009 Daniel James. +// Copyright 2021, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP +#define BOOST_FUNCTIONAL_HASH_FWD_HPP + +#include + +namespace boost +{ + +namespace container_hash +{ + +template struct is_range; +template struct is_contiguous_range; +template struct is_unordered_range; +template struct is_described_class; +template struct is_tuple_like; + +} // namespace container_hash + +template struct hash; + +template void hash_combine( std::size_t& seed, T const& v ); + +template void hash_range( std::size_t&, It, It ); +template std::size_t hash_range( It, It ); + +template void hash_unordered_range( std::size_t&, It, It ); +template std::size_t hash_unordered_range( It, It ); + +} // namespace boost + +#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP diff --git a/src/boost/container_hash/is_contiguous_range.hpp b/src/boost/container_hash/is_contiguous_range.hpp new file mode 100644 index 00000000..c18db6b2 --- /dev/null +++ b/src/boost/container_hash/is_contiguous_range.hpp @@ -0,0 +1,98 @@ +// Copyright 2017, 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED +#define BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED + +#include +#include +#include +#include + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +#include + +namespace boost +{ +namespace hash_detail +{ + +template + std::integral_constant< bool, std::is_same::value_type, T>::value && std::is_integral::value > + is_contiguous_range_check( It first, It last, T const*, T const*, S ); + +template decltype( is_contiguous_range_check( std::declval().begin(), std::declval().end(), std::declval().data(), std::declval().data() + std::declval().size(), std::declval().size() ) ) is_contiguous_range_( int ); +template std::false_type is_contiguous_range_( ... ); + +template struct is_contiguous_range: decltype( hash_detail::is_contiguous_range_( 0 ) ) +{ +}; + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_contiguous_range: std::integral_constant< bool, is_range::value && hash_detail::is_contiguous_range::value > +{ +}; + +} // namespace container_hash +} // namespace boost + +#else // !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +#include +#include +#include +#include + +namespace boost +{ +namespace container_hash +{ + +template struct is_contiguous_range: std::false_type +{ +}; + +template struct is_contiguous_range< std::basic_string >: std::true_type +{ +}; + +template struct is_contiguous_range< std::basic_string const >: std::true_type +{ +}; + +template struct is_contiguous_range< std::vector >: std::true_type +{ +}; + +template struct is_contiguous_range< std::vector const >: std::true_type +{ +}; + +template struct is_contiguous_range< std::vector >: std::false_type +{ +}; + +template struct is_contiguous_range< std::vector const >: std::false_type +{ +}; + +template struct is_contiguous_range< std::array >: std::true_type +{ +}; + +template struct is_contiguous_range< std::array const >: std::true_type +{ +}; + +} // namespace container_hash +} // namespace boost + +#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + +#endif // #ifndef BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED diff --git a/src/boost/container_hash/is_described_class.hpp b/src/boost/container_hash/is_described_class.hpp new file mode 100644 index 00000000..88f8ed37 --- /dev/null +++ b/src/boost/container_hash/is_described_class.hpp @@ -0,0 +1,37 @@ +// Copyright 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED +#define BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED + +#include +#include +#include + +namespace boost +{ +namespace container_hash +{ + +#if defined(BOOST_DESCRIBE_CXX11) + +template struct is_described_class: std::integral_constant::value && + describe::has_describe_members::value && + !std::is_union::value> +{ +}; + +#else + +template struct is_described_class: std::false_type +{ +}; + +#endif + +} // namespace container_hash +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED diff --git a/src/boost/container_hash/is_range.hpp b/src/boost/container_hash/is_range.hpp new file mode 100644 index 00000000..e6adbce5 --- /dev/null +++ b/src/boost/container_hash/is_range.hpp @@ -0,0 +1,41 @@ +// Copyright 2017 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_RANGE_HPP_INCLUDED +#define BOOST_HASH_IS_RANGE_HPP_INCLUDED + +#include +#include + +namespace boost +{ + +namespace hash_detail +{ + +template struct iterator_traits: std::iterator_traits {}; +template<> struct iterator_traits< void* > {}; +template<> struct iterator_traits< void const* > {}; + +template + std::integral_constant< bool, !std::is_same::type, typename iterator_traits::value_type>::value > + is_range_check( It first, It last ); + +template decltype( is_range_check( std::declval().begin(), std::declval().end() ) ) is_range_( int ); +template std::false_type is_range_( ... ); + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_range: decltype( hash_detail::is_range_( 0 ) ) +{ +}; + +} // namespace container_hash + +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_RANGE_HPP_INCLUDED diff --git a/src/boost/container_hash/is_tuple_like.hpp b/src/boost/container_hash/is_tuple_like.hpp new file mode 100644 index 00000000..bd34ee8c --- /dev/null +++ b/src/boost/container_hash/is_tuple_like.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED +#define BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED + +// Copyright 2017, 2022 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct is_tuple_like_: std::false_type +{ +}; + +template struct is_tuple_like_::value == std::tuple_size::value> >: std::true_type +{ +}; + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_tuple_like: hash_detail::is_tuple_like_< typename std::remove_cv::type > +{ +}; + +} // namespace container_hash +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED diff --git a/src/boost/container_hash/is_unordered_range.hpp b/src/boost/container_hash/is_unordered_range.hpp new file mode 100644 index 00000000..5a81b7d5 --- /dev/null +++ b/src/boost/container_hash/is_unordered_range.hpp @@ -0,0 +1,38 @@ +// Copyright 2017 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED +#define BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED + +#include +#include + +namespace boost +{ +namespace hash_detail +{ + +template struct has_hasher_: std::false_type +{ +}; + +template struct has_hasher_< T, std::integral_constant< bool, + std::is_same::value + > >: std::true_type +{ +}; + +} // namespace hash_detail + +namespace container_hash +{ + +template struct is_unordered_range: std::integral_constant< bool, is_range::value && hash_detail::has_hasher_::value > +{ +}; + +} // namespace container_hash +} // namespace boost + +#endif // #ifndef BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED diff --git a/src/boost/core/addressof.hpp b/src/boost/core/addressof.hpp new file mode 100644 index 00000000..5473c36a --- /dev/null +++ b/src/boost/core/addressof.hpp @@ -0,0 +1,274 @@ +/* +Copyright (C) 2002 Brad King (brad.king@kitware.com) + Douglas Gregor (gregod@cs.rpi.edu) + +Copyright (C) 2002, 2008, 2013 Peter Dimov + +Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com) + +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) +*/ + +#ifndef BOOST_CORE_ADDRESSOF_HPP +#define BOOST_CORE_ADDRESSOF_HPP + +#include + +#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215 +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#elif defined(BOOST_GCC) && BOOST_GCC >= 70000 +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#elif defined(__has_builtin) +#if __has_builtin(__builtin_addressof) +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#endif +#endif + +#if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF) +#if defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF +#endif + +namespace boost { + +template +BOOST_CONSTEXPR inline T* +addressof(T& o) BOOST_NOEXCEPT +{ + return __builtin_addressof(o); +} + +} /* boost */ +#else +#include +#include + +namespace boost { +namespace detail { + +template +class addrof_ref { +public: + BOOST_FORCEINLINE addrof_ref(T& o) BOOST_NOEXCEPT + : o_(o) { } + BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT { + return o_; + } +private: + addrof_ref& operator=(const addrof_ref&); + T& o_; +}; + +template +struct addrof { + static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT { + return reinterpret_cast(& + const_cast(reinterpret_cast(o))); + } + static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT { + return p; + } +}; + +#if !defined(BOOST_NO_CXX11_NULLPTR) +#if !defined(BOOST_NO_CXX11_DECLTYPE) && \ + (defined(__INTEL_COMPILER) || \ + (defined(__clang__) && !defined(_LIBCPP_VERSION))) +typedef decltype(nullptr) addrof_null_t; +#else +typedef std::nullptr_t addrof_null_t; +#endif + +template<> +struct addrof { + typedef addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; + +template<> +struct addrof { + typedef const addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; + +template<> +struct addrof { + typedef volatile addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; + +template<> +struct addrof { + typedef const volatile addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; +#endif + +} /* detail */ + +#if defined(BOOST_NO_CXX11_SFINAE_EXPR) || \ + defined(BOOST_NO_CXX11_CONSTEXPR) || \ + defined(BOOST_NO_CXX11_DECLTYPE) +#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF + +template +BOOST_FORCEINLINE T* +addressof(T& o) BOOST_NOEXCEPT +{ +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) || \ + BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120) + return boost::detail::addrof::get(o, 0); +#else + return boost::detail::addrof::get(boost::detail::addrof_ref(o), 0); +#endif +} + +#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) +namespace detail { + +template +struct addrof_result { + typedef T* type; +}; + +} /* detail */ + +template +BOOST_FORCEINLINE typename boost::detail::addrof_result::type +addressof(T (&o)[N]) BOOST_NOEXCEPT +{ + return &o; +} +#endif + +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) +template +BOOST_FORCEINLINE +T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N] +{ + return reinterpret_cast(&o); +} + +template +BOOST_FORCEINLINE +const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N] +{ + return reinterpret_cast(&o); +} +#endif +#else +namespace detail { + +template +T addrof_declval() BOOST_NOEXCEPT; + +template +struct addrof_void { + typedef void type; +}; + +template +struct addrof_member_operator { + static constexpr bool value = false; +}; + +template +struct addrof_member_operator().operator&())>::type> { + static constexpr bool value = true; +}; + +#if BOOST_WORKAROUND(BOOST_INTEL, < 1600) +struct addrof_addressable { }; + +addrof_addressable* +operator&(addrof_addressable&) BOOST_NOEXCEPT; +#endif + +template +struct addrof_non_member_operator { + static constexpr bool value = false; +}; + +template +struct addrof_non_member_operator()))>::type> { + static constexpr bool value = true; +}; + +template +struct addrof_expression { + static constexpr bool value = false; +}; + +template +struct addrof_expression())>::type> { + static constexpr bool value = true; +}; + +template +struct addrof_is_constexpr { + static constexpr bool value = addrof_expression::value && + !addrof_member_operator::value && + !addrof_non_member_operator::value; +}; + +template +struct addrof_if { }; + +template +struct addrof_if { + typedef T* type; +}; + +template +BOOST_FORCEINLINE +typename addrof_if::value, T>::type +addressof(T& o) BOOST_NOEXCEPT +{ + return addrof::get(addrof_ref(o), 0); +} + +template +constexpr BOOST_FORCEINLINE +typename addrof_if::value, T>::type +addressof(T& o) BOOST_NOEXCEPT +{ + return &o; +} + +} /* detail */ + +template +constexpr BOOST_FORCEINLINE T* +addressof(T& o) BOOST_NOEXCEPT +{ + return boost::detail::addressof(o); +} +#endif + +} /* boost */ +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +namespace boost { + +template +const T* addressof(const T&&) = delete; + +} /* boost */ +#endif + +#endif diff --git a/src/boost/core/allocator_access.hpp b/src/boost/core/allocator_access.hpp new file mode 100644 index 00000000..0f0ed325 --- /dev/null +++ b/src/boost/core/allocator_access.hpp @@ -0,0 +1,834 @@ +/* +Copyright 2020-2022 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_ALLOCATOR_ACCESS_HPP +#define BOOST_CORE_ALLOCATOR_ACCESS_HPP + +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#include +#endif +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#endif + +#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40300) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_CLANG) && !defined(__CUDACC__) +#if __has_feature(is_empty) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#endif +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __oracle_is_empty(T) +#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#elif defined(BOOST_CODEGEARC) +#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T) +#endif + +#if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#endif +#if defined(_STL_DISABLE_DEPRECATED_WARNING) +_STL_DISABLE_DEPRECATED_WARNING +#endif +#if defined(__clang__) && defined(__has_warning) +# if __has_warning("-Wdeprecated-declarations") +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +# endif +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4996) +#elif defined(BOOST_GCC) && BOOST_GCC >= 40600 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +namespace boost { + +template +struct allocator_value_type { + typedef typename A::value_type type; +}; + +namespace detail { + +template +struct alloc_ptr { + typedef typename boost::allocator_value_type::type* type; +}; + +template +struct alloc_void { + typedef void type; +}; + +template +struct alloc_ptr::type> { + typedef typename A::pointer type; +}; + +} /* detail */ + +template +struct allocator_pointer { + typedef typename detail::alloc_ptr::type type; +}; + +namespace detail { + +template +struct alloc_const_ptr { + typedef typename boost::pointer_traits::type>::template rebind_to::type>::type type; +}; + +template +struct alloc_const_ptr::type> { + typedef typename A::const_pointer type; +}; + +} /* detail */ + +template +struct allocator_const_pointer { + typedef typename detail::alloc_const_ptr::type type; +}; + +namespace detail { + +template +struct alloc_to { }; + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template class A, class T, class U> +struct alloc_to, T> { + typedef A type; +}; + +template class A, class T, class U, class V> +struct alloc_to, T> { + typedef A type; +}; + +template class A, class T, class U, class V1, + class V2> +struct alloc_to, T> { + typedef A type; +}; +#else +template class A, class T, class U, class... V> +struct alloc_to, T> { + typedef A type; +}; +#endif + +template +struct alloc_rebind { + typedef typename alloc_to::type type; +}; + +template +struct alloc_rebind::other>::type> { + typedef typename A::template rebind::other type; +}; + +} /* detail */ + +template +struct allocator_rebind { + typedef typename detail::alloc_rebind::type type; +}; + +namespace detail { + +template +struct alloc_void_ptr { + typedef typename boost::pointer_traits::type>::template + rebind_to::type type; +}; + +template +struct alloc_void_ptr::type> { + typedef typename A::void_pointer type; +}; + +} /* detail */ + +template +struct allocator_void_pointer { + typedef typename detail::alloc_void_ptr::type type; +}; + +namespace detail { + +template +struct alloc_const_void_ptr { + typedef typename boost::pointer_traits::type>::template + rebind_to::type type; +}; + +template +struct alloc_const_void_ptr::type> { + typedef typename A::const_void_pointer type; +}; + +} /* detail */ + +template +struct allocator_const_void_pointer { + typedef typename detail::alloc_const_void_ptr::type type; +}; + +namespace detail { + +template +struct alloc_diff_type { + typedef typename boost::pointer_traits::type>::difference_type type; +}; + +template +struct alloc_diff_type::type> { + typedef typename A::difference_type type; +}; + +} /* detail */ + +template +struct allocator_difference_type { + typedef typename detail::alloc_diff_type::type type; +}; + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_size_type { + typedef std::size_t type; +}; +#else +template +struct alloc_size_type { + typedef typename std::make_unsigned::type>::type type; +}; +#endif + +template +struct alloc_size_type::type> { + typedef typename A::size_type type; +}; + +} /* detail */ + +template +struct allocator_size_type { + typedef typename detail::alloc_size_type::type type; +}; + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_bool { + typedef bool value_type; + typedef alloc_bool type; + + static const bool value = V; + + operator bool() const BOOST_NOEXCEPT { + return V; + } + + bool operator()() const BOOST_NOEXCEPT { + return V; + } +}; + +template +const bool alloc_bool::value; + +typedef alloc_bool alloc_false; +#else +typedef std::false_type alloc_false; +#endif + +template +struct alloc_pocca { + typedef alloc_false type; +}; + +template +struct alloc_pocca::type> { + typedef typename A::propagate_on_container_copy_assignment type; +}; + +} /* detail */ + +template +struct allocator_propagate_on_container_copy_assignment { + typedef typename detail::alloc_pocca::type type; +}; + +namespace detail { + +template +struct alloc_pocma { + typedef alloc_false type; +}; + +template +struct alloc_pocma::type> { + typedef typename A::propagate_on_container_move_assignment type; +}; + +} /* detail */ + +template +struct allocator_propagate_on_container_move_assignment { + typedef typename detail::alloc_pocma::type type; +}; + +namespace detail { + +template +struct alloc_pocs { + typedef alloc_false type; +}; + +template +struct alloc_pocs::type> { + typedef typename A::propagate_on_container_swap type; +}; + +} /* detail */ + +template +struct allocator_propagate_on_container_swap { + typedef typename detail::alloc_pocs::type type; +}; + +namespace detail { + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_equal { + typedef typename std::is_empty::type type; +}; +#elif defined(BOOST_DETAIL_ALLOC_EMPTY) +template +struct alloc_equal { + typedef alloc_bool type; +}; +#else +template +struct alloc_equal { + typedef alloc_false type; +}; +#endif + +template +struct alloc_equal::type> { + typedef typename A::is_always_equal type; +}; + +} /* detail */ + +template +struct allocator_is_always_equal { + typedef typename detail::alloc_equal::type type; +}; + +template +inline typename allocator_pointer::type +allocator_allocate(A& a, typename allocator_size_type::type n) +{ + return a.allocate(n); +} + +template +inline void +allocator_deallocate(A& a, typename allocator_pointer::type p, + typename allocator_size_type::type n) +{ + a.deallocate(p, n); +} + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline typename allocator_pointer::type +allocator_allocate(A& a, typename allocator_size_type::type n, + typename allocator_const_void_pointer::type h) +{ + return a.allocate(n, h); +} +#else +namespace detail { + +template +struct alloc_no { + char x, y; +}; + +template +class alloc_has_allocate { + template + static auto check(int) + -> alloc_no().allocate(std::declval::type>(), std::declval::type>()))>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; + +} /* detail */ + +template +inline typename std::enable_if::value, + typename allocator_pointer::type>::type +allocator_allocate(A& a, typename allocator_size_type::type n, + typename allocator_const_void_pointer::type h) +{ + return a.allocate(n, h); +} + +template +inline typename std::enable_if::value, + typename allocator_pointer::type>::type +allocator_allocate(A& a, typename allocator_size_type::type n, + typename allocator_const_void_pointer::type) +{ + return a.allocate(n); +} +#endif + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_has_construct { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template +struct alloc_has_construct::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#else +template +class alloc_has_construct { + template + static auto check(int) + -> alloc_no().construct(std::declval(), + std::declval()...))>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +template +struct alloc_if { }; + +template +struct alloc_if { + typedef T type; +}; + +} /* detail */ + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline typename detail::alloc_if::value>::type +allocator_construct(A& a, T* p) +{ + a.construct(p); +} + +template +inline typename detail::alloc_if::value>::type +allocator_construct(A&, T* p) +{ + ::new((void*)p) T(); +} + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline void +allocator_construct(A&, T* p, V&& v, Args&&... args) +{ + ::new((void*)p) T(std::forward(v), std::forward(args)...); +} +#else +template +inline void +allocator_construct(A&, T* p, V&& v) +{ + ::new((void*)p) T(std::forward(v)); +} +#endif +#else +template +inline void +allocator_construct(A&, T* p, const V& v) +{ + ::new((void*)p) T(v); +} + +template +inline void +allocator_construct(A&, T* p, V& v) +{ + ::new((void*)p) T(v); +} +#endif +#else +template +inline typename std::enable_if::value>::type +allocator_construct(A& a, T* p, Args&&... args) +{ + a.construct(p, std::forward(args)...); +} + +template +inline typename std::enable_if::value>::type +allocator_construct(A&, T* p, Args&&... args) +{ + ::new((void*)p) T(std::forward(args)...); +} +#endif + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_has_destroy { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template +struct alloc_has_destroy::type> { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#else +template +class alloc_has_destroy { + template + static auto check(int) + -> alloc_no().destroy(std::declval()))>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value>::type +allocator_destroy(A& a, T* p) +{ + a.destroy(p); +} + +template +inline typename detail::alloc_if::value>::type +allocator_destroy(A&, T* p) +{ + p->~T(); + (void)p; +} + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct alloc_no { + char x, y; +}; + +template +class alloc_has_max_size { + template + static alloc_no::type(O::*)(), + &O::max_size> check(int); + + template + static alloc_no::type(O::*)() const, + &O::max_size> check(int); + + template + static alloc_no::type(*)(), + &O::max_size> check(int); + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#else +template +class alloc_has_max_size { + template + static auto check(int) + -> alloc_no().max_size())>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value, + typename allocator_size_type::type>::type +allocator_max_size(const A& a) BOOST_NOEXCEPT +{ + return a.max_size(); +} + +template +inline typename detail::alloc_if::value, + typename allocator_size_type::type>::type +allocator_max_size(const A&) BOOST_NOEXCEPT +{ + return (std::numeric_limits::type>::max)() / + sizeof(typename allocator_value_type::type); +} + +namespace detail { + +#if defined(BOOST_NO_CXX11_ALLOCATOR) +template +class alloc_has_soccc { + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static alloc_no + check(int); + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#else +template +class alloc_has_soccc { + template + static auto check(int) -> alloc_no().select_on_container_copy_construction())>; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; +#endif + +} /* detail */ + +template +inline typename detail::alloc_if::value, A>::type +allocator_select_on_container_copy_construction(const A& a) +{ + return a.select_on_container_copy_construction(); +} + +template +inline typename detail::alloc_if::value, A>::type +allocator_select_on_container_copy_construction(const A& a) +{ + return a; +} + +template +inline void +allocator_destroy_n(A& a, T* p, std::size_t n) +{ + while (n > 0) { + boost::allocator_destroy(a, p + --n); + } +} + +namespace detail { + +template +class alloc_destroyer { +public: + alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT + : a_(a), p_(p), n_(0) { } + + ~alloc_destroyer() { + boost::allocator_destroy_n(a_, p_, n_); + } + + std::size_t& size() BOOST_NOEXCEPT { + return n_; + } + +private: + alloc_destroyer(const alloc_destroyer&); + alloc_destroyer& operator=(const alloc_destroyer&); + + A& a_; + T* p_; + std::size_t n_; +}; + +} /* detail */ + +template +inline void +allocator_construct_n(A& a, T* p, std::size_t n) +{ + detail::alloc_destroyer d(a, p); + for (std::size_t& i = d.size(); i < n; ++i) { + boost::allocator_construct(a, p + i); + } + d.size() = 0; +} + +template +inline void +allocator_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m) +{ + detail::alloc_destroyer d(a, p); + for (std::size_t& i = d.size(); i < n; ++i) { + boost::allocator_construct(a, p + i, l[i % m]); + } + d.size() = 0; +} + +template +inline void +allocator_construct_n(A& a, T* p, std::size_t n, I b) +{ + detail::alloc_destroyer d(a, p); + for (std::size_t& i = d.size(); i < n; void(++i), void(++b)) { + boost::allocator_construct(a, p + i, *b); + } + d.size() = 0; +} + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template +using allocator_value_type_t = typename allocator_value_type::type; + +template +using allocator_pointer_t = typename allocator_pointer::type; + +template +using allocator_const_pointer_t = typename allocator_const_pointer::type; + +template +using allocator_void_pointer_t = typename allocator_void_pointer::type; + +template +using allocator_const_void_pointer_t = + typename allocator_const_void_pointer::type; + +template +using allocator_difference_type_t = + typename allocator_difference_type::type; + +template +using allocator_size_type_t = typename allocator_size_type::type; + +template +using allocator_propagate_on_container_copy_assignment_t = + typename allocator_propagate_on_container_copy_assignment::type; + +template +using allocator_propagate_on_container_move_assignment_t = + typename allocator_propagate_on_container_move_assignment::type; + +template +using allocator_propagate_on_container_swap_t = + typename allocator_propagate_on_container_swap::type; + +template +using allocator_is_always_equal_t = + typename allocator_is_always_equal::type; + +template +using allocator_rebind_t = typename allocator_rebind::type; +#endif + +} /* boost */ + +#if defined(__clang__) && defined(__has_warning) +# if __has_warning("-Wdeprecated-declarations") +# pragma clang diagnostic pop +# endif +#elif defined(_MSC_VER) +# pragma warning(pop) +#elif defined(BOOST_GCC) && BOOST_GCC >= 40600 +# pragma GCC diagnostic pop +#endif +#if defined(_STL_RESTORE_DEPRECATED_WARNING) +_STL_RESTORE_DEPRECATED_WARNING +#endif +#if defined(_LIBCPP_SUPPRESS_DEPRECATED_POP) +_LIBCPP_SUPPRESS_DEPRECATED_POP +#endif + +#endif diff --git a/src/boost/core/allocator_traits.hpp b/src/boost/core/allocator_traits.hpp new file mode 100644 index 00000000..bf8749d8 --- /dev/null +++ b/src/boost/core/allocator_traits.hpp @@ -0,0 +1,112 @@ +/* +Copyright 2021 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_ALLOCATOR_TRAITS_HPP +#define BOOST_CORE_ALLOCATOR_TRAITS_HPP + +#include + +namespace boost { + +template +struct allocator_traits { + typedef A allocator_type; + + typedef typename allocator_value_type::type value_type; + + typedef typename allocator_pointer::type pointer; + + typedef typename allocator_const_pointer::type const_pointer; + + typedef typename allocator_void_pointer::type void_pointer; + + typedef typename allocator_const_void_pointer::type const_void_pointer; + + typedef typename allocator_difference_type::type difference_type; + + typedef typename allocator_size_type::type size_type; + + typedef typename allocator_propagate_on_container_copy_assignment::type + propagate_on_container_copy_assignment; + + typedef typename allocator_propagate_on_container_move_assignment::type + propagate_on_container_move_assignment; + + typedef typename allocator_propagate_on_container_swap::type + propagate_on_container_swap; + + typedef typename allocator_is_always_equal::type is_always_equal; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + template + using rebind_traits = allocator_traits::type>; +#else + template + struct rebind_traits + : allocator_traits::type> { }; +#endif + + static pointer allocate(A& a, size_type n) { + return boost::allocator_allocate(a, n); + } + + static pointer allocate(A& a, size_type n, const_void_pointer h) { + return boost::allocator_allocate(a, n, h); + } + + static void deallocate(A& a, pointer p, size_type n) { + return boost::allocator_deallocate(a, p, n); + } + + template + static void construct(A& a, T* p) { + boost::allocator_construct(a, p); + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + static void construct(A& a, T* p, V&& v, Args&&... args) { + boost::allocator_construct(a, p, std::forward(v), + std::forward(args)...); + } +#else + template + static void construct(A& a, T* p, V&& v) { + boost::allocator_construct(a, p, std::forward(v)); + } +#endif +#else + template + static void construct(A& a, T* p, const V& v) { + boost::allocator_construct(a, p, v); + } + + template + static void construct(A& a, T* p, V& v) { + boost::allocator_construct(a, p, v); + } +#endif + + template + static void destroy(A& a, T* p) { + boost::allocator_destroy(a, p); + } + + static size_type max_size(const A& a) BOOST_NOEXCEPT { + return boost::allocator_max_size(a); + } + + static A select_on_container_copy_construction(const A& a) { + return boost::allocator_select_on_container_copy_construction(a); + } +}; + +} /* boost */ + +#endif diff --git a/src/boost/core/bit.hpp b/src/boost/core/bit.hpp new file mode 100644 index 00000000..cebc8787 --- /dev/null +++ b/src/boost/core/bit.hpp @@ -0,0 +1,954 @@ +#ifndef BOOST_CORE_BIT_HPP_INCLUDED +#define BOOST_CORE_BIT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/core/bit.hpp +// +// A portable version of the C++20 standard header +// +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) + +# include +# pragma intrinsic(_BitScanForward) +# pragma intrinsic(_BitScanReverse) + +# if defined(_M_X64) +# pragma intrinsic(_BitScanForward64) +# pragma intrinsic(_BitScanReverse64) +# endif + +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4244) // conversion from int to T + +#endif // defined(_MSC_VER) + +#if defined(BOOST_MSVC) && BOOST_MSVC >= 1925 +# define BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL +#endif + +#if defined(__has_builtin) +# if __has_builtin(__builtin_bit_cast) +# define BOOST_CORE_HAS_BUILTIN_BIT_CAST +# endif +# if __has_builtin(__builtin_bswap16) +# define BOOST_CORE_HAS_BUILTIN_BSWAP16 +# endif +#endif + +#if !defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST) && (defined(BOOST_MSVC) && BOOST_MSVC >= 1926) +# define BOOST_CORE_HAS_BUILTIN_BIT_CAST +#endif + +#if !defined(BOOST_CORE_HAS_BUILTIN_BSWAP16) && (defined(BOOST_GCC) && BOOST_GCC >= 40800) +# define BOOST_CORE_HAS_BUILTIN_BSWAP16 +#endif + +namespace boost +{ +namespace core +{ + +// bit_cast + +#if defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST) + +template +BOOST_CONSTEXPR To bit_cast( From const & from ) BOOST_NOEXCEPT +{ + return __builtin_bit_cast( To, from ); +} + +#else + +template +To bit_cast( From const & from ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( sizeof(To) == sizeof(From) ); + + To to; + std::memcpy( &to, &from, sizeof(To) ); + return to; +} + +#endif + +// countl + +#if defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CONSTEXPR inline int countl_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ) - ( std::numeric_limits::digits - std::numeric_limits::digits ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ) - ( std::numeric_limits::digits - std::numeric_limits::digits ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return x? __builtin_clzl( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return x? __builtin_clzll( x ): std::numeric_limits::digits; +} + +} // namespace detail + +template +BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::detail::countl_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + constexpr unsigned char mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 }; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return mod37[ x % 37 ]; + } + else + { + unsigned long r; + + if( _BitScanReverse( &r, x ) ) + { + return 31 - static_cast( r ); + } + else + { + return 32; + } + } +} + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 24; +} + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 16; +} + +#elif defined(_MSC_VER) + +inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanReverse( &r, x ) ) + { + return 31 - static_cast( r ); + } + else + { + return 32; + } +} + +inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 24; +} + +inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 16; +} + +#else + +inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 }; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return mod37[ x % 37 ]; +} + +inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 24; +} + +inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 16; +} + +#endif + +#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + return static_cast( x >> 32 ) != 0? + boost::core::detail::countl_impl( static_cast( x >> 32 ) ): + boost::core::detail::countl_impl( static_cast( x ) ) + 32; + } + else + { + unsigned long r; + + if( _BitScanReverse64( &r, x ) ) + { + return 63 - static_cast( r ); + } + else + { + return 64; + } + } +} + +#elif defined(_MSC_VER) && defined(_M_X64) + +inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanReverse64( &r, x ) ) + { + return 63 - static_cast( r ); + } + else + { + return 64; + } +} + +#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x >> 32 ) != 0? + boost::core::detail::countl_impl( static_cast( x >> 32 ) ): + boost::core::detail::countl_impl( static_cast( x ) ) + 32; +} + +#else + +inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x >> 32 ) != 0? + boost::core::detail::countl_impl( static_cast( x >> 32 ) ): + boost::core::detail::countl_impl( static_cast( x ) ) + 32; +} + +#endif + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +template +BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::countl_zero( static_cast( ~x ) ); +} + +// countr + +#if defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CONSTEXPR inline int countr_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctzl( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctzll( x ): std::numeric_limits::digits; +} + +} // namespace detail + +template +BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::detail::countr_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + constexpr unsigned char mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 }; + return mod37[ ( -(boost::int32_t)x & x ) % 37 ]; + } + else + { + unsigned long r; + + if( _BitScanForward( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 32; + } + } +} + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x100 ); +} + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x10000 ); +} + +#elif defined(_MSC_VER) + +inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanForward( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 32; + } +} + +inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x100 ); +} + +inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x10000 ); +} + +#else + +inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 }; + return mod37[ ( -(boost::int32_t)x & x ) % 37 ]; +} + +inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x100 ); +} + +inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x10000 ); +} + +#endif + +#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + return static_cast( x ) != 0? + boost::core::detail::countr_impl( static_cast( x ) ): + boost::core::detail::countr_impl( static_cast( x >> 32 ) ) + 32; + } + else + { + unsigned long r; + + if( _BitScanForward64( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 64; + } + } +} + +#elif defined(_MSC_VER) && defined(_M_X64) + +inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + unsigned long r; + + if( _BitScanForward64( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 64; + } +} + +#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x ) != 0? + boost::core::detail::countr_impl( static_cast( x ) ): + boost::core::detail::countr_impl( static_cast( x >> 32 ) ) + 32; +} + +#else + +inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return static_cast( x ) != 0? + boost::core::detail::countr_impl( static_cast( x ) ): + boost::core::detail::countr_impl( static_cast( x >> 32 ) ) + 32; +} + +#endif + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +template +BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::countr_zero( static_cast( ~x ) ); +} + +// popcount + +#if defined(__GNUC__) || defined(__clang__) + +#if defined(__clang__) && __clang_major__ * 100 + __clang_minor__ < 304 +# define BOOST_CORE_POPCOUNT_CONSTEXPR +#else +# define BOOST_CORE_POPCOUNT_CONSTEXPR BOOST_CONSTEXPR +#endif + +namespace detail +{ + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return __builtin_popcountl( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return __builtin_popcountll( x ); +} + +} // namespace detail + +#undef BOOST_CORE_POPCOUNT_CONSTEXPR + +template +BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return boost::core::detail::popcount_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + x = x - ( ( x >> 1 ) & 0x55555555 ); + x = ( x & 0x33333333 ) + ( ( x >> 2 ) & 0x33333333 ); + x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F; + + return static_cast( ( x * 0x01010101 ) >> 24 ); +} + +BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + x = x - ( ( x >> 1 ) & 0x5555555555555555 ); + x = ( x & 0x3333333333333333 ) + ( ( x >> 2 ) & 0x3333333333333333 ); + x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F0F0F0F0F; + + return static_cast( ( x * 0x0101010101010101 ) >> 56 ); +} + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) ) + { + return boost::core::detail::popcount_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::popcount_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +// rotating + +template +BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + unsigned const mask = std::numeric_limits::digits - 1; + return static_cast( x << (static_cast( s ) & mask) | x >> (static_cast( -s ) & mask) ); +} + +template +BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + unsigned const mask = std::numeric_limits::digits - 1; + return static_cast( x >> (static_cast( s ) & mask) | x << (static_cast( -s ) & mask) ); +} + +// integral powers of 2 + +template +BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return x != 0 && ( x & ( x - 1 ) ) == 0; +} + +// bit_width returns `int` now, https://cplusplus.github.io/LWG/issue3656 +// has been applied to C++20 as a DR + +template +BOOST_CONSTEXPR int bit_width( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return std::numeric_limits::digits - boost::core::countl_zero( x ); +} + +template +BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + return x == 0? T(0): static_cast( T(1) << ( boost::core::bit_width( x ) - 1 ) ); +} + +namespace detail +{ + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t bit_ceil_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( x == 0 ) + { + return 0; + } + + --x; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + ++x; + + return x; +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( x == 0 ) + { + return 0; + } + + --x; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + + ++x; + + return x; +} + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer && !std::numeric_limits::is_signed ); + + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) ) + { + return static_cast( boost::core::detail::bit_ceil_impl( static_cast( x ) ) ); + } + else + { + return static_cast( boost::core::detail::bit_ceil_impl( static_cast( x ) ) ); + } +} + +// endian + +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big + +#elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER + +#elif defined(__LITTLE_ENDIAN__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#elif defined(__BIG_ENDIAN__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big + +#elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#else + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER + +#endif + +#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) + +enum class endian +{ + big, + little, + native BOOST_CORE_BIT_NATIVE_INITIALIZER +}; + +typedef endian endian_type; + +#else + +namespace endian +{ + +enum type +{ + big, + little, + native BOOST_CORE_BIT_NATIVE_INITIALIZER +}; + +} // namespace endian + +typedef endian::type endian_type; + +#endif + +#undef BOOST_CORE_BIT_NATIVE_INITIALIZER + +// byteswap + +namespace detail +{ + +BOOST_CONSTEXPR inline boost::uint8_t byteswap_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return x; +} + +#if defined(BOOST_CORE_HAS_BUILTIN_BSWAP16) + +BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return __builtin_bswap16( x ); +} + +#else + +BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return static_cast( x << 8 | x >> 8 ); +} + +#endif + +#if defined(__GNUC__) || defined(__clang__) + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + return __builtin_bswap32( x ); +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return __builtin_bswap64( x ); +} + +#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL) + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + boost::uint32_t step16 = x << 16 | x >> 16; + return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff); + } + else + { + return _byteswap_ulong( x ); + } +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( __builtin_is_constant_evaluated() ) + { + boost::uint64_t step32 = x << 32 | x >> 32; + boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; + return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8; + } + else + { + return _byteswap_uint64( x ); + } +} + +#elif defined(_MSC_VER) + +inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + return _byteswap_ulong( x ); +} + +inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + return _byteswap_uint64( x ); +} + +#else + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + boost::uint32_t step16 = x << 16 | x >> 16; + return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff); +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + boost::uint64_t step32 = x << 32 | x >> 32; + boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16; + return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8; +} + +#endif + +} // namespace detail + +template BOOST_CXX14_CONSTEXPR T byteswap( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( std::numeric_limits::is_integer ); + + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } + else + { + return static_cast( boost::core::detail::byteswap_impl( static_cast( x ) ) ); + } +} + +} // namespace core +} // namespace boost + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_CORE_BIT_HPP_INCLUDED diff --git a/src/boost/core/detail/sp_thread_pause.hpp b/src/boost/core/detail/sp_thread_pause.hpp new file mode 100644 index 00000000..8971fbd1 --- /dev/null +++ b/src/boost/core/detail/sp_thread_pause.hpp @@ -0,0 +1,71 @@ +#ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED +#define BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/core/detail/sp_thread_pause.hpp +// +// inline void bost::core::sp_thread_pause(); +// +// Emits a "pause" instruction. +// +// Copyright 2008, 2020, 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(__has_builtin) +# if __has_builtin(__builtin_ia32_pause) && !defined(__INTEL_COMPILER) +# define BOOST_CORE_HAS_BUILTIN_IA32_PAUSE +# endif +#endif + +#if defined(BOOST_CORE_HAS_BUILTIN_IA32_PAUSE) + +# define BOOST_CORE_SP_PAUSE() __builtin_ia32_pause() + +#elif defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) + +# include +# define BOOST_CORE_SP_PAUSE() _mm_pause() + +#elif defined(_MSC_VER) && ( defined(_M_ARM) || defined(_M_ARM64) ) + +# include +# define BOOST_CORE_SP_PAUSE() __yield() + +#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) + +# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "rep; nop" : : : "memory" ) + +#elif defined(__GNUC__) && ( (defined(__ARM_ARCH) && __ARM_ARCH >= 8) || defined(__ARM_ARCH_8A__) || defined(__aarch64__) ) + +# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "yield" : : : "memory" ) + +#else + +# define BOOST_CORE_SP_PAUSE() ((void)0) + +#endif + +namespace boost +{ +namespace core +{ + +BOOST_FORCEINLINE void sp_thread_pause() BOOST_NOEXCEPT +{ + BOOST_CORE_SP_PAUSE(); +} + +} // namespace core +} // namespace boost + +#undef BOOST_CORE_SP_PAUSE + +#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED diff --git a/src/boost/core/detail/sp_thread_sleep.hpp b/src/boost/core/detail/sp_thread_sleep.hpp new file mode 100644 index 00000000..bb5b1e08 --- /dev/null +++ b/src/boost/core/detail/sp_thread_sleep.hpp @@ -0,0 +1,122 @@ +#ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED +#define BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/core/detail/sp_thread_sleep.hpp +// +// inline void bost::core::sp_thread_sleep(); +// +// Cease execution for a while to yield to other threads, +// as if by calling nanosleep() with an appropriate interval. +// +// Copyright 2008, 2020, 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using Sleep(1) in sp_thread_sleep") +#endif + +#include + +namespace boost +{ +namespace core +{ +namespace detail +{ + +inline void sp_thread_sleep() BOOST_NOEXCEPT +{ + Sleep( 1 ); +} + +} // namespace detail + +using boost::core::detail::sp_thread_sleep; + +} // namespace core +} // namespace boost + +#elif defined(BOOST_HAS_NANOSLEEP) + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using nanosleep() in sp_thread_sleep") +#endif + +#include + +#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) +# include +#endif + +namespace boost +{ +namespace core +{ + +inline void sp_thread_sleep() BOOST_NOEXCEPT +{ +#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) && !defined(__OHOS__) + + int oldst; + pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldst ); + +#endif + + // g++ -Wextra warns on {} or {0} + struct timespec rqtp = { 0, 0 }; + + // POSIX says that timespec has tv_sec and tv_nsec + // But it doesn't guarantee order or placement + + rqtp.tv_sec = 0; + rqtp.tv_nsec = 1000; + + nanosleep( &rqtp, 0 ); + +#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) && !defined(__OHOS__) + + pthread_setcancelstate( oldst, &oldst ); + +#endif + +} + +} // namespace core +} // namespace boost + +#else + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using sp_thread_yield() in sp_thread_sleep") +#endif + +#include + +namespace boost +{ +namespace core +{ + +inline void sp_thread_sleep() BOOST_NOEXCEPT +{ + sp_thread_yield(); +} + +} // namespace core +} // namespace boost + +#endif + +#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED diff --git a/src/boost/core/detail/sp_thread_yield.hpp b/src/boost/core/detail/sp_thread_yield.hpp new file mode 100644 index 00000000..25127e8a --- /dev/null +++ b/src/boost/core/detail/sp_thread_yield.hpp @@ -0,0 +1,100 @@ +#ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED +#define BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/core/detail/sp_thread_yield.hpp +// +// inline void bost::core::sp_thread_yield(); +// +// Gives up the remainder of the time slice, +// as if by calling sched_yield(). +// +// Copyright 2008, 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using SwitchToThread() in sp_thread_yield") +#endif + +#include + +namespace boost +{ +namespace core +{ +namespace detail +{ + +inline void sp_thread_yield() BOOST_NOEXCEPT +{ + SwitchToThread(); +} + +} // namespace detail + +using boost::core::detail::sp_thread_yield; + +} // namespace core +} // namespace boost + +#elif defined(BOOST_HAS_SCHED_YIELD) + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using sched_yield() in sp_thread_yield") +#endif + +#ifndef _AIX +# include +#else + // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var + extern "C" int sched_yield(void); +#endif + +namespace boost +{ +namespace core +{ + +inline void sp_thread_yield() BOOST_NOEXCEPT +{ + sched_yield(); +} + +} // namespace core +} // namespace boost + +#else + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using sp_thread_pause() in sp_thread_yield") +#endif + +#include + +namespace boost +{ +namespace core +{ + +inline void sp_thread_yield() BOOST_NOEXCEPT +{ + sp_thread_pause(); +} + +} // namespace core +} // namespace boost + +#endif + +#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED diff --git a/src/boost/core/detail/sp_win32_sleep.hpp b/src/boost/core/detail/sp_win32_sleep.hpp new file mode 100644 index 00000000..adec53e4 --- /dev/null +++ b/src/boost/core/detail/sp_win32_sleep.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED +#define BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/core/detail/sp_win32_sleep.hpp +// +// Declares the Win32 Sleep() function. +// +// Copyright 2008, 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// https://www.boost.org/LICENSE_1_0.txt + +#if defined( BOOST_USE_WINDOWS_H ) +# include +#endif + +namespace boost +{ +namespace core +{ +namespace detail +{ + +#if !defined( BOOST_USE_WINDOWS_H ) + +#if defined(__clang__) && defined(__x86_64__) +// clang x64 warns that __stdcall is ignored +# define BOOST_CORE_SP_STDCALL +#else +# define BOOST_CORE_SP_STDCALL __stdcall +#endif + +#if defined(__LP64__) // Cygwin 64 + extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned int ms ); +#else + extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned long ms ); +#endif + +extern "C" __declspec(dllimport) int BOOST_CORE_SP_STDCALL SwitchToThread(); + +#undef BOOST_CORE_SP_STDCALL + +#endif // !defined( BOOST_USE_WINDOWS_H ) + +} // namespace detail +} // namespace core +} // namespace boost + +#endif // #ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED diff --git a/src/boost/core/empty_value.hpp b/src/boost/core/empty_value.hpp new file mode 100644 index 00000000..5eeee51f --- /dev/null +++ b/src/boost/core/empty_value.hpp @@ -0,0 +1,203 @@ +/* +Copyright 2018 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_EMPTY_VALUE_HPP +#define BOOST_CORE_EMPTY_VALUE_HPP + +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#include +#endif + +#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40700) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1800) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1800) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#elif defined(BOOST_CLANG) && !defined(__CUDACC__) +#if __has_feature(is_empty) && __has_feature(is_final) +#define BOOST_DETAIL_EMPTY_VALUE_BASE +#endif +#endif + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4510) +#endif + +namespace boost { + +template +struct use_empty_value_base { + enum { +#if defined(BOOST_DETAIL_EMPTY_VALUE_BASE) + value = __is_empty(T) && !__is_final(T) +#else + value = false +#endif + }; +}; + +struct empty_init_t { }; + +namespace empty_ { + +template::value> +class empty_value { +public: + typedef T type; + +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) + empty_value() = default; +#else + BOOST_CONSTEXPR empty_value() { } +#endif + + BOOST_CONSTEXPR empty_value(boost::empty_init_t) + : value_() { } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args) + : value_(std::forward(value), std::forward(args)...) { } +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value) + : value_(std::forward(value)) { } +#endif +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value) + : value_(value) { } + + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value) + : value_(value) { } +#endif + + BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT { + return value_; + } + + BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT { + return value_; + } + +private: + T value_; +}; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +#if defined(BOOST_MSVC) +/* +This is a workaround to an MSVC bug when T is a nested class: +https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025 +*/ +namespace detail { + +template +class empty_value_base + : public T { +public: +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) + empty_value_base() = default; +#else + BOOST_CONSTEXPR empty_value_base() { } +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + BOOST_CONSTEXPR empty_value_base(U&& value, Args&&... args) + : T(std::forward(value), std::forward(args)...) { } +#else + template + BOOST_CONSTEXPR empty_value_base(U&& value) + : T(std::forward(value)) { } +#endif +#else + template + BOOST_CONSTEXPR empty_value_base(const U& value) + : T(value) { } + + template + BOOST_CONSTEXPR empty_value_base(U& value) + : T(value) { } +#endif +}; + +} /* detail */ +#endif + +template +class empty_value +#if defined(BOOST_MSVC) + : detail::empty_value_base { + typedef detail::empty_value_base empty_base_; +#else + : T { + typedef T empty_base_; +#endif + +public: + typedef T type; + +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) + empty_value() = default; +#else + BOOST_CONSTEXPR empty_value() { } +#endif + + BOOST_CONSTEXPR empty_value(boost::empty_init_t) + : empty_base_() { } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args) + : empty_base_(std::forward(value), std::forward(args)...) { } +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value) + : empty_base_(std::forward(value)) { } +#endif +#else + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value) + : empty_base_(value) { } + + template + BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value) + : empty_base_(value) { } +#endif + + BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT { + return *this; + } + + BOOST_CXX14_CONSTEXPR T& get() BOOST_NOEXCEPT { + return *this; + } +}; +#endif + +} /* empty_ */ + +using empty_::empty_value; + +BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t(); + +} /* boost */ + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#endif diff --git a/src/boost/core/ignore_unused.hpp b/src/boost/core/ignore_unused.hpp new file mode 100644 index 00000000..7c4a9978 --- /dev/null +++ b/src/boost/core/ignore_unused.hpp @@ -0,0 +1,100 @@ +// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. +// +// 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) + +#ifndef BOOST_CORE_IGNORE_UNUSED_HPP +#define BOOST_CORE_IGNORE_UNUSED_HPP + +#include + +namespace boost { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts&& ...) +{} + +#else + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts const& ...) +{} + +#endif + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&, T5&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&, T5 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +#endif + +} // namespace boost + +#endif // BOOST_CORE_IGNORE_UNUSED_HPP diff --git a/src/boost/core/no_exceptions_support.hpp b/src/boost/core/no_exceptions_support.hpp new file mode 100644 index 00000000..1278e856 --- /dev/null +++ b/src/boost/core/no_exceptions_support.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP +#define BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +//---------------------------------------------------------------------- +// (C) Copyright 2004 Pavel Vozenilek. +// 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) +// +// +// This file contains helper macros used when exception support may be +// disabled (as indicated by macro BOOST_NO_EXCEPTIONS). +// +// Before picking up these macros you may consider using RAII techniques +// to deal with exceptions - their syntax can be always the same with +// or without exception support enabled. +//---------------------------------------------------------------------- + +#include +#include + +#if !(defined BOOST_NO_EXCEPTIONS) +# define BOOST_TRY { try +# define BOOST_CATCH(x) catch(x) +# define BOOST_RETHROW throw; +# define BOOST_CATCH_END } +#else +# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) +# define BOOST_TRY { if ("") +# define BOOST_CATCH(x) else if (!"") +# elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 +# define BOOST_TRY { if (true) +# define BOOST_CATCH(x) else if (false) +# else + // warning C4127: conditional expression is constant +# define BOOST_TRY { \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (true) \ + __pragma(warning(pop)) +# define BOOST_CATCH(x) else \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (false) \ + __pragma(warning(pop)) +# endif +# define BOOST_RETHROW +# define BOOST_CATCH_END } +#endif + + +#endif diff --git a/src/boost/core/noncopyable.hpp b/src/boost/core/noncopyable.hpp new file mode 100644 index 00000000..4ec2d54f --- /dev/null +++ b/src/boost/core/noncopyable.hpp @@ -0,0 +1,63 @@ +// Boost noncopyable.hpp header file --------------------------------------// + +// (C) Copyright Beman Dawes 1999-2003. 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) + +// See http://www.boost.org/libs/utility for documentation. + +#ifndef BOOST_CORE_NONCOPYABLE_HPP +#define BOOST_CORE_NONCOPYABLE_HPP + +#include + +namespace boost { + +// Private copy constructor and copy assignment ensure classes derived from +// class noncopyable cannot be copied. + +// Contributed by Dave Abrahams + +namespace noncopyable_ // protection from unintended ADL +{ +#ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED +#define BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED + +// noncopyable derives from base_token to enable Type Traits to detect +// whether a type derives from noncopyable without needing the definition +// of noncopyable itself. +// +// The definition of base_token is macro-guarded so that Type Traits can +// define it locally without including this header, to avoid a dependency +// on Core. + + struct base_token {}; + +#endif // #ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED + + class noncopyable: base_token + { + protected: +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) + BOOST_CONSTEXPR noncopyable() = default; + ~noncopyable() = default; +#else + noncopyable() {} + ~noncopyable() {} +#endif +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) + noncopyable( const noncopyable& ) = delete; + noncopyable& operator=( const noncopyable& ) = delete; +#else + private: // emphasize the following members are private + noncopyable( const noncopyable& ); + noncopyable& operator=( const noncopyable& ); +#endif + }; +} + +typedef noncopyable_::noncopyable noncopyable; + +} // namespace boost + +#endif // BOOST_CORE_NONCOPYABLE_HPP diff --git a/src/boost/core/nvp.hpp b/src/boost/core/nvp.hpp new file mode 100644 index 00000000..8826a592 --- /dev/null +++ b/src/boost/core/nvp.hpp @@ -0,0 +1,57 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_NVP_HPP +#define BOOST_CORE_NVP_HPP + +#include +#include + +namespace boost { +namespace serialization { + +template +class nvp { +public: + nvp(const char* n, T& v) BOOST_NOEXCEPT + : n_(n) + , v_(boost::addressof(v)) { } + + const char* name() const BOOST_NOEXCEPT { + return n_; + } + + T& value() const BOOST_NOEXCEPT { + return *v_; + } + + const T& const_value() const BOOST_NOEXCEPT { + return *v_; + } + +private: + const char* n_; + T* v_; +}; + +template +inline const nvp +make_nvp(const char* n, T& v) BOOST_NOEXCEPT +{ + return nvp(n, v); +} + +} /* serialization */ + +using serialization::nvp; +using serialization::make_nvp; + +} /* boost */ + +#define BOOST_NVP(v) boost::make_nvp(BOOST_STRINGIZE(v), v) + +#endif diff --git a/src/boost/core/pointer_traits.hpp b/src/boost/core/pointer_traits.hpp new file mode 100644 index 00000000..7de7a8e9 --- /dev/null +++ b/src/boost/core/pointer_traits.hpp @@ -0,0 +1,285 @@ +/* +Copyright 2017-2021 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_POINTER_TRAITS_HPP +#define BOOST_CORE_POINTER_TRAITS_HPP + +#include +#include +#include + +namespace boost { +namespace detail { + +struct ptr_none { }; + +template +struct ptr_valid { + typedef void type; +}; + +template +struct ptr_first { + typedef ptr_none type; +}; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template class T, class U, class... Args> +struct ptr_first > { + typedef U type; +}; +#else +template class T, class U> +struct ptr_first > { + typedef U type; +}; + +template class T, class U1, class U2> +struct ptr_first > { + typedef U1 type; +}; + +template class T, class U1, class U2, class U3> +struct ptr_first > { + typedef U1 type; +}; +#endif + +template +struct ptr_element { + typedef typename ptr_first::type type; +}; + +template +struct ptr_element::type> { + typedef typename T::element_type type; +}; + +template +struct ptr_difference { + typedef std::ptrdiff_t type; +}; + +template +struct ptr_difference::type> { + typedef typename T::difference_type type; +}; + +template +struct ptr_transform { }; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template class T, class U, class... Args, class V> +struct ptr_transform, V> { + typedef T type; +}; +#else +template class T, class U, class V> +struct ptr_transform, V> { + typedef T type; +}; + +template class T, class U1, class U2, class V> +struct ptr_transform, V> { + typedef T type; +}; + +template class T, + class U1, class U2, class U3, class V> +struct ptr_transform, V> { + typedef T type; +}; +#endif + +template +struct ptr_rebind + : ptr_transform { }; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template +struct ptr_rebind >::type> { + typedef typename T::template rebind type; +}; +#else +template +struct ptr_rebind::other>::type> { + typedef typename T::template rebind::other type; +}; +#endif + +#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +template +class ptr_to_expr { + template + struct result { + char x, y; + }; + + static E& source(); + + template + static auto check(int) -> result; + + template + static char check(long); + +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(check(0)) > 1; +}; + +template +struct ptr_to_expr { + BOOST_STATIC_CONSTEXPR bool value = true; +}; + +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr::value; +}; +#else +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = true; +}; +#endif + +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template +struct ptr_has_to { + BOOST_STATIC_CONSTEXPR bool value = false; +}; + +template::value> +struct ptr_to { }; + +template +struct ptr_to { + static T pointer_to(E& v) { + return T::pointer_to(v); + } +}; + +template +struct ptr_to { + static T* pointer_to(T& v) BOOST_NOEXCEPT { + return boost::addressof(v); + } +}; + +template +struct ptr_traits + : ptr_to { + typedef T pointer; + typedef E element_type; + typedef typename ptr_difference::type difference_type; + + template + struct rebind_to + : ptr_rebind { }; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + template + using rebind = typename rebind_to::type; +#endif +}; + +template +struct ptr_traits { }; + +} /* detail */ + +template +struct pointer_traits + : detail::ptr_traits::type> { }; + +template +struct pointer_traits + : detail::ptr_to { + typedef T* pointer; + typedef T element_type; + typedef std::ptrdiff_t difference_type; + + template + struct rebind_to { + typedef U* type; + }; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + template + using rebind = typename rebind_to::type; +#endif +}; + +template +BOOST_CONSTEXPR inline T* +to_address(T* v) BOOST_NOEXCEPT +{ + return v; +} + +#if !defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION) +namespace detail { + +template +inline T* +ptr_address(T* v, int) BOOST_NOEXCEPT +{ + return v; +} + +template +inline auto +ptr_address(const T& v, int) BOOST_NOEXCEPT +-> decltype(boost::pointer_traits::to_address(v)) +{ + return boost::pointer_traits::to_address(v); +} + +template +inline auto +ptr_address(const T& v, long) BOOST_NOEXCEPT +{ + return boost::detail::ptr_address(v.operator->(), 0); +} + +} /* detail */ + +template +inline auto +to_address(const T& v) BOOST_NOEXCEPT +{ + return boost::detail::ptr_address(v, 0); +} +#else +template +inline typename pointer_traits::element_type* +to_address(const T& v) BOOST_NOEXCEPT +{ + return boost::to_address(v.operator->()); +} +#endif + +} /* boost */ + +#endif diff --git a/src/boost/core/serialization.hpp b/src/boost/core/serialization.hpp new file mode 100644 index 00000000..9c78c582 --- /dev/null +++ b/src/boost/core/serialization.hpp @@ -0,0 +1,131 @@ +#ifndef BOOST_CORE_SERIALIZATION_HPP_INCLUDED +#define BOOST_CORE_SERIALIZATION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// Utilities needed to implement serialization support +// without including a Boost.Serialization header + +#include +#include + +namespace boost +{ + +namespace serialization +{ + +// Forward declarations (needed for specializations) + +template struct version; + +class access; + +// Our own version_type replacement. This has to be in +// the `serialization` namespace, because its only purpose +// is to add `serialization` as an associated namespace. + +struct core_version_type +{ + unsigned int version_; + + core_version_type( unsigned int version ): version_( version ) {} + operator unsigned int () const { return version_; } +}; + +} // namespace serialization + +namespace core +{ + +// nvp + +using serialization::nvp; +using serialization::make_nvp; + +// split_free + +namespace detail +{ + +template struct load_or_save_f; + +template<> struct load_or_save_f +{ + template void operator()( A& a, T& t, unsigned int v ) const + { + save( a, t, serialization::core_version_type( v ) ); + } +}; + +template<> struct load_or_save_f +{ + template void operator()( A& a, T& t, unsigned int v ) const + { + load( a, t, serialization::core_version_type( v ) ); + } +}; + +} // namespace detail + +template inline void split_free( A& a, T& t, unsigned int v ) +{ + detail::load_or_save_f< A::is_saving::value >()( a, t, v ); +} + +// split_member + +namespace detail +{ + +template struct load_or_save_m; + +template struct load_or_save_m +{ + template void operator()( A& a, T const& t, unsigned int v ) const + { + Access::member_save( a, t, v ); + } +}; + +template struct load_or_save_m +{ + template void operator()( A& a, T& t, unsigned int v ) const + { + Access::member_load( a, t, v ); + } +}; + +} // namespace detail + +template inline void split_member( A& a, T& t, unsigned int v ) +{ + detail::load_or_save_m< A::is_saving::value >()( a, t, v ); +} + +// load_construct_data_adl + +template void load_construct_data_adl( Ar& ar, T* t, unsigned int v ) +{ + load_construct_data( ar, t, serialization::core_version_type( v ) ); +} + +// save_construct_data_adl + +template void save_construct_data_adl( Ar& ar, T const* t, unsigned int v ) +{ + save_construct_data( ar, t, serialization::core_version_type( v ) ); +} + +} // namespace core +} // namespace boost + +#endif // #ifndef BOOST_CORE_SERIALIZATION_HPP_INCLUDED diff --git a/src/boost/core/yield_primitives.hpp b/src/boost/core/yield_primitives.hpp new file mode 100644 index 00000000..899453e5 --- /dev/null +++ b/src/boost/core/yield_primitives.hpp @@ -0,0 +1,12 @@ +#ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED +#define BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#endif // #ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED diff --git a/src/boost/cstdint.hpp b/src/boost/cstdint.hpp new file mode 100644 index 00000000..967aacfd --- /dev/null +++ b/src/boost/cstdint.hpp @@ -0,0 +1,556 @@ +// boost cstdint.hpp header file ------------------------------------------// + +// (C) Copyright Beman Dawes 1999. +// (C) Copyright Jens Mauer 2001 +// (C) Copyright John Maddock 2001 +// 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) + +// See http://www.boost.org/libs/integer for documentation. + +// Revision History +// 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) +// 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) +// 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) +// 12 Nov 00 Merged (Jens Maurer) +// 23 Sep 00 Added INTXX_C macro support (John Maddock). +// 22 Sep 00 Better 64-bit support (John Maddock) +// 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost +// 8 Aug 99 Initial version (Beman Dawes) + + +#ifndef BOOST_CSTDINT_HPP +#define BOOST_CSTDINT_HPP + +// +// Since we always define the INT#_C macros as per C++0x, +// define __STDC_CONSTANT_MACROS so that does the right +// thing if possible, and so that the user knows that the macros +// are actually defined as per C99. +// +#ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS +#endif + +#include +// +// For the following code we get several warnings along the lines of: +// +// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant +// +// So we declare this a system header to suppress these warnings. +// See also https://github.com/boostorg/config/issues/190 +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +// +// Note that GLIBC is a bit inconsistent about whether int64_t is defined or not +// depending upon what headers happen to have been included first... +// so we disable use of stdint.h when GLIBC does not define __GLIBC_HAVE_LONG_LONG. +// See https://svn.boost.org/trac/boost/ticket/3548 and http://sources.redhat.com/bugzilla/show_bug.cgi?id=10990 +// +#if defined(BOOST_HAS_STDINT_H) \ + && (!defined(__GLIBC__) \ + || defined(__GLIBC_HAVE_LONG_LONG) \ + || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 17))))) + +// The following #include is an implementation artifact; not part of interface. +# ifdef __hpux +// HP-UX has a vaguely nice in a non-standard location +# include +# ifdef __STDC_32_MODE__ + // this is triggered with GCC, because it defines __cplusplus < 199707L +# define BOOST_NO_INT64_T +# endif +# elif defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX) +# include +# else +# include + +// There is a bug in Cygwin two _C macros +# if defined(INTMAX_C) && defined(__CYGWIN__) +# undef INTMAX_C +# undef UINTMAX_C +# define INTMAX_C(c) c##LL +# define UINTMAX_C(c) c##ULL +# endif + +# endif + +#if defined(__QNX__) && defined(__EXT_QNX) + +// QNX (Dinkumware stdlib) defines these as non-standard names. +// Reflect to the standard names. + +typedef ::intleast8_t int_least8_t; +typedef ::intfast8_t int_fast8_t; +typedef ::uintleast8_t uint_least8_t; +typedef ::uintfast8_t uint_fast8_t; + +typedef ::intleast16_t int_least16_t; +typedef ::intfast16_t int_fast16_t; +typedef ::uintleast16_t uint_least16_t; +typedef ::uintfast16_t uint_fast16_t; + +typedef ::intleast32_t int_least32_t; +typedef ::intfast32_t int_fast32_t; +typedef ::uintleast32_t uint_least32_t; +typedef ::uintfast32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + +typedef ::intleast64_t int_least64_t; +typedef ::intfast64_t int_fast64_t; +typedef ::uintleast64_t uint_least64_t; +typedef ::uintfast64_t uint_fast64_t; + +# endif + +#endif + +namespace boost +{ + + using ::int8_t; + using ::int_least8_t; + using ::int_fast8_t; + using ::uint8_t; + using ::uint_least8_t; + using ::uint_fast8_t; + + using ::int16_t; + using ::int_least16_t; + using ::int_fast16_t; + using ::uint16_t; + using ::uint_least16_t; + using ::uint_fast16_t; + + using ::int32_t; + using ::int_least32_t; + using ::int_fast32_t; + using ::uint32_t; + using ::uint_least32_t; + using ::uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + using ::int_least64_t; + using ::int_fast64_t; + using ::uint64_t; + using ::uint_least64_t; + using ::uint_fast64_t; + +# endif + + using ::intmax_t; + using ::uintmax_t; + +} // namespace boost + +#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) || defined(__VMS) || defined(__SOLARIS9__) || defined(__NetBSD__) +// FreeBSD and Tru64 have an that contains much of what we need. +# include + +namespace boost { + + using ::int8_t; + typedef int8_t int_least8_t; + typedef int8_t int_fast8_t; + using ::uint8_t; + typedef uint8_t uint_least8_t; + typedef uint8_t uint_fast8_t; + + using ::int16_t; + typedef int16_t int_least16_t; + typedef int16_t int_fast16_t; + using ::uint16_t; + typedef uint16_t uint_least16_t; + typedef uint16_t uint_fast16_t; + + using ::int32_t; + typedef int32_t int_least32_t; + typedef int32_t int_fast32_t; + using ::uint32_t; + typedef uint32_t uint_least32_t; + typedef uint32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + typedef int64_t int_least64_t; + typedef int64_t int_fast64_t; + using ::uint64_t; + typedef uint64_t uint_least64_t; + typedef uint64_t uint_fast64_t; + + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; + +# else + + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; + +# endif + +} // namespace boost + +#else // BOOST_HAS_STDINT_H + +# include // implementation artifact; not part of interface +# include // needed for limits macros + + +namespace boost +{ + +// These are fairly safe guesses for some 16-bit, and most 32-bit and 64-bit +// platforms. For other systems, they will have to be hand tailored. +// +// Because the fast types are assumed to be the same as the undecorated types, +// it may be possible to hand tailor a more efficient implementation. Such +// an optimization may be illusionary; on the Intel x86-family 386 on, for +// example, byte arithmetic and load/stores are as fast as "int" sized ones. + +// 8-bit types ------------------------------------------------------------// + +# if UCHAR_MAX == 0xff + typedef signed char int8_t; + typedef signed char int_least8_t; + typedef signed char int_fast8_t; + typedef unsigned char uint8_t; + typedef unsigned char uint_least8_t; + typedef unsigned char uint_fast8_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 16-bit types -----------------------------------------------------------// + +# if USHRT_MAX == 0xffff +# if defined(__crayx1) + // The Cray X1 has a 16-bit short, however it is not recommend + // for use in performance critical code. + typedef short int16_t; + typedef short int_least16_t; + typedef int int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned int uint_fast16_t; +# else + typedef short int16_t; + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# endif +# elif (USHRT_MAX == 0xffffffff) && defined(__MTA__) + // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified + // MTA / XMT does support the following non-standard integer types + typedef __short16 int16_t; + typedef __short16 int_least16_t; + typedef __short16 int_fast16_t; + typedef unsigned __short16 uint16_t; + typedef unsigned __short16 uint_least16_t; + typedef unsigned __short16 uint_fast16_t; +# elif (USHRT_MAX == 0xffffffff) && defined(CRAY) + // no 16-bit types on Cray: + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 32-bit types -----------------------------------------------------------// + +# if UINT_MAX == 0xffffffff + typedef int int32_t; + typedef int int_least32_t; + typedef int int_fast32_t; + typedef unsigned int uint32_t; + typedef unsigned int uint_least32_t; + typedef unsigned int uint_fast32_t; +# elif (USHRT_MAX == 0xffffffff) + typedef short int32_t; + typedef short int_least32_t; + typedef short int_fast32_t; + typedef unsigned short uint32_t; + typedef unsigned short uint_least32_t; + typedef unsigned short uint_fast32_t; +# elif ULONG_MAX == 0xffffffff + typedef long int32_t; + typedef long int_least32_t; + typedef long int_fast32_t; + typedef unsigned long uint32_t; + typedef unsigned long uint_least32_t; + typedef unsigned long uint_fast32_t; +# elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) + // Integers are 64 bits on the MTA / XMT + typedef __int32 int32_t; + typedef __int32 int_least32_t; + typedef __int32 int_fast32_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int32 uint_fast32_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// + +# if defined(BOOST_HAS_LONG_LONG) && \ + !defined(BOOST_MSVC) && !defined(BOOST_BORLANDC) && \ + (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) + // 2**64 - 1 +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + + typedef ::boost::long_long_type intmax_t; + typedef ::boost::ulong_long_type uintmax_t; + typedef ::boost::long_long_type int64_t; + typedef ::boost::long_long_type int_least64_t; + typedef ::boost::long_long_type int_fast64_t; + typedef ::boost::ulong_long_type uint64_t; + typedef ::boost::ulong_long_type uint_least64_t; + typedef ::boost::ulong_long_type uint_fast64_t; + +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615 // 2**64 - 1 + typedef long intmax_t; + typedef unsigned long uintmax_t; + typedef long int64_t; + typedef long int_least64_t; + typedef long int_fast64_t; + typedef unsigned long uint64_t; + typedef unsigned long uint_least64_t; + typedef unsigned long uint_fast64_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(__GNUC__) && defined(BOOST_HAS_LONG_LONG) + __extension__ typedef long long intmax_t; + __extension__ typedef unsigned long long uintmax_t; + __extension__ typedef long long int64_t; + __extension__ typedef long long int_least64_t; + __extension__ typedef long long int_fast64_t; + __extension__ typedef unsigned long long uint64_t; + __extension__ typedef unsigned long long uint_least64_t; + __extension__ typedef unsigned long long uint_fast64_t; +# elif defined(BOOST_HAS_MS_INT64) + // + // we have Borland/Intel/Microsoft __int64: + // + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; + typedef __int64 int64_t; + typedef __int64 int_least64_t; + typedef __int64 int_fast64_t; + typedef unsigned __int64 uint64_t; + typedef unsigned __int64 uint_least64_t; + typedef unsigned __int64 uint_fast64_t; +# else // assume no 64-bit integers +# define BOOST_NO_INT64_T + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# endif + +} // namespace boost + + +#endif // BOOST_HAS_STDINT_H + +// intptr_t/uintptr_t are defined separately because they are optional and not universally available +#if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H) +// Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h +#include +#endif + +#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \ + || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \ + || defined(__CYGWIN__) || defined(__VXWORKS__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ + || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || (defined(sun) && !defined(BOOST_HAS_STDINT_H)) || defined(INTPTR_MAX) + +namespace boost { + using ::intptr_t; + using ::uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +// Clang pretends to be GCC, so it'll match this condition +#elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__) + +namespace boost { + typedef __INTPTR_TYPE__ intptr_t; + typedef __UINTPTR_TYPE__ uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +#endif + +#endif // BOOST_CSTDINT_HPP + + +/**************************************************** + +Macro definition section: + +Added 23rd September 2000 (John Maddock). +Modified 11th September 2001 to be excluded when +BOOST_HAS_STDINT_H is defined (John Maddock). +Modified 11th Dec 2009 to always define the +INT#_C macros if they're not already defined (John Maddock). + +******************************************************/ + +#if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \ + (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C)) +// +// Undef the macros as a precaution, since we may get here if has failed +// to define them all, see https://svn.boost.org/trac/boost/ticket/12786 +// +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef INTMAX_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C +#undef UINTMAX_C + +#include +# define BOOST__STDC_CONSTANT_MACROS_DEFINED +# if defined(BOOST_HAS_MS_INT64) +// +// Borland/Intel/Microsoft compilers have width specific suffixes: +// +#ifndef INT8_C +# define INT8_C(value) value##i8 +#endif +#ifndef INT16_C +# define INT16_C(value) value##i16 +#endif +#ifndef INT32_C +# define INT32_C(value) value##i32 +#endif +#ifndef INT64_C +# define INT64_C(value) value##i64 +#endif +# ifdef BOOST_BORLANDC + // Borland bug: appending ui8 makes the type a signed char +# define UINT8_C(value) static_cast(value##u) +# else +# define UINT8_C(value) value##ui8 +# endif +#ifndef UINT16_C +# define UINT16_C(value) value##ui16 +#endif +#ifndef UINT32_C +# define UINT32_C(value) value##ui32 +#endif +#ifndef UINT64_C +# define UINT64_C(value) value##ui64 +#endif +#ifndef INTMAX_C +# define INTMAX_C(value) value##i64 +# define UINTMAX_C(value) value##ui64 +#endif + +# else +// do it the old fashioned way: + +// 8-bit types ------------------------------------------------------------// + +# if (UCHAR_MAX == 0xff) && !defined(INT8_C) +# define INT8_C(value) static_cast(value) +# define UINT8_C(value) static_cast(value##u) +# endif + +// 16-bit types -----------------------------------------------------------// + +# if (USHRT_MAX == 0xffff) && !defined(INT16_C) +# define INT16_C(value) static_cast(value) +# define UINT16_C(value) static_cast(value##u) +# endif + +// 32-bit types -----------------------------------------------------------// +#ifndef INT32_C +# if (UINT_MAX == 0xffffffff) +# define INT32_C(value) value +# define UINT32_C(value) value##u +# elif ULONG_MAX == 0xffffffff +# define INT32_C(value) value##L +# define UINT32_C(value) value##uL +# endif +#endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// +#ifndef INT64_C +# if defined(BOOST_HAS_LONG_LONG) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX) || defined(_ULLONG_MAX) || defined(_LLONG_MAX)) + +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) || \ + (defined(_ULLONG_MAX) && _ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(_LLONG_MAX) && _LLONG_MAX == 9223372036854775807LL) + +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615U // 2**64 - 1 +# define INT64_C(value) value##L +# define UINT64_C(value) value##uL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(BOOST_HAS_LONG_LONG) + // Usual macros not defined, work things out for ourselves: +# if(~0uLL == 18446744073709551615ULL) +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +# ifdef BOOST_NO_INT64_T +# define INTMAX_C(value) INT32_C(value) +# define UINTMAX_C(value) UINT32_C(value) +# else +# define INTMAX_C(value) INT64_C(value) +# define UINTMAX_C(value) UINT64_C(value) +# endif +#endif +# endif // Borland/Microsoft specific width suffixes + +#endif // INT#_C macros. + + + + diff --git a/src/boost/current_function.hpp b/src/boost/current_function.hpp new file mode 100644 index 00000000..731d1b13 --- /dev/null +++ b/src/boost/current_function.hpp @@ -0,0 +1,75 @@ +#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED +#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/current_function.hpp - BOOST_CURRENT_FUNCTION +// +// Copyright 2002-2018 Peter Dimov +// +// 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 +// +// http://www.boost.org/libs/assert +// + +namespace boost +{ + +namespace detail +{ + +inline void current_function_helper() +{ + +#if defined( BOOST_DISABLE_CURRENT_FUNCTION ) + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) || defined(__clang__) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__DMC__) && (__DMC__ >= 0x810) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__FUNCSIG__) + +# define BOOST_CURRENT_FUNCTION __FUNCSIG__ + +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) + +# define BOOST_CURRENT_FUNCTION __FUNCTION__ + +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) + +# define BOOST_CURRENT_FUNCTION __FUNC__ + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) + +# define BOOST_CURRENT_FUNCTION __func__ + +#elif defined(__cplusplus) && (__cplusplus >= 201103) + +# define BOOST_CURRENT_FUNCTION __func__ + +#else + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#endif + +} + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED diff --git a/src/boost/describe/bases.hpp b/src/boost/describe/bases.hpp new file mode 100644 index 00000000..b01313e0 --- /dev/null +++ b/src/boost/describe/bases.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_DESCRIBE_BASES_HPP_INCLUDED +#define BOOST_DESCRIBE_BASES_HPP_INCLUDED + +// Copyright 2020, 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +template using _describe_bases = decltype( boost_base_descriptor_fn( static_cast(0) ) ); + +template struct base_filter +{ + template using fn = mp11::mp_bool< ( M & mod_any_access & T::modifiers ) != 0 >; +}; + +template struct has_describe_bases: std::false_type +{ +}; + +template struct has_describe_bases>>: std::true_type +{ +}; + +} // namespace detail + +template using describe_bases = mp11::mp_copy_if_q, detail::base_filter>; + +template using has_describe_bases = detail::has_describe_bases; + +} // namespace describe +} // namespace boost + +#endif // !defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_BASES_HPP_INCLUDED diff --git a/src/boost/describe/detail/config.hpp b/src/boost/describe/detail/config.hpp new file mode 100644 index 00000000..c24a070e --- /dev/null +++ b/src/boost/describe/detail/config.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if __cplusplus >= 201402L + +# define BOOST_DESCRIBE_CXX14 +# define BOOST_DESCRIBE_CXX11 + +#elif defined(_MSC_VER) && _MSC_VER >= 1900 + +# define BOOST_DESCRIBE_CXX14 +# define BOOST_DESCRIBE_CXX11 + +#elif __cplusplus >= 201103L + +# define BOOST_DESCRIBE_CXX11 + +# if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 7 +# undef BOOST_DESCRIBE_CXX11 +# endif + +#endif + +#if defined(BOOST_DESCRIBE_CXX11) +# define BOOST_DESCRIBE_CONSTEXPR_OR_CONST constexpr +#else +# define BOOST_DESCRIBE_CONSTEXPR_OR_CONST const +#endif + +#if defined(__clang__) +# define BOOST_DESCRIBE_MAYBE_UNUSED __attribute__((unused)) +#else +# define BOOST_DESCRIBE_MAYBE_UNUSED +#endif + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED diff --git a/src/boost/describe/detail/cx_streq.hpp b/src/boost/describe/detail/cx_streq.hpp new file mode 100644 index 00000000..15e87dc2 --- /dev/null +++ b/src/boost/describe/detail/cx_streq.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +constexpr bool cx_streq( char const * s1, char const * s2 ) +{ + return s1[0] == s2[0] && ( s1[0] == 0 || cx_streq( s1 + 1, s2 + 1 ) ); +} + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED diff --git a/src/boost/describe/detail/void_t.hpp b/src/boost/describe/detail/void_t.hpp new file mode 100644 index 00000000..f304250d --- /dev/null +++ b/src/boost/describe/detail/void_t.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED +#define BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED + +// Copyright 2021 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +template struct make_void +{ + using type = void; +}; + +template using void_t = typename make_void::type; + +} // namespace detail +} // namespace describe +} // namespace boost + +#endif // defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED diff --git a/src/boost/describe/members.hpp b/src/boost/describe/members.hpp new file mode 100644 index 00000000..828c4955 --- /dev/null +++ b/src/boost/describe/members.hpp @@ -0,0 +1,161 @@ +#ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED +#define BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(BOOST_DESCRIBE_CXX11) + +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace describe +{ +namespace detail +{ + +// _describe_members + +template using _describe_public_members = decltype( boost_public_member_descriptor_fn( static_cast(0) ) ); +template using _describe_protected_members = decltype( boost_protected_member_descriptor_fn( static_cast(0) ) ); +template using _describe_private_members = decltype( boost_private_member_descriptor_fn( static_cast(0) ) ); + +template using _describe_members = mp11::mp_append<_describe_public_members, _describe_protected_members, _describe_private_members>; + +// describe_inherited_members + +// T: type +// V: list of virtual bases visited so far +template struct describe_inherited_members_impl; +template using describe_inherited_members = typename describe_inherited_members_impl::type; + +// L: list of base class descriptors +// T: derived type +// V: list of virtual bases visited so far +template struct describe_inherited_members2_impl; +template using describe_inherited_members2 = typename describe_inherited_members2_impl::type; + +template struct describe_inherited_members_impl +{ + using R1 = describe_inherited_members2, T, V>; + using R2 = _describe_members; + + using type = mp11::mp_append; +}; + +template class L, class T, class V> struct describe_inherited_members2_impl, T, V> +{ + using type = L<>; +}; + +template using name_matches = mp11::mp_bool< cx_streq( D1::name, D2::name ) >; + +template using name_is_hidden = mp11::mp_any_of_q>; + +constexpr unsigned cx_max( unsigned m1, unsigned m2 ) +{ + return m1 > m2? m1: m2; +} + +template struct update_modifiers +{ + template struct fn + { + using L = _describe_members; + static constexpr unsigned hidden = name_is_hidden::value? mod_hidden: 0; + + static constexpr unsigned mods = D::modifiers; + static constexpr unsigned access = cx_max( mods & mod_any_access, Bm & mod_any_access ); + + static constexpr decltype(D::pointer) pointer = D::pointer; + static constexpr decltype(D::name) name = D::name; + static constexpr unsigned modifiers = ( mods & ~mod_any_access ) | access | mod_inherited | hidden; + }; +}; + +#ifndef __cpp_inline_variables +template template constexpr decltype(D::pointer) update_modifiers::fn::pointer; +template template constexpr decltype(D::name) update_modifiers::fn::name; +template template constexpr unsigned update_modifiers::fn::modifiers; +#endif + +template struct gather_virtual_bases_impl; +template using gather_virtual_bases = typename gather_virtual_bases_impl::type; + +template struct gather_virtual_bases_impl +{ + using B = typename D::type; + static constexpr unsigned M = D::modifiers; + + using R1 = mp11::mp_transform>; + using R2 = mp11::mp_apply; + + using type = mp11::mp_if_c<(M & mod_virtual) != 0, mp11::mp_push_front, R2>; +}; + +template class L, class D1, class... D, class T, class V> struct describe_inherited_members2_impl, T, V> +{ + using B = typename D1::type; + static constexpr unsigned M = D1::modifiers; + + using R1 = mp11::mp_if_c<(M & mod_virtual) && mp11::mp_contains::value, L<>, describe_inherited_members>; + + using R2 = mp11::mp_transform_q, R1>; + + using V2 = mp11::mp_append>; + using R3 = describe_inherited_members2, T, V2>; + + using type = mp11::mp_append; +}; + +// describe_members + +template using describe_members = mp11::mp_eval_if_c<(M & mod_inherited) == 0, _describe_members, describe_inherited_members, T, mp11::mp_list<>>; + +// member_filter + +template struct member_filter +{ + template using fn = mp11::mp_bool< + (M & mod_any_access & T::modifiers) != 0 && + ( (M & mod_any_member) != 0 || (M & mod_static) == (T::modifiers & mod_static) ) && + ( (M & mod_any_member) != 0 || (M & mod_function) == (T::modifiers & mod_function) ) && + (M & mod_hidden) >= (T::modifiers & mod_hidden) + >; +}; + +// has_describe_members + +template struct has_describe_members: std::false_type +{ +}; + +template struct has_describe_members>>: std::true_type +{ +}; + +} // namespace detail + +template using describe_members = mp11::mp_copy_if_q, detail::member_filter>; + +template using has_describe_members = detail::has_describe_members; + +} // namespace describe +} // namespace boost + +#endif // !defined(BOOST_DESCRIBE_CXX11) + +#endif // #ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED diff --git a/src/boost/describe/modifiers.hpp b/src/boost/describe/modifiers.hpp new file mode 100644 index 00000000..06650ea1 --- /dev/null +++ b/src/boost/describe/modifiers.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED +#define BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED + +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +namespace boost +{ +namespace describe +{ + +enum modifiers +{ + mod_public = 1, + mod_protected = 2, + mod_private = 4, + mod_virtual = 8, + mod_static = 16, + mod_function = 32, + mod_any_member = 64, + mod_inherited = 128, + mod_hidden = 256 +}; + +BOOST_DESCRIBE_CONSTEXPR_OR_CONST modifiers mod_any_access = static_cast( mod_public | mod_protected | mod_private ); + +} // namespace describe +} // namespace boost + +#endif // #ifndef BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED diff --git a/src/boost/detail/workaround.hpp b/src/boost/detail/workaround.hpp new file mode 100644 index 00000000..9c392182 --- /dev/null +++ b/src/boost/detail/workaround.hpp @@ -0,0 +1,10 @@ +// Copyright David Abrahams 2002. +// 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) +#ifndef BOOST_WORKAROUND_DWA2002126_HPP +#define BOOST_WORKAROUND_DWA2002126_HPP + +#include + +#endif // BOOST_WORKAROUND_DWA2002126_HPP diff --git a/src/boost/exception/exception.hpp b/src/boost/exception/exception.hpp new file mode 100644 index 00000000..4ec18d7d --- /dev/null +++ b/src/boost/exception/exception.hpp @@ -0,0 +1,569 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//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) + +#ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 +#define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 + +#include +#include +#include + +#ifdef BOOST_EXCEPTION_MINI_BOOST +#include +namespace boost { namespace exception_detail { using std::shared_ptr; } } +#else +namespace boost { template class shared_ptr; } +namespace boost { namespace exception_detail { using boost::shared_ptr; } } +#endif + +#if !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#if defined(__GNUC__) && __GNUC__*100+__GNUC_MINOR__>301 +#pragma GCC system_header +#endif +#ifdef __clang__ +#pragma clang system_header +#endif +#ifdef _MSC_VER +#pragma warning(push,1) +#pragma warning(disable: 4265) +#endif +#endif + +namespace +boost + { + namespace + exception_detail + { + template + class + refcount_ptr + { + public: + + refcount_ptr(): + px_(0) + { + } + + ~refcount_ptr() + { + release(); + } + + refcount_ptr( refcount_ptr const & x ): + px_(x.px_) + { + add_ref(); + } + + refcount_ptr & + operator=( refcount_ptr const & x ) + { + adopt(x.px_); + return *this; + } + + void + adopt( T * px ) + { + release(); + px_=px; + add_ref(); + } + + T * + get() const + { + return px_; + } + + private: + + T * px_; + + void + add_ref() + { + if( px_ ) + px_->add_ref(); + } + + void + release() + { + if( px_ && px_->release() ) + px_=0; + } + }; + } + + //////////////////////////////////////////////////////////////////////// + + template + class error_info; + + typedef error_info throw_function; + typedef error_info throw_file; + typedef error_info throw_line; + typedef error_info throw_column; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef int value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef int value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + class + BOOST_SYMBOL_VISIBLE + exception; + + namespace + exception_detail + { + class error_info_base; + struct type_info_; + + struct + error_info_container + { + virtual char const * diagnostic_information( char const * ) const = 0; + virtual shared_ptr get( type_info_ const & ) const = 0; + virtual void set( shared_ptr const &, type_info_ const & ) = 0; + virtual void add_ref() const = 0; + virtual bool release() const = 0; + virtual refcount_ptr clone() const = 0; + + protected: + + ~error_info_container() BOOST_NOEXCEPT_OR_NOTHROW + { + } + }; + + template + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template + struct set_info_rv; + + template <> + struct set_info_rv; + + template <> + struct set_info_rv; + + template <> + struct set_info_rv; + + template <> + struct set_info_rv; + + char const * get_diagnostic_information( exception const &, char const * ); + + void copy_boost_exception( exception *, exception const * ); + + template + E const & set_info( E const &, error_info const & ); + + template + E const & set_info( E const &, throw_function const & ); + + template + E const & set_info( E const &, throw_file const & ); + + template + E const & set_info( E const &, throw_line const & ); + + template + E const & set_info( E const &, throw_column const & ); + + boost::source_location get_exception_throw_location( exception const & ); + } + + class + BOOST_SYMBOL_VISIBLE + exception + { + // + public: + template void set( typename Tag::type const & ); + template typename Tag::type const * get() const; + // + + protected: + + exception(): + throw_function_(0), + throw_file_(0), + throw_line_(-1), + throw_column_(-1) + { + } + +#ifdef __HP_aCC + //On HP aCC, this protected copy constructor prevents throwing boost::exception. + //On all other platforms, the same effect is achieved by the pure virtual destructor. + exception( exception const & x ) BOOST_NOEXCEPT_OR_NOTHROW: + data_(x.data_), + throw_function_(x.throw_function_), + throw_file_(x.throw_file_), + throw_line_(x.throw_line_), + throw_column_(x.throw_column_) + { + } +#endif + + virtual ~exception() BOOST_NOEXCEPT_OR_NOTHROW +#ifndef __HP_aCC + = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors. +#endif + ; + +#if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310) + public: +#else + private: + + template + friend E const & exception_detail::set_info( E const &, throw_function const & ); + + template + friend E const & exception_detail::set_info( E const &, throw_file const & ); + + template + friend E const & exception_detail::set_info( E const &, throw_line const & ); + + template + friend E const & exception_detail::set_info( E const &, throw_column const & ); + + template + friend E const & exception_detail::set_info( E const &, error_info const & ); + + friend char const * exception_detail::get_diagnostic_information( exception const &, char const * ); + + friend boost::source_location exception_detail::get_exception_throw_location( exception const & ); + + template + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + template + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend void exception_detail::copy_boost_exception( exception *, exception const * ); +#endif + mutable exception_detail::refcount_ptr data_; + mutable char const * throw_function_; + mutable char const * throw_file_; + mutable int throw_line_; + mutable int throw_column_; + }; + + inline + exception:: + ~exception() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + namespace + exception_detail + { + template + E const & + set_info( E const & x, throw_function const & y ) + { + x.throw_function_=y.v_; + return x; + } + + template + E const & + set_info( E const & x, throw_file const & y ) + { + x.throw_file_=y.v_; + return x; + } + + template + E const & + set_info( E const & x, throw_line const & y ) + { + x.throw_line_=y.v_; + return x; + } + + template + E const & + set_info( E const & x, throw_column const & y ) + { + x.throw_column_=y.v_; + return x; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + + template <> + struct + set_info_rv + { + template + static + E const & + set( E const & x, throw_column && y ) + { + x.throw_column_=y.v_; + return x; + } + }; + +#endif + + inline boost::source_location get_exception_throw_location( exception const & x ) + { + return boost::source_location( + x.throw_file_? x.throw_file_: "", + x.throw_line_ >= 0? x.throw_line_: 0, + x.throw_function_? x.throw_function_: "", + x.throw_column_ >= 0? x.throw_column_: 0 + ); + } + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { + template + struct + BOOST_SYMBOL_VISIBLE + error_info_injector: + public T, + public exception + { + explicit + error_info_injector( T const & x ): + T(x) + { + } + + ~error_info_injector() BOOST_NOEXCEPT_OR_NOTHROW + { + } + }; + + struct large_size { char c[256]; }; + large_size dispatch_boost_exception( exception const * ); + + struct small_size { }; + small_size dispatch_boost_exception( void const * ); + + template + struct enable_error_info_helper; + + template + struct + enable_error_info_helper + { + typedef T type; + }; + + template + struct + enable_error_info_helper + { + typedef error_info_injector type; + }; + + template + struct + enable_error_info_return_type + { + typedef typename enable_error_info_helper(0)))>::type type; + }; + } + + template + inline + typename + exception_detail::enable_error_info_return_type::type + enable_error_info( T const & x ) + { + typedef typename exception_detail::enable_error_info_return_type::type rt; + return rt(x); + } + + //////////////////////////////////////////////////////////////////////// +#if defined(BOOST_NO_EXCEPTIONS) + BOOST_NORETURN void throw_exception(std::exception const & e); // user defined +#endif + + namespace + exception_detail + { + class + BOOST_SYMBOL_VISIBLE + clone_base + { + public: + + virtual clone_base const * clone() const = 0; + virtual void rethrow() const = 0; + + virtual + ~clone_base() BOOST_NOEXCEPT_OR_NOTHROW + { + } + }; + + inline + void + copy_boost_exception( exception * a, exception const * b ) + { + refcount_ptr data; + if( error_info_container * d=b->data_.get() ) + data = d->clone(); + a->throw_file_ = b->throw_file_; + a->throw_line_ = b->throw_line_; + a->throw_function_ = b->throw_function_; + a->throw_column_ = b->throw_column_; + a->data_ = data; + } + + inline + void + copy_boost_exception( void *, void const * ) + { + } + + template + class + BOOST_SYMBOL_VISIBLE + clone_impl: + public T, + public virtual clone_base + { + struct clone_tag { }; + clone_impl( clone_impl const & x, clone_tag ): + T(x) + { + copy_boost_exception(this,&x); + } + + public: + + explicit + clone_impl( T const & x ): + T(x) + { + copy_boost_exception(this,&x); + } + + ~clone_impl() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + private: + + clone_base const * + clone() const + { + return new clone_impl(*this,clone_tag()); + } + + void + rethrow() const + { +#if defined(BOOST_NO_EXCEPTIONS) + boost::throw_exception(*this); +#else + throw*this; +#endif + } + }; + } + + template + inline + exception_detail::clone_impl + enable_current_exception( T const & x ) + { + return exception_detail::clone_impl(x); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif + +#endif // #ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 diff --git a/src/boost/limits.hpp b/src/boost/limits.hpp new file mode 100644 index 00000000..1b54477e --- /dev/null +++ b/src/boost/limits.hpp @@ -0,0 +1,146 @@ + +// (C) Copyright John maddock 1999. +// (C) David Abrahams 2002. 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) +// +// use this header as a workaround for missing + +// See http://www.boost.org/libs/compatibility/index.html for documentation. + +#ifndef BOOST_LIMITS +#define BOOST_LIMITS + +#include + +#ifdef BOOST_NO_LIMITS +# error "There is no std::numeric_limits suppport available." +#else +# include +#endif + +#if (defined(BOOST_HAS_LONG_LONG) && defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)) \ + || (defined(BOOST_HAS_MS_INT64) && defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS)) +// Add missing specializations for numeric_limits: +#ifdef BOOST_HAS_MS_INT64 +# define BOOST_LLT __int64 +# define BOOST_ULLT unsigned __int64 +#else +# define BOOST_LLT ::boost::long_long_type +# define BOOST_ULLT ::boost::ulong_long_type +#endif + +#include // for CHAR_BIT + +namespace std +{ + template<> + class numeric_limits + { + public: + + BOOST_STATIC_CONSTANT(bool, is_specialized = true); +#ifdef BOOST_HAS_MS_INT64 + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x8000000000000000i64; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x7FFFFFFFFFFFFFFFi64; } +#elif defined(LLONG_MAX) + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MIN; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MAX; } +#elif defined(LONGLONG_MAX) + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MIN; } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MAX; } +#else + static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); } + static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~(min)(); } +#endif + BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT -1); + BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT) - 1) * 301L / 1000); + BOOST_STATIC_CONSTANT(bool, is_signed = true); + BOOST_STATIC_CONSTANT(bool, is_integer = true); + BOOST_STATIC_CONSTANT(bool, is_exact = true); + BOOST_STATIC_CONSTANT(int, radix = 2); + static BOOST_LLT epsilon() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT round_error() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + + BOOST_STATIC_CONSTANT(int, min_exponent = 0); + BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); + BOOST_STATIC_CONSTANT(int, max_exponent = 0); + BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); + + BOOST_STATIC_CONSTANT(bool, has_infinity = false); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_denorm = false); + BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); + static BOOST_LLT infinity() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT quiet_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT signaling_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_LLT denorm_min() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + + BOOST_STATIC_CONSTANT(bool, is_iec559 = false); + BOOST_STATIC_CONSTANT(bool, is_bounded = true); + BOOST_STATIC_CONSTANT(bool, is_modulo = true); + + BOOST_STATIC_CONSTANT(bool, traps = false); + BOOST_STATIC_CONSTANT(bool, tinyness_before = false); + BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); + + }; + + template<> + class numeric_limits + { + public: + + BOOST_STATIC_CONSTANT(bool, is_specialized = true); +#ifdef BOOST_HAS_MS_INT64 + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0ui64; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0xFFFFFFFFFFFFFFFFui64; } +#elif defined(ULLONG_MAX) && defined(ULLONG_MIN) + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MIN; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MAX; } +#elif defined(ULONGLONG_MAX) && defined(ULONGLONG_MIN) + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MIN; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MAX; } +#else + static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0uLL; } + static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~0uLL; } +#endif + BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT); + BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT)) * 301L / 1000); + BOOST_STATIC_CONSTANT(bool, is_signed = false); + BOOST_STATIC_CONSTANT(bool, is_integer = true); + BOOST_STATIC_CONSTANT(bool, is_exact = true); + BOOST_STATIC_CONSTANT(int, radix = 2); + static BOOST_ULLT epsilon() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT round_error() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + + BOOST_STATIC_CONSTANT(int, min_exponent = 0); + BOOST_STATIC_CONSTANT(int, min_exponent10 = 0); + BOOST_STATIC_CONSTANT(int, max_exponent = 0); + BOOST_STATIC_CONSTANT(int, max_exponent10 = 0); + + BOOST_STATIC_CONSTANT(bool, has_infinity = false); + BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false); + BOOST_STATIC_CONSTANT(bool, has_denorm = false); + BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false); + static BOOST_ULLT infinity() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT quiet_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT signaling_NaN() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + static BOOST_ULLT denorm_min() BOOST_NOEXCEPT_OR_NOTHROW { return 0; }; + + BOOST_STATIC_CONSTANT(bool, is_iec559 = false); + BOOST_STATIC_CONSTANT(bool, is_bounded = true); + BOOST_STATIC_CONSTANT(bool, is_modulo = true); + + BOOST_STATIC_CONSTANT(bool, traps = false); + BOOST_STATIC_CONSTANT(bool, tinyness_before = false); + BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero); + + }; +} +#endif + +#endif + diff --git a/src/boost/mp11/algorithm.hpp b/src/boost/mp11/algorithm.hpp new file mode 100644 index 00000000..dd39fbaa --- /dev/null +++ b/src/boost/mp11/algorithm.hpp @@ -0,0 +1,1353 @@ +#ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED +#define BOOST_MP11_ALGORITHM_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov +// +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma push_macro( "I" ) +# undef I +#endif + +namespace boost +{ +namespace mp11 +{ + +// mp_transform +namespace detail +{ + +template class F, class... L> struct mp_transform_impl +{ +}; + +template class F, template class L, class... T> struct mp_transform_impl> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L::type...>; + +#else + + using type = L...>; + +#endif +}; + +template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_impl, L2> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + + using type = L1...>; + +#endif +}; + +template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_transform_impl, L2, L3> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + + using type = L1...>; + +#endif +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class F, template class L, auto... A> struct mp_transform_impl> +{ + using type = L< F< mp_value >::value... >; +}; + +template class F, template class L1, auto... A1, template class L2, auto... A2> struct mp_transform_impl, L2> +{ + using type = L1< F< mp_value, mp_value >::value... >; +}; + +template class F, template class L1, auto... A1, template class L2, auto... A2, template class L3, auto... A3> struct mp_transform_impl, L2, L3> +{ + using type = L1< F< mp_value, mp_value, mp_value >::value... >; +}; + +#endif + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template using mp_same_size_1 = mp_same...>; +template struct mp_same_size_2: mp_defer {}; + +#endif + +struct list_size_mismatch +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... L> struct mp_transform_cuda_workaround +{ + using type = mp_if...>, detail::mp_transform_impl, detail::list_size_mismatch>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1900 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template class F, class... L> using mp_transform = typename mp_if::type, detail::mp_transform_impl, detail::list_size_mismatch>::type; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... L> using mp_transform = typename detail::mp_transform_cuda_workaround< F, L...>::type::type; + +#else + +template class F, class... L> using mp_transform = typename mp_if...>, detail::mp_transform_impl, detail::list_size_mismatch>::type; + +#endif + +#endif + +template using mp_transform_q = mp_transform; + +namespace detail +{ + +template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4, class... L> struct mp_transform_impl, L2, L3, L4, L...> +{ + using A1 = L1...>; + + template using _f = mp_transform; + + using A2 = mp_fold, A1, _f>; + + template using _g = mp_apply; + + using type = mp_transform<_g, A2>; +}; + +} // namespace detail + +// mp_transform_if +namespace detail +{ + +template class P, template class F, class... L> struct mp_transform_if_impl +{ + // the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template" + + using Qp = mp_quote

; + using Qf = mp_quote; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct _f_ { using type = mp_eval_if_q>, mp_first>, Qf, U...>; }; + template using _f = typename _f_::type; + +#else + + template using _f = mp_eval_if_q>, mp_first>, Qf, U...>; + +#endif + + using type = mp_transform<_f, L...>; +}; + +} // namespace detail + +template class P, template class F, class... L> using mp_transform_if = typename detail::mp_transform_if_impl::type; +template using mp_transform_if_q = typename detail::mp_transform_if_impl::type; + +// mp_filter +namespace detail +{ + +template class P, class L1, class... L> struct mp_filter_impl +{ + using Qp = mp_quote

; + + template using _f = mp_if< mp_invoke_q, mp_list, mp_list<> >; + + using _t1 = mp_transform<_f, L1, L...>; + using _t2 = mp_apply; + + using type = mp_assign; +}; + +} // namespace detail + +template class P, class... L> using mp_filter = typename detail::mp_filter_impl::type; +template using mp_filter_q = typename detail::mp_filter_impl::type; + +// mp_fill +namespace detail +{ + +template struct mp_fill_impl +{ +// An error "no type named 'type'" here means that the L argument of mp_fill is not a list +}; + +template class L, class... T, class V> struct mp_fill_impl, V> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 ) + + template struct _f { using type = V; }; + using type = L::type...>; + +#else + + template using _f = V; + using type = L<_f...>; + +#endif +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, class V> struct mp_fill_impl, V> +{ + using type = L<((void)A, V::value)...>; +}; + +#endif + +} // namespace detail + +template using mp_fill = typename detail::mp_fill_impl::type; + +// mp_contains +template using mp_contains = mp_to_bool>; + +// mp_repeat(_c) +namespace detail +{ + +template struct mp_repeat_c_impl +{ + using _l1 = typename mp_repeat_c_impl::type; + using _l2 = typename mp_repeat_c_impl::type; + + using type = mp_append<_l1, _l1, _l2>; +}; + +template struct mp_repeat_c_impl +{ + using type = mp_clear; +}; + +template struct mp_repeat_c_impl +{ + using type = L; +}; + +} // namespace detail + +template using mp_repeat_c = typename detail::mp_repeat_c_impl::type; +template using mp_repeat = typename detail::mp_repeat_c_impl::type; + +// mp_product +namespace detail +{ + +template class F, class P, class... L> struct mp_product_impl_2 +{ +}; + +template class F, class P> struct mp_product_impl_2 +{ + using type = mp_list>; +}; + +template class F, class P, template class L1, class... T1, class... L> struct mp_product_impl_2, L...> +{ + using type = mp_append, L...>::type...>; +}; + +template class F, class... L> struct mp_product_impl +{ +}; + +template class F> struct mp_product_impl +{ + using type = mp_list< F<> >; +}; + +template class F, class L1, class... L> struct mp_product_impl +{ + using type = mp_assign, L1, L...>::type>; +}; + +} // namespace detail + +template class F, class... L> using mp_product = typename detail::mp_product_impl::type; +template using mp_product_q = typename detail::mp_product_impl::type; + +// mp_drop(_c) +namespace detail +{ + +template struct mp_drop_impl; + +template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2, mp_true> +{ + template static mp_identity> f( U*..., mp_identity*... ); + + using R = decltype( f( static_cast*>(0) ... ) ); + + using type = typename R::type; +}; + +} // namespace detail + +template using mp_drop_c = mp_assign, mp_repeat_c, N>, mp_bool::value>>::type>; + +template using mp_drop = mp_drop_c; + +// mp_from_sequence +namespace detail +{ + +template struct mp_from_sequence_impl; + +template class S, class U, U... J, class F> struct mp_from_sequence_impl, F, false> +{ + using type = mp_list_c; +}; + +template class S, class U, U... J, class F> struct mp_from_sequence_impl, F, true> +{ + using type = mp_list_c; +}; + +} // namespace detail + +template> using mp_from_sequence = typename detail::mp_from_sequence_impl::type; + +// mp_iota(_c) +template using mp_iota_c = mp_from_sequence, mp_size_t>; +template> using mp_iota = mp_from_sequence::type, N::value>, F>; + +// mp_at(_c) +namespace detail +{ + +template struct mp_at_c_impl; + +#if defined(BOOST_MP11_HAS_TYPE_PACK_ELEMENT) + +template class L, class... T, std::size_t I> struct mp_at_c_impl, I> +{ + using type = __type_pack_element; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, std::size_t I> struct mp_at_c_impl, I> +{ + using type = __type_pack_element...>; +}; + +#endif + +#else + +template struct mp_at_c_impl +{ + using _map = mp_transform >, mp_rename>; + using type = mp_second > >; +}; + +#endif + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template struct mp_at_c_cuda_workaround +{ + using type = mp_if_c<(I < mp_size::value), detail::mp_at_c_impl, void>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template using mp_at_c = typename detail::mp_at_c_cuda_workaround< L, I >::type::type; + +#else + +template using mp_at_c = typename mp_if_c<(I < mp_size::value), detail::mp_at_c_impl, void>::type; + +#endif + +template using mp_at = mp_at_c; + +// mp_take(_c) +namespace detail +{ + +template struct mp_take_c_impl +{ +}; + +template class L, class... T> +struct mp_take_c_impl<0, L> +{ + using type = L<>; +}; + +template class L, class T1, class... T> +struct mp_take_c_impl<1, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class... T> +struct mp_take_c_impl<2, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class... T> +struct mp_take_c_impl<3, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class... T> +struct mp_take_c_impl<4, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class... T> +struct mp_take_c_impl<5, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class... T> +struct mp_take_c_impl<6, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class... T> +struct mp_take_c_impl<7, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class... T> +struct mp_take_c_impl<8, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class... T> +struct mp_take_c_impl<9, L> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, std::size_t N> +struct mp_take_c_impl, typename std::enable_if= 10>::type> +{ + using type = mp_append, typename mp_take_c_impl>::type>; +}; + +} // namespace detail + +template using mp_take_c = mp_assign>::type>; +template using mp_take = mp_take_c; + +// mp_slice(_c) +template using mp_slice_c = mp_drop_c< mp_take_c, I >; +template using mp_slice = mp_drop< mp_take, I >; + +// mp_back +template using mp_back = mp_at_c::value - 1>; + +// mp_pop_back +template using mp_pop_back = mp_take_c::value - 1>; + +// mp_replace +namespace detail +{ + +template struct mp_replace_impl; + +template class L, class... T, class V, class W> struct mp_replace_impl, V, W> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + template struct _f { using type = mp_if, W, A>; }; + using type = L::type...>; +#else + template using _f = mp_if, W, A>; + using type = L<_f...>; +#endif +}; + +} // namespace detail + +template using mp_replace = typename detail::mp_replace_impl::type; + +// mp_replace_if +namespace detail +{ + +template class P, class W> struct mp_replace_if_impl; + +template class L, class... T, template class P, class W> struct mp_replace_if_impl, P, W> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, W, U>; }; + using type = L::type...>; +#else + template using _f = mp_if, W, U>; + using type = L<_f...>; +#endif +}; + +} // namespace detail + +template class P, class W> using mp_replace_if = typename detail::mp_replace_if_impl::type; +template using mp_replace_if_q = mp_replace_if; + +// mp_copy_if +// in detail/mp_copy_if.hpp + +// mp_remove +namespace detail +{ + +template struct mp_remove_impl; + +template class L, class... T, class V> struct mp_remove_impl, V> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list<>, mp_list>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list<>, mp_list>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template using mp_remove = typename detail::mp_remove_impl::type; + +// mp_remove_if +// in detail/mp_remove_if.hpp + +// mp_flatten> +namespace detail +{ + +template struct mp_flatten_impl +{ + template using fn = mp_if, T, mp_list>; +}; + +} // namespace detail + +template> using mp_flatten = mp_apply, L>, mp_clear>>; + +// mp_partition +namespace detail +{ + +template class P> struct mp_partition_impl; + +template class L, class... T, template class P> struct mp_partition_impl, P> +{ + using type = L, P>, mp_remove_if, P>>; +}; + +} // namespace detail + +template class P> using mp_partition = typename detail::mp_partition_impl::type; +template using mp_partition_q = mp_partition; + +// mp_sort +namespace detail +{ + +template class P> struct mp_sort_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_sort_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, template class P> struct mp_sort_impl, P> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, template class P> struct mp_sort_impl, P> +{ + using type = L; +}; + +template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +{ + template using F = P; + + using part = mp_partition, F>; + + using S1 = typename mp_sort_impl, P>::type; + using S2 = typename mp_sort_impl, P>::type; + + using type = mp_append, S2>; +}; + +} // namespace detail + +template class P> using mp_sort = typename detail::mp_sort_impl::type; +template using mp_sort_q = mp_sort; + +// mp_nth_element(_c) +namespace detail +{ + +template class P> struct mp_nth_element_impl; + +template class L, class T1, std::size_t I, template class P> struct mp_nth_element_impl, I, P> +{ + static_assert( I == 0, "mp_nth_element index out of range" ); + using type = T1; +}; + +template class L, class T1, class... T, std::size_t I, template class P> struct mp_nth_element_impl, I, P> +{ + static_assert( I < 1 + sizeof...(T), "mp_nth_element index out of range" ); + + template using F = P; + + using part = mp_partition, F>; + + using L1 = mp_first; + static std::size_t const N1 = mp_size::value; + + using L2 = mp_second; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + + struct detail + { + struct mp_nth_element_impl_cuda_workaround + { + using type = mp_cond< + + mp_bool<(I < N1)>, mp_nth_element_impl, + mp_bool<(I == N1)>, mp_identity, + mp_true, mp_nth_element_impl + + >; + }; + }; + + using type = typename detail::mp_nth_element_impl_cuda_workaround::type::type; + +#else + + using type = typename mp_cond< + + mp_bool<(I < N1)>, mp_nth_element_impl, + mp_bool<(I == N1)>, mp_identity, + mp_true, mp_nth_element_impl + + >::type; + +#endif +}; + +} // namespace detail + +template class P> using mp_nth_element_c = typename detail::mp_nth_element_impl::type; +template class P> using mp_nth_element = typename detail::mp_nth_element_impl::type; +template using mp_nth_element_q = mp_nth_element; + +// mp_find +namespace detail +{ + +template struct mp_find_impl; + +#if !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) + +constexpr std::size_t cx_find_index( bool const * first, bool const * last ) +{ + std::size_t m = 0; + + while( first != last && !*first ) + { + ++m; + ++first; + } + + return m; +} + +#else + +constexpr std::size_t cx_find_index( bool const * first, bool const * last ) +{ + return first == last || *first? 0: 1 + cx_find_index( first + 1, last ); +} + +#endif + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static constexpr bool _v[] = { std::is_same::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class L, class... T, class V> struct mp_find_impl, V> +{ + using type = mp_size_t<0>; +}; + +template class L, class T1, class... T, class V> struct mp_find_impl, V> +{ + using _r = typename mp_find_impl, V>::type; + using type = mp_size_t<1 + _r::value>; +}; + +#endif + +} // namespace detail + +template using mp_find = typename detail::mp_find_impl::type; + +// mp_find_if +namespace detail +{ + +template class P> struct mp_find_if_impl; + +#if !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, template class P> struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static constexpr bool _v[] = { P::value... }; + using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >; +}; + +#else + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = mp_size_t<0>; +}; + +#else + +template class L, template class P> struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +#endif + +template class P> struct mp_find_if_impl_2 +{ + using _r = typename mp_find_if_impl::type; + using type = mp_size_t<1 + _r::value>; +}; + +template class L, class T1, class... T, template class P> struct mp_find_if_impl, P> +{ + using type = typename mp_if, mp_identity>, mp_find_if_impl_2, P>>::type; +}; + +#endif + +} // namespace detail + +template class P> using mp_find_if = typename detail::mp_find_if_impl::type; +template using mp_find_if_q = mp_find_if; + +// mp_reverse +namespace detail +{ + +template struct mp_reverse_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T> struct mp_reverse_impl> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L> struct mp_reverse_impl> +{ + using type = L<>; +}; + +#endif + +template class L, class T1> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_reverse_impl> +{ + using type = mp_push_back>::type, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1>; +}; + +} // namespace detail + +template using mp_reverse = typename detail::mp_reverse_impl::type; + +// mp_fold +// in detail/mp_fold.hpp + +// mp_reverse_fold +namespace detail +{ + +template class F> struct mp_reverse_fold_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +template class L, class T1, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using rest = typename mp_reverse_fold_impl, V, F>::type; + using type = F; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using rest = typename mp_reverse_fold_impl, V, F>::type; + using type = F > > > > > > > > >; +}; + +} // namespace detail + +template class F> using mp_reverse_fold = typename detail::mp_reverse_fold_impl::type; +template using mp_reverse_fold_q = mp_reverse_fold; + +// mp_unique +namespace detail +{ + +template struct mp_unique_impl; + +template class L, class... T> struct mp_unique_impl> +{ + using type = mp_set_push_back, T...>; +}; + +} // namespace detail + +template using mp_unique = typename detail::mp_unique_impl::type; + +// mp_unique_if +namespace detail +{ + +template class P> struct mp_unique_if_push_back +{ + template struct impl + { + }; + + template class L, class... Ts, class T> + struct impl, T> + { + using type = mp_if...>, L, L>; + }; + + template using fn = typename impl::type; +}; + +} // namespace detail + +template class P> +using mp_unique_if = mp_fold_q, detail::mp_unique_if_push_back

>; + +template using mp_unique_if_q = mp_unique_if; + +// mp_all_of +template class P> using mp_all_of = mp_bool< mp_count_if::value == mp_size::value >; +template using mp_all_of_q = mp_all_of; + +// mp_none_of +template class P> using mp_none_of = mp_bool< mp_count_if::value == 0 >; +template using mp_none_of_q = mp_none_of; + +// mp_any_of +template class P> using mp_any_of = mp_bool< mp_count_if::value != 0 >; +template using mp_any_of_q = mp_any_of; + +// mp_replace_at_c +namespace detail +{ + +template struct mp_replace_at_impl +{ + static_assert( I::value >= 0, "mp_replace_at: I must not be negative" ); + + template using _p = std::is_same>; + template using _f = W; + + using type = mp_transform_if<_p, _f, L, mp_iota > >; +}; + +} // namespace detail + +template using mp_replace_at = typename detail::mp_replace_at_impl::type; +template using mp_replace_at_c = typename detail::mp_replace_at_impl, W>::type; + +//mp_for_each(f) +namespace detail +{ + +template BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list, F && f ) +{ + using A = int[sizeof...(T)]; + return (void)A{ ((void)f(T()), 0)... }, std::forward(f); +} + +template BOOST_MP11_CONSTEXPR F mp_for_each_impl( mp_list<>, F && f ) +{ + return std::forward(f); +} + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, >= 1900 ) + +// msvc has a limit of 1024 + +template BOOST_MP11_CONSTEXPR mp_if_c::value <= 1024, F> mp_for_each( F && f ) +{ + return detail::mp_for_each_impl( mp_rename(), std::forward(f) ); +} + +template BOOST_MP11_CONSTEXPR mp_if_c::value >= 1025, F> mp_for_each( F && f ) +{ + using L2 = mp_rename; + + using L3 = mp_take_c; + using L4 = mp_drop_c; + + return mp_for_each( mp_for_each( std::forward(f) ) ); +} + +#else + +template BOOST_MP11_CONSTEXPR F mp_for_each( F && f ) +{ + return detail::mp_for_each_impl( mp_rename(), std::forward(f) ); +} + +#endif + +// mp_insert +template using mp_insert = mp_append, mp_push_front, T...>>; + +// mp_insert_c +template using mp_insert_c = mp_append, mp_push_front, T...>>; + +// mp_erase +template using mp_erase = mp_append, mp_drop>; + +// mp_erase_c +template using mp_erase_c = mp_append, mp_drop_c>; + +// mp_starts_with +// contributed by Glen Joseph Fernandes (glenjofe@gmail.com) +namespace detail { + +template +struct mp_starts_with_impl { }; + +template class L1, class... T1, template class L2, + class... T2> +struct mp_starts_with_impl, L2 > { + template + static mp_false check(L); + + template + static mp_true check(mp_list); + + using type = decltype(check(mp_list())); +}; + +} // namespace detail + +template +using mp_starts_with = typename detail::mp_starts_with_impl::type; + +// mp_rotate_left(_c) +namespace detail +{ + +// limit divisor to 1 to avoid division by 0 and give a rotation of 0 for lists containing 0 or 1 elements +template using canonical_left_rotation = mp_size_t; + +// perform right rotation as a left rotation by inverting the number of elements to rotate +template using canonical_right_rotation = mp_size_t; + +// avoid errors when rotating fixed-sized lists by using mp_list for the transformation +template> using mp_rotate_impl = mp_assign, mp_take >>; + +} // namespace detail + +template using mp_rotate_left_c = detail::mp_rotate_impl::value, N>>; +template using mp_rotate_left = mp_rotate_left_c; + +// mp_rotate_right(_c) +template using mp_rotate_right_c = mp_rotate_left::value, N>>; +template using mp_rotate_right = mp_rotate_right_c; + +// mp_min_element +// mp_max_element +// in detail/mp_min_element.hpp + +// mp_power_set +namespace detail +{ + +template struct mp_power_set_impl; + +} // namespace detail + +template using mp_power_set = typename detail::mp_power_set_impl::type; + +namespace detail +{ + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T> struct mp_power_set_impl< L > +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L< L<> >; +}; + +#else + +template class L> struct mp_power_set_impl< L<> > +{ + using type = L< L<> >; +}; + +#endif + +template class L, class T1, class... T> struct mp_power_set_impl< L > +{ + using S1 = mp_power_set< L >; + + template using _f = mp_push_front; + + using S2 = mp_transform<_f, S1>; + + using type = mp_append< S1, S2 >; +}; + +} // namespace detail + +// mp_partial_sum +namespace detail +{ + +template class F> struct mp_partial_sum_impl_f +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 ) + + template using fn = mp_list, T>, mp_push_back, F, T>> >; + +#else + + template, T>> using fn = mp_list, N>>; + +#endif +}; + +} // namespace detail + +template class F> using mp_partial_sum = mp_second>, detail::mp_partial_sum_impl_f> >; +template using mp_partial_sum_q = mp_partial_sum; + +// mp_iterate +namespace detail +{ + +template class F, template class R, class N> struct mp_iterate_impl; + +} // namespace detail + +template class F, template class R> using mp_iterate = typename detail::mp_iterate_impl>::type; + +namespace detail +{ + +template class F, template class R> struct mp_iterate_impl +{ + template using _f = mp_list>; + using type = mp_eval_or, _f, V>; +}; + +template class F, template class R> struct mp_iterate_impl +{ + using type = mp_push_front, F, R>, F>; +}; + +} // namespace detail + +template using mp_iterate_q = mp_iterate; + +// mp_pairwise_fold +namespace detail +{ + +template using mp_pairwise_fold_impl = mp_transform_q, mp_pop_front>; + +} // namespace detail + +template using mp_pairwise_fold_q = mp_eval_if, mp_clear, detail::mp_pairwise_fold_impl, L, Q>; +template class F> using mp_pairwise_fold = mp_pairwise_fold_q>; + +// mp_sliding_fold +namespace detail +{ + +template struct mp_sliding_fold_impl; + +template struct mp_sliding_fold_impl +{ + static const std::size_t M = mp_size::value - N::value + 1; + + template using F = mp_slice_c; + + using J = mp_transform>; + + using type = mp_apply>; +}; + +template struct mp_sliding_fold_impl +{ + using type = mp_clear; +}; + +} // namespace detail + +template using mp_sliding_fold_q = typename detail::mp_sliding_fold_impl::value >= N::value)>, L, N, Q>::type; +template class F> using mp_sliding_fold = mp_sliding_fold_q>; + +// mp_intersperse +namespace detail +{ + +template struct mp_intersperse_impl +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class S> struct mp_intersperse_impl, S> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, class S> struct mp_intersperse_impl, S> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, class... T, class S> struct mp_intersperse_impl, S> +{ + using type = mp_append, L...>; +}; + +} // namespace detail + +template using mp_intersperse = typename detail::mp_intersperse_impl::type; + +// mp_split +namespace detail +{ + +template struct mp_split_impl; + +} // namespace detail + +template using mp_split = typename detail::mp_split_impl>::type; + +namespace detail +{ + +template using mp_split_impl_ = mp_push_front, S>, mp_take>; + +template struct mp_split_impl +{ + using type = mp_eval_if_c::value == J::value, mp_push_back, L>, mp_split_impl_, L, S, J>; +}; + +} // namespace detail + +// mp_join + +template using mp_join = mp_apply>>; + +} // namespace mp11 +} // namespace boost + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma pop_macro( "I" ) +#endif + +#endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED diff --git a/src/boost/mp11/bind.hpp b/src/boost/mp11/bind.hpp new file mode 100644 index 00000000..289b073f --- /dev/null +++ b/src/boost/mp11/bind.hpp @@ -0,0 +1,120 @@ +#ifndef BOOST_MP11_BIND_HPP_INCLUDED +#define BOOST_MP11_BIND_HPP_INCLUDED + +// Copyright 2017, 2018 Peter Dimov. +// +// 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 +#include +#include + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma push_macro( "I" ) +# undef I +#endif + +namespace boost +{ +namespace mp11 +{ + +// mp_bind_front +template class F, class... T> struct mp_bind_front +{ + // the indirection through mp_defer works around the language inability + // to expand U... into a fixed parameter list of an alias template + + template using fn = typename mp_defer::type; +}; + +template using mp_bind_front_q = mp_bind_front; + +// mp_bind_back +template class F, class... T> struct mp_bind_back +{ + template using fn = typename mp_defer::type; +}; + +template using mp_bind_back_q = mp_bind_back; + +// mp_arg +template struct mp_arg +{ + template using fn = mp_at_c, I>; +}; + +using _1 = mp_arg<0>; +using _2 = mp_arg<1>; +using _3 = mp_arg<2>; +using _4 = mp_arg<3>; +using _5 = mp_arg<4>; +using _6 = mp_arg<5>; +using _7 = mp_arg<6>; +using _8 = mp_arg<7>; +using _9 = mp_arg<8>; + +// mp_bind +template class F, class... T> struct mp_bind; + +namespace detail +{ + +template struct eval_bound_arg +{ + using type = V; +}; + +template struct eval_bound_arg, T...> +{ + using type = typename mp_arg::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind_front::template fn; +}; + +template class F, class... U, class... T> struct eval_bound_arg, T...> +{ + using type = typename mp_bind_back::template fn; +}; + +} // namespace detail + +template class F, class... T> struct mp_bind +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1915 ) +private: + + template struct _f { using type = F::type...>; }; + +public: + + template using fn = typename _f::type; + +#else + + template using fn = F::type...>; + +#endif +}; + +template using mp_bind_q = mp_bind; + +} // namespace mp11 +} // namespace boost + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma pop_macro( "I" ) +#endif + +#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED diff --git a/src/boost/mp11/detail/config.hpp b/src/boost/mp11/detail/config.hpp new file mode 100644 index 00000000..44686c73 --- /dev/null +++ b/src/boost/mp11/detail/config.hpp @@ -0,0 +1,149 @@ +#ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED +#define BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED + +// Copyright 2016, 2018, 2019 Peter Dimov. +// +// 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 + +// BOOST_MP11_WORKAROUND + +#if defined( BOOST_STRICT_CONFIG ) || defined( BOOST_MP11_NO_WORKAROUNDS ) + +# define BOOST_MP11_WORKAROUND( symbol, test ) 0 + +#else + +# define BOOST_MP11_WORKAROUND( symbol, test ) ((symbol) != 0 && ((symbol) test)) + +#endif + +// + +#define BOOST_MP11_CUDA 0 +#define BOOST_MP11_CLANG 0 +#define BOOST_MP11_INTEL 0 +#define BOOST_MP11_GCC 0 +#define BOOST_MP11_MSVC 0 + +#define BOOST_MP11_CONSTEXPR constexpr + +#if defined( __CUDACC__ ) + +// nvcc + +# undef BOOST_MP11_CUDA +# define BOOST_MP11_CUDA (__CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__) + +// CUDA (8.0) has no constexpr support in msvc mode: +# if defined(_MSC_VER) && (BOOST_MP11_CUDA < 9000000) + +# define BOOST_MP11_NO_CONSTEXPR + +# undef BOOST_MP11_CONSTEXPR +# define BOOST_MP11_CONSTEXPR + +# endif + +#endif + +#if defined(__clang__) + +// Clang + +# undef BOOST_MP11_CLANG +# define BOOST_MP11_CLANG (__clang_major__ * 100 + __clang_minor__) + +# if defined(__has_cpp_attribute) +# if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode +# define BOOST_MP11_HAS_FOLD_EXPRESSIONS +# endif +# endif + +#if BOOST_MP11_CLANG < 400 && __cplusplus >= 201402L \ + && defined( __GLIBCXX__ ) && !__has_include() + +// Clang pre-4 in C++14 mode, libstdc++ pre-4.9, ::gets is not defined, +// but Clang tries to import it into std + + extern "C" char *gets (char *__s); +#endif + +#elif defined(__INTEL_COMPILER) + +// Intel C++ + +# undef BOOST_MP11_INTEL +# define BOOST_MP11_INTEL __INTEL_COMPILER + +#elif defined(__GNUC__) + +// g++ + +# undef BOOST_MP11_GCC +# define BOOST_MP11_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) + +#elif defined(_MSC_VER) + +// MS Visual C++ + +# undef BOOST_MP11_MSVC +# define BOOST_MP11_MSVC _MSC_VER + +# if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) +# define BOOST_MP11_NO_CONSTEXPR +# endif + +#if _MSC_FULL_VER < 190024210 // 2015u3 +# undef BOOST_MP11_CONSTEXPR +# define BOOST_MP11_CONSTEXPR +#endif + +#endif + +// BOOST_MP11_HAS_CXX14_CONSTEXPR + +#if !defined(BOOST_MP11_NO_CONSTEXPR) && defined(__cpp_constexpr) && __cpp_constexpr >= 201304 +# define BOOST_MP11_HAS_CXX14_CONSTEXPR +#endif + +// BOOST_MP11_HAS_FOLD_EXPRESSIONS + +#if !defined(BOOST_MP11_HAS_FOLD_EXPRESSIONS) && defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603 +# define BOOST_MP11_HAS_FOLD_EXPRESSIONS +#endif + +// BOOST_MP11_HAS_TYPE_PACK_ELEMENT + +#if defined(__has_builtin) +# if __has_builtin(__type_pack_element) +# define BOOST_MP11_HAS_TYPE_PACK_ELEMENT +# endif +#endif + +// BOOST_MP11_HAS_TEMPLATE_AUTO + +#if defined(__cpp_nontype_template_parameter_auto) && __cpp_nontype_template_parameter_auto >= 201606L +# define BOOST_MP11_HAS_TEMPLATE_AUTO +#endif + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) +// mp_value<0> is bool, mp_value<-1L> is int, etc +# undef BOOST_MP11_HAS_TEMPLATE_AUTO +#endif + +// BOOST_MP11_DEPRECATED(msg) + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, < 304 ) +# define BOOST_MP11_DEPRECATED(msg) +#elif defined(__GNUC__) || defined(__clang__) +# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg))) +#elif defined(_MSC_VER) && _MSC_VER >= 1900 +# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]] +#else +# define BOOST_MP11_DEPRECATED(msg) +#endif + +#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_append.hpp b/src/boost/mp11/detail/mp_append.hpp new file mode 100644 index 00000000..858ee24e --- /dev/null +++ b/src/boost/mp11/detail/mp_append.hpp @@ -0,0 +1,321 @@ +#ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_append + +namespace detail +{ + +// append_type_lists + +template struct mp_append_impl; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template struct mp_append_impl +{ +}; + +template<> struct mp_append_impl<> +{ + using type = mp_list<>; +}; + +template class L, class... T> struct mp_append_impl> +{ + using type = L; +}; + +template class L1, class... T1, template class L2, class... T2> struct mp_append_impl, L2> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_append_impl, L2, L3> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4> struct mp_append_impl, L2, L3, L4> +{ + using type = L1; +}; + +template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4, template class L5, class... T5, class... Lr> struct mp_append_impl, L2, L3, L4, L5, Lr...> +{ + using type = typename mp_append_impl, Lr...>::type; +}; + +#else + +template, class L2 = mp_list<>, class L3 = mp_list<>, class L4 = mp_list<>, class L5 = mp_list<>, class L6 = mp_list<>, class L7 = mp_list<>, class L8 = mp_list<>, class L9 = mp_list<>, class L10 = mp_list<>, class L11 = mp_list<>> struct append_11_impl +{ +}; + +template< + template class L1, class... T1, + template class L2, class... T2, + template class L3, class... T3, + template class L4, class... T4, + template class L5, class... T5, + template class L6, class... T6, + template class L7, class... T7, + template class L8, class... T8, + template class L9, class... T9, + template class L10, class... T10, + template class L11, class... T11> + +struct append_11_impl, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11> +{ + using type = L1; +}; + +template< + + class L00 = mp_list<>, class L01 = mp_list<>, class L02 = mp_list<>, class L03 = mp_list<>, class L04 = mp_list<>, class L05 = mp_list<>, class L06 = mp_list<>, class L07 = mp_list<>, class L08 = mp_list<>, class L09 = mp_list<>, class L0A = mp_list<>, + class L10 = mp_list<>, class L11 = mp_list<>, class L12 = mp_list<>, class L13 = mp_list<>, class L14 = mp_list<>, class L15 = mp_list<>, class L16 = mp_list<>, class L17 = mp_list<>, class L18 = mp_list<>, class L19 = mp_list<>, + class L20 = mp_list<>, class L21 = mp_list<>, class L22 = mp_list<>, class L23 = mp_list<>, class L24 = mp_list<>, class L25 = mp_list<>, class L26 = mp_list<>, class L27 = mp_list<>, class L28 = mp_list<>, class L29 = mp_list<>, + class L30 = mp_list<>, class L31 = mp_list<>, class L32 = mp_list<>, class L33 = mp_list<>, class L34 = mp_list<>, class L35 = mp_list<>, class L36 = mp_list<>, class L37 = mp_list<>, class L38 = mp_list<>, class L39 = mp_list<>, + class L40 = mp_list<>, class L41 = mp_list<>, class L42 = mp_list<>, class L43 = mp_list<>, class L44 = mp_list<>, class L45 = mp_list<>, class L46 = mp_list<>, class L47 = mp_list<>, class L48 = mp_list<>, class L49 = mp_list<>, + class L50 = mp_list<>, class L51 = mp_list<>, class L52 = mp_list<>, class L53 = mp_list<>, class L54 = mp_list<>, class L55 = mp_list<>, class L56 = mp_list<>, class L57 = mp_list<>, class L58 = mp_list<>, class L59 = mp_list<>, + class L60 = mp_list<>, class L61 = mp_list<>, class L62 = mp_list<>, class L63 = mp_list<>, class L64 = mp_list<>, class L65 = mp_list<>, class L66 = mp_list<>, class L67 = mp_list<>, class L68 = mp_list<>, class L69 = mp_list<>, + class L70 = mp_list<>, class L71 = mp_list<>, class L72 = mp_list<>, class L73 = mp_list<>, class L74 = mp_list<>, class L75 = mp_list<>, class L76 = mp_list<>, class L77 = mp_list<>, class L78 = mp_list<>, class L79 = mp_list<>, + class L80 = mp_list<>, class L81 = mp_list<>, class L82 = mp_list<>, class L83 = mp_list<>, class L84 = mp_list<>, class L85 = mp_list<>, class L86 = mp_list<>, class L87 = mp_list<>, class L88 = mp_list<>, class L89 = mp_list<>, + class L90 = mp_list<>, class L91 = mp_list<>, class L92 = mp_list<>, class L93 = mp_list<>, class L94 = mp_list<>, class L95 = mp_list<>, class L96 = mp_list<>, class L97 = mp_list<>, class L98 = mp_list<>, class L99 = mp_list<>, + class LA0 = mp_list<>, class LA1 = mp_list<>, class LA2 = mp_list<>, class LA3 = mp_list<>, class LA4 = mp_list<>, class LA5 = mp_list<>, class LA6 = mp_list<>, class LA7 = mp_list<>, class LA8 = mp_list<>, class LA9 = mp_list<> + +> struct append_111_impl +{ + using type = typename append_11_impl< + + typename append_11_impl::type, + typename append_11_impl, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type, + typename append_11_impl, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type, + typename append_11_impl, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type, + typename append_11_impl, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type, + typename append_11_impl, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type, + typename append_11_impl, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type, + typename append_11_impl, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type, + typename append_11_impl, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type, + typename append_11_impl, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type, + typename append_11_impl, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type + + >::type; +}; + +template< + + class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A, + class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19, + class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29, + class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39, + class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49, + class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59, + class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69, + class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79, + class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89, + class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99, + class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9, + class... Lr + +> struct append_inf_impl +{ + using prefix = typename append_111_impl< + + L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A, + L10, L11, L12, L13, L14, L15, L16, L17, L18, L19, + L20, L21, L22, L23, L24, L25, L26, L27, L28, L29, + L30, L31, L32, L33, L34, L35, L36, L37, L38, L39, + L40, L41, L42, L43, L44, L45, L46, L47, L48, L49, + L50, L51, L52, L53, L54, L55, L56, L57, L58, L59, + L60, L61, L62, L63, L64, L65, L66, L67, L68, L69, + L70, L71, L72, L73, L74, L75, L76, L77, L78, L79, + L80, L81, L82, L83, L84, L85, L86, L87, L88, L89, + L90, L91, L92, L93, L94, L95, L96, L97, L98, L99, + LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9 + + >::type; + + using type = typename mp_append_impl::type; +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template +struct mp_append_impl_cuda_workaround +{ + using type = mp_if_c<(sizeof...(L) > 111), mp_quote, mp_if_c<(sizeof...(L) > 11), mp_quote, mp_quote > >; +}; + +template struct mp_append_impl: mp_append_impl_cuda_workaround::type::template fn +{ +}; + +#else + +template struct mp_append_impl: + mp_cond< + mp_bool<(sizeof...(L) > 111)>, mp_quote, + mp_bool<(sizeof...(L) > 11)>, mp_quote, + mp_true, mp_quote + >::template fn +{ +}; + +#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +struct append_type_lists +{ + template using fn = typename mp_append_impl::type; +}; + +// append_value_lists + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template struct append_value_impl; + +template, class L2 = mp_list_v<>, class L3 = mp_list_v<>, class L4 = mp_list_v<>, class L5 = mp_list_v<>, class L6 = mp_list_v<>, class L7 = mp_list_v<>, class L8 = mp_list_v<>, class L9 = mp_list_v<>, class L10 = mp_list_v<>, class L11 = mp_list_v<>> struct append_value_11_impl +{ +}; + +template< + template class L1, auto... T1, + template class L2, auto... T2, + template class L3, auto... T3, + template class L4, auto... T4, + template class L5, auto... T5, + template class L6, auto... T6, + template class L7, auto... T7, + template class L8, auto... T8, + template class L9, auto... T9, + template class L10, auto... T10, + template class L11, auto... T11> + +struct append_value_11_impl, L2, L3, L4, L5, L6, L7, L8, L9, L10, L11> +{ + using type = L1; +}; + +template< + + class L00 = mp_list_v<>, class L01 = mp_list_v<>, class L02 = mp_list_v<>, class L03 = mp_list_v<>, class L04 = mp_list_v<>, class L05 = mp_list_v<>, class L06 = mp_list_v<>, class L07 = mp_list_v<>, class L08 = mp_list_v<>, class L09 = mp_list_v<>, class L0A = mp_list_v<>, + class L10 = mp_list_v<>, class L11 = mp_list_v<>, class L12 = mp_list_v<>, class L13 = mp_list_v<>, class L14 = mp_list_v<>, class L15 = mp_list_v<>, class L16 = mp_list_v<>, class L17 = mp_list_v<>, class L18 = mp_list_v<>, class L19 = mp_list_v<>, + class L20 = mp_list_v<>, class L21 = mp_list_v<>, class L22 = mp_list_v<>, class L23 = mp_list_v<>, class L24 = mp_list_v<>, class L25 = mp_list_v<>, class L26 = mp_list_v<>, class L27 = mp_list_v<>, class L28 = mp_list_v<>, class L29 = mp_list_v<>, + class L30 = mp_list_v<>, class L31 = mp_list_v<>, class L32 = mp_list_v<>, class L33 = mp_list_v<>, class L34 = mp_list_v<>, class L35 = mp_list_v<>, class L36 = mp_list_v<>, class L37 = mp_list_v<>, class L38 = mp_list_v<>, class L39 = mp_list_v<>, + class L40 = mp_list_v<>, class L41 = mp_list_v<>, class L42 = mp_list_v<>, class L43 = mp_list_v<>, class L44 = mp_list_v<>, class L45 = mp_list_v<>, class L46 = mp_list_v<>, class L47 = mp_list_v<>, class L48 = mp_list_v<>, class L49 = mp_list_v<>, + class L50 = mp_list_v<>, class L51 = mp_list_v<>, class L52 = mp_list_v<>, class L53 = mp_list_v<>, class L54 = mp_list_v<>, class L55 = mp_list_v<>, class L56 = mp_list_v<>, class L57 = mp_list_v<>, class L58 = mp_list_v<>, class L59 = mp_list_v<>, + class L60 = mp_list_v<>, class L61 = mp_list_v<>, class L62 = mp_list_v<>, class L63 = mp_list_v<>, class L64 = mp_list_v<>, class L65 = mp_list_v<>, class L66 = mp_list_v<>, class L67 = mp_list_v<>, class L68 = mp_list_v<>, class L69 = mp_list_v<>, + class L70 = mp_list_v<>, class L71 = mp_list_v<>, class L72 = mp_list_v<>, class L73 = mp_list_v<>, class L74 = mp_list_v<>, class L75 = mp_list_v<>, class L76 = mp_list_v<>, class L77 = mp_list_v<>, class L78 = mp_list_v<>, class L79 = mp_list_v<>, + class L80 = mp_list_v<>, class L81 = mp_list_v<>, class L82 = mp_list_v<>, class L83 = mp_list_v<>, class L84 = mp_list_v<>, class L85 = mp_list_v<>, class L86 = mp_list_v<>, class L87 = mp_list_v<>, class L88 = mp_list_v<>, class L89 = mp_list_v<>, + class L90 = mp_list_v<>, class L91 = mp_list_v<>, class L92 = mp_list_v<>, class L93 = mp_list_v<>, class L94 = mp_list_v<>, class L95 = mp_list_v<>, class L96 = mp_list_v<>, class L97 = mp_list_v<>, class L98 = mp_list_v<>, class L99 = mp_list_v<>, + class LA0 = mp_list_v<>, class LA1 = mp_list_v<>, class LA2 = mp_list_v<>, class LA3 = mp_list_v<>, class LA4 = mp_list_v<>, class LA5 = mp_list_v<>, class LA6 = mp_list_v<>, class LA7 = mp_list_v<>, class LA8 = mp_list_v<>, class LA9 = mp_list_v<> + +> struct append_value_111_impl +{ + using type = typename append_value_11_impl< + + typename append_value_11_impl::type, + typename append_value_11_impl, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type, + typename append_value_11_impl, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type, + typename append_value_11_impl, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type, + typename append_value_11_impl, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type, + typename append_value_11_impl, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type, + typename append_value_11_impl, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type, + typename append_value_11_impl, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type, + typename append_value_11_impl, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type, + typename append_value_11_impl, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type, + typename append_value_11_impl, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type + + >::type; +}; + +template< + + class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A, + class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19, + class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29, + class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39, + class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49, + class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59, + class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69, + class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79, + class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89, + class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99, + class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9, + class... Lr + +> struct append_value_inf_impl +{ + using prefix = typename append_value_111_impl< + + L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A, + L10, L11, L12, L13, L14, L15, L16, L17, L18, L19, + L20, L21, L22, L23, L24, L25, L26, L27, L28, L29, + L30, L31, L32, L33, L34, L35, L36, L37, L38, L39, + L40, L41, L42, L43, L44, L45, L46, L47, L48, L49, + L50, L51, L52, L53, L54, L55, L56, L57, L58, L59, + L60, L61, L62, L63, L64, L65, L66, L67, L68, L69, + L70, L71, L72, L73, L74, L75, L76, L77, L78, L79, + L80, L81, L82, L83, L84, L85, L86, L87, L88, L89, + L90, L91, L92, L93, L94, L95, L96, L97, L98, L99, + LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9 + + >::type; + + using type = typename append_value_impl::type; +}; + +template struct append_value_impl: + mp_cond< + mp_bool<(sizeof...(L) > 111)>, mp_quote, + mp_bool<(sizeof...(L) > 11)>, mp_quote, + mp_true, mp_quote + >::template fn +{ +}; + +struct append_value_lists +{ + template using fn = typename append_value_impl::type; +}; + +#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +} // namespace detail + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template using mp_append = typename mp_if_c<(sizeof...(L) > 0 && sizeof...(L) == mp_count_if, mp_is_value_list>::value), detail::append_value_lists, detail::append_type_lists>::template fn; + +#else + +template using mp_append = detail::append_type_lists::fn; + +#endif + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_copy_if.hpp b/src/boost/mp11/detail/mp_copy_if.hpp new file mode 100644 index 00000000..4edcde09 --- /dev/null +++ b/src/boost/mp11/detail/mp_copy_if.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_copy_if +namespace detail +{ + +template class P> struct mp_copy_if_impl +{ +}; + +template class L, class... T, template class P> struct mp_copy_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list, mp_list<>>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list, mp_list<>>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template class P> using mp_copy_if = typename detail::mp_copy_if_impl::type; +template using mp_copy_if_q = mp_copy_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_count.hpp b/src/boost/mp11/detail/mp_count.hpp new file mode 100644 index 00000000..bc8aed93 --- /dev/null +++ b/src/boost/mp11/detail/mp_count.hpp @@ -0,0 +1,147 @@ +#ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED + +// Copyright 2015, 2016 Peter Dimov. +// +// 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 +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_count +namespace detail +{ + +#if !defined( BOOST_MP11_NO_CONSTEXPR ) + +constexpr std::size_t cx_plus() +{ + return 0; +} + +template constexpr std::size_t cx_plus(T1 t1, T... t) +{ + return static_cast(t1) + cx_plus(t...); +} + +template +constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t) +{ + return static_cast(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...); +} + +#endif + +template struct mp_count_impl; + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) + +template constexpr std::size_t cx_count() +{ + constexpr bool a[] = { false, std::is_same::value... }; + + std::size_t r = 0; + + for( std::size_t i = 0; i < sizeof...(T); ++i ) + { + r += a[ i+1 ]; + } + + return r; +} + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t()>; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t::value...)>; +}; + +#else + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t...>::value>; +}; + +#endif + +} // namespace detail + +template using mp_count = typename detail::mp_count_impl::type; + +// mp_count_if +namespace detail +{ + +template class P> struct mp_count_if_impl; + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +template class P, class... T> constexpr std::size_t cx_count_if() +{ + constexpr bool a[] = { false, static_cast( P::value )... }; + + std::size_t r = 0; + + for( std::size_t i = 0; i < sizeof...(T); ++i ) + { + r += a[ i+1 ]; + } + + return r; +} + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ + using type = mp_size_t()>; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ + using type = mp_size_t>::value...)>; +}; + +#else + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + + template struct _f { using type = mp_to_bool>; }; + using type = mp_size_t::type...>::value>; + +#else + + using type = mp_size_t>...>::value>; + +#endif +}; + +#endif + +} // namespace detail + +template class P> using mp_count_if = typename detail::mp_count_if_impl::type; +template using mp_count_if_q = mp_count_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_defer.hpp b/src/boost/mp11/detail/mp_defer.hpp new file mode 100644 index 00000000..9aaca99e --- /dev/null +++ b/src/boost/mp11/detail/mp_defer.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED + +// Copyright 2015-2020, 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_if, mp_if_c +namespace detail +{ + +template struct mp_if_c_impl +{ +}; + +template struct mp_if_c_impl +{ + using type = T; +}; + +template struct mp_if_c_impl +{ + using type = E; +}; + +} // namespace detail + +template using mp_if_c = typename detail::mp_if_c_impl::type; +template using mp_if = typename detail::mp_if_c_impl(C::value), T, E...>::type; + +// mp_valid + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800 + +// contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17 + +namespace detail +{ + +template using void_t = void; + +template class F, class... T> +struct mp_valid_impl: mp_false {}; + +template class F, class... T> +struct mp_valid_impl>, F, T...>: mp_true {}; + +} // namespace detail + +template class F, class... T> using mp_valid = typename detail::mp_valid_impl; + +#else + +// implementation by Bruno Dutra (by the name is_evaluable) +namespace detail +{ + +template class F, class... T> struct mp_valid_impl +{ + template class G, class = G> static mp_true check(int); + template class> static mp_false check(...); + + using type = decltype(check(0)); +}; + +} // namespace detail + +template class F, class... T> using mp_valid = typename detail::mp_valid_impl::type; + +#endif + +template using mp_valid_q = mp_valid; + +// mp_defer +namespace detail +{ + +template class F, class... T> struct mp_defer_impl +{ + using type = F; +}; + +struct mp_no_type +{ +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... T> struct mp_defer_cuda_workaround +{ + using type = mp_if, detail::mp_defer_impl, detail::mp_no_type>; +}; + +#endif + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) + +template class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type; + +#else + +template class F, class... T> using mp_defer = mp_if, detail::mp_defer_impl, detail::mp_no_type>; + +#endif + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_fold.hpp b/src/boost/mp11/detail/mp_fold.hpp new file mode 100644 index 00000000..e2c464c9 --- /dev/null +++ b/src/boost/mp11/detail/mp_fold.hpp @@ -0,0 +1,166 @@ +#ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_fold +namespace detail +{ + +template class F> struct mp_fold_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_fold is not a list +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +// + +template class F> struct mp_fold_Q1 +{ + template + using fn = F; +}; + +template class F> struct mp_fold_Q2 +{ + template + using fn = F, T2>; +}; + +template class F> struct mp_fold_Q3 +{ + template + using fn = F, T2>, T3>; +}; + +template class F> struct mp_fold_Q4 +{ + template + using fn = F, T2>, T3>, T4>; +}; + +template class F> struct mp_fold_Q5 +{ + template + using fn = F, T2>, T3>, T4>, T5>; +}; + +template class F> struct mp_fold_Q6 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>; +}; + +template class F> struct mp_fold_Q7 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>, T7>; +}; + +template class F> struct mp_fold_Q8 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>, T7>, T8>; +}; + +template class F> struct mp_fold_Q9 +{ + template + using fn = F, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>; +}; + +// + +template class L, class T1, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1> +{ +}; + +template class L, class T1, class T2, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2> +{ +}; + +template class L, class T1, class T2, class T3, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6, T7> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6, T7, T8> +{ +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class V, template class F> +struct mp_fold_impl, V, F>: mp_defer::template fn, T1, T2, T3, T4, T5, T6, T7, T8, T9> +{ +}; + +// + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template class F> +struct mp_fold_impl, V, F> +{ + using type = typename mp_fold_impl, F, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>, T10>, F>::type; +}; + +} // namespace detail + +template class F> using mp_fold = typename detail::mp_fold_impl, V, F>::type; +template using mp_fold_q = mp_fold; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_front.hpp b/src/boost/mp11/detail/mp_front.hpp new file mode 100644 index 00000000..53a73ac3 --- /dev/null +++ b/src/boost/mp11/detail/mp_front.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED + +// Copyright 2015-2023 Peter Dimov. +// +// 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 +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_front +namespace detail +{ + +template struct mp_front_impl +{ +// An error "no type named 'type'" here means that the argument to mp_front +// is either not a list, or is an empty list +}; + +template class L, class T1, class... T> struct mp_front_impl> +{ + using type = T1; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A> struct mp_front_impl> +{ + using type = mp_value; +}; + +#endif + +} // namespace detail + +template using mp_front = typename detail::mp_front_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_is_list.hpp b/src/boost/mp11/detail/mp_is_list.hpp new file mode 100644 index 00000000..25b378bd --- /dev/null +++ b/src/boost/mp11/detail/mp_is_list.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 + +namespace boost +{ +namespace mp11 +{ + +// mp_is_list +namespace detail +{ + +template struct mp_is_list_impl +{ + using type = mp_false; +}; + +template class L, class... T> struct mp_is_list_impl> +{ + using type = mp_true; +}; + +} // namespace detail + +template using mp_is_list = typename detail::mp_is_list_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_is_value_list.hpp b/src/boost/mp11/detail/mp_is_value_list.hpp new file mode 100644 index 00000000..8f94f030 --- /dev/null +++ b/src/boost/mp11/detail/mp_is_value_list.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_is_value_list +namespace detail +{ + +template struct mp_is_value_list_impl +{ + using type = mp_false; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A> struct mp_is_value_list_impl> +{ + using type = mp_true; +}; + +#endif + +} // namespace detail + +template using mp_is_value_list = typename detail::mp_is_value_list_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_list.hpp b/src/boost/mp11/detail/mp_list.hpp new file mode 100644 index 00000000..8e8d3e5e --- /dev/null +++ b/src/boost/mp11/detail/mp_list.hpp @@ -0,0 +1,24 @@ +#ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED + +// Copyright 2015, 2016 Peter Dimov. +// +// 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 + +namespace boost +{ +namespace mp11 +{ + +// mp_list +template struct mp_list +{ +}; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_list_v.hpp b/src/boost/mp11/detail/mp_list_v.hpp new file mode 100644 index 00000000..bc05238a --- /dev/null +++ b/src/boost/mp11/detail/mp_list_v.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +#include + +namespace boost +{ +namespace mp11 +{ + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +// mp_list_v +template struct mp_list_v +{ +}; + +#endif + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_map_find.hpp b/src/boost/mp11/detail/mp_map_find.hpp new file mode 100644 index 00000000..2fb70d8e --- /dev/null +++ b/src/boost/mp11/detail/mp_map_find.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED + +// Copyright 2015 Peter Dimov. +// +// 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 +#include + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +// not exactly good practice, but... +namespace std +{ + template class tuple; +} + +#endif + +namespace boost +{ +namespace mp11 +{ + +// mp_map_find +namespace detail +{ + +#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +template using mpmf_wrap = mp_identity; +template using mpmf_unwrap = typename T::type; + +#else + +template struct mpmf_tuple {}; + +template struct mpmf_wrap_impl +{ + using type = mp_identity; +}; + +template struct mpmf_wrap_impl< std::tuple > +{ + using type = mp_identity< mpmf_tuple >; +}; + +template using mpmf_wrap = typename mpmf_wrap_impl::type; + +template struct mpmf_unwrap_impl +{ + using type = typename T::type; +}; + +template struct mpmf_unwrap_impl< mp_identity< mpmf_tuple > > +{ + using type = std::tuple; +}; + +template using mpmf_unwrap = typename mpmf_unwrap_impl::type; + +#endif // #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 ) + +template struct mp_map_find_impl; + +template class M, class... T, class K> struct mp_map_find_impl, K> +{ + using U = mp_inherit...>; + + template class L, class... U> static mp_identity> f( mp_identity>* ); + static mp_identity f( ... ); + + using type = mpmf_unwrap< decltype( f( static_cast(0) ) ) >; +}; + +} // namespace detail + +template using mp_map_find = typename detail::mp_map_find_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_min_element.hpp b/src/boost/mp11/detail/mp_min_element.hpp new file mode 100644 index 00000000..55c21acd --- /dev/null +++ b/src/boost/mp11/detail/mp_min_element.hpp @@ -0,0 +1,51 @@ +#ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_min_element +namespace detail +{ + +template class P> struct select_min +{ + template using fn = mp_if, T1, T2>; +}; + +} // namespace detail + +template class P> using mp_min_element = mp_fold_q, mp_first, detail::select_min

>; +template using mp_min_element_q = mp_min_element; + +// mp_max_element +namespace detail +{ + +template class P> struct select_max +{ + template using fn = mp_if, T1, T2>; +}; + +} // namespace detail + +template class P> using mp_max_element = mp_fold_q, mp_first, detail::select_max

>; +template using mp_max_element_q = mp_max_element; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_plus.hpp b/src/boost/mp11/detail/mp_plus.hpp new file mode 100644 index 00000000..5c9417cd --- /dev/null +++ b/src/boost/mp11/detail/mp_plus.hpp @@ -0,0 +1,84 @@ +#ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED + +// Copyright 2015 Peter Dimov. +// +// 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 +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_plus +namespace detail +{ + +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, != 0 ) + +// msvc fails with parser stack overflow for large sizeof...(T) +// clang exceeds -fbracket-depth, which defaults to 256 + +template struct mp_plus_impl +{ + static const auto _v = (T::value + ... + 0); + using type = std::integral_constant::type, _v>; +}; + +#else + +template struct mp_plus_impl; + +template<> struct mp_plus_impl<> +{ + using type = std::integral_constant; +}; + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 ) + +template struct mp_plus_impl +{ + static const decltype(T1::value + mp_plus_impl::type::value) _v = T1::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +template struct mp_plus_impl +{ + static const + decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl::type::value) + _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +#else + +template struct mp_plus_impl +{ + static const auto _v = T1::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +template struct mp_plus_impl +{ + static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; +}; + +#endif + +#endif + +} // namespace detail + +template using mp_plus = typename detail::mp_plus_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_remove_if.hpp b/src/boost/mp11/detail/mp_remove_if.hpp new file mode 100644 index 00000000..9687b4a1 --- /dev/null +++ b/src/boost/mp11/detail/mp_remove_if.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_remove_if +namespace detail +{ + +template class P> struct mp_remove_if_impl +{ +}; + +template class L, class... T, template class P> struct mp_remove_if_impl, P> +{ +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) + template struct _f { using type = mp_if, mp_list<>, mp_list>; }; + using type = mp_append, typename _f::type...>; +#else + template using _f = mp_if, mp_list<>, mp_list>; + using type = mp_append, _f...>; +#endif +}; + +} // namespace detail + +template class P> using mp_remove_if = typename detail::mp_remove_if_impl::type; +template using mp_remove_if_q = mp_remove_if; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_rename.hpp b/src/boost/mp11/detail/mp_rename.hpp new file mode 100644 index 00000000..dde8f6f4 --- /dev/null +++ b/src/boost/mp11/detail/mp_rename.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED + +// Copyright 2015-2023 Peter Dimov. +// +// 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 +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_rename +namespace detail +{ + +template class B> struct mp_rename_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_rename is not a list +}; + +template class L, class... T, template class B> struct mp_rename_impl, B>: mp_defer +{ +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, template class B> struct mp_rename_impl, B>: mp_defer...> +{ +}; + +#endif + +} // namespace detail + +template class B> using mp_rename = typename detail::mp_rename_impl::type; + +// mp_apply +template class F, class L> using mp_apply = typename detail::mp_rename_impl::type; + +// mp_apply_q +template using mp_apply_q = typename detail::mp_rename_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_value.hpp b/src/boost/mp11/detail/mp_value.hpp new file mode 100644 index 00000000..d0e59825 --- /dev/null +++ b/src/boost/mp11/detail/mp_value.hpp @@ -0,0 +1,25 @@ +#ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +namespace boost +{ +namespace mp11 +{ + +template using mp_value = std::integral_constant; + +} // namespace mp11 +} // namespace boost + +#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +#endif // #ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_void.hpp b/src/boost/mp11/detail/mp_void.hpp new file mode 100644 index 00000000..a7ac7b71 --- /dev/null +++ b/src/boost/mp11/detail/mp_void.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED + +// Copyright 2015-2017 Peter Dimov. +// +// 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 + +namespace boost +{ +namespace mp11 +{ + +// mp_void +namespace detail +{ + +template struct mp_void_impl +{ + using type = void; +}; + +} // namespace detail + +template using mp_void = typename detail::mp_void_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED diff --git a/src/boost/mp11/detail/mp_with_index.hpp b/src/boost/mp11/detail/mp_with_index.hpp new file mode 100644 index 00000000..b6932f2d --- /dev/null +++ b/src/boost/mp11/detail/mp_with_index.hpp @@ -0,0 +1,385 @@ +#ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED + +// Copyright 2017 Peter Dimov. +// +// 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 +#include +#include +#include +#include + +#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) +# define BOOST_MP11_CONSTEXPR14 constexpr +#else +# define BOOST_MP11_CONSTEXPR14 +#endif + +#if defined( __GNUC__ ) || defined( __clang__ ) +# define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable(); +#elif defined( _MSC_VER ) +# define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false); +#else +# define BOOST_MP11_UNREACHABLE_DEFAULT +#endif + +namespace boost +{ +namespace mp11 +{ + +namespace detail +{ + +template struct mp_with_index_impl_ +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + if( i < N / 2 ) + { + return mp_with_index_impl_::template call( i, std::forward(f) ); + } + else + { + return mp_with_index_impl_::template call( i - N/2, std::forward(f) ); + } + } +}; + +template<> struct mp_with_index_impl_<0> +{ +}; + +template<> struct mp_with_index_impl_<1> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t /*i*/, F && f ) + { + return std::forward(f)( mp_size_t() ); + } +}; + +template<> struct mp_with_index_impl_<2> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<3> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<4> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<5> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<6> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<7> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<8> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<9> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<10> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<11> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<12> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<13> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<14> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<15> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_with_index_impl_<16> +{ + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + BOOST_MP11_UNREACHABLE_DEFAULT + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + case 15: return std::forward(f)( mp_size_t() ); + } + } +}; + +} // namespace detail + +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) +{ + assert( i < N ); + return detail::mp_with_index_impl_::template call<0>( i, std::forward(f) ); +} + +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_with_index( std::size_t i, F && f ) +{ + return mp_with_index( i, std::forward(f) ); +} + +#undef BOOST_MP11_CONSTEXPR14 +#undef BOOST_MP11_UNREACHABLE_DEFAULT + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED diff --git a/src/boost/mp11/function.hpp b/src/boost/mp11/function.hpp new file mode 100644 index 00000000..e20b4520 --- /dev/null +++ b/src/boost/mp11/function.hpp @@ -0,0 +1,222 @@ +#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED +#define BOOST_MP11_FUNCTION_HPP_INCLUDED + +// Copyright 2015-2019 Peter Dimov. +// +// 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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_void +// in detail/mp_void.hpp + +// mp_and +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 ) + +namespace detail +{ + +template struct mp_and_impl; + +} // namespace detail + +template using mp_and = mp_to_bool< typename detail::mp_and_impl::type >; + +namespace detail +{ + +template<> struct mp_and_impl<> +{ + using type = mp_true; +}; + +template struct mp_and_impl +{ + using type = T; +}; + +template struct mp_and_impl +{ + using type = mp_eval_if< mp_not, T1, mp_and, T... >; +}; + +} // namespace detail + +#else + +namespace detail +{ + +template struct mp_and_impl +{ + using type = mp_false; +}; + +template struct mp_and_impl< mp_list, mp_void...> > +{ + using type = mp_true; +}; + +} // namespace detail + +template using mp_and = typename detail::mp_and_impl>::type; + +#endif + +// mp_all +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355 +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 ) + +template using mp_all = mp_bool< mp_count_if< mp_list, mp_not >::value == 0 >; + +#else + +template using mp_all = mp_bool< mp_count< mp_list...>, mp_false >::value == 0 >; + +#endif + +// mp_or +namespace detail +{ + +template struct mp_or_impl; + +} // namespace detail + +template using mp_or = mp_to_bool< typename detail::mp_or_impl::type >; + +namespace detail +{ + +template<> struct mp_or_impl<> +{ + using type = mp_false; +}; + +template struct mp_or_impl +{ + using type = T; +}; + +template struct mp_or_impl +{ + using type = mp_eval_if< T1, T1, mp_or, T... >; +}; + +} // namespace detail + +// mp_any +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356 +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 ) + +template using mp_any = mp_bool< mp_count_if< mp_list, mp_to_bool >::value != 0 >; + +#else + +template using mp_any = mp_bool< mp_count< mp_list...>, mp_true >::value != 0 >; + +#endif + +// mp_same +namespace detail +{ + +template struct mp_same_impl; + +template<> struct mp_same_impl<> +{ + using type = mp_true; +}; + +template struct mp_same_impl +{ + using type = mp_bool< mp_count, T1>::value == sizeof...(T) >; +}; + +} // namespace detail + +template using mp_same = typename detail::mp_same_impl::type; + +// mp_similar +namespace detail +{ + +template struct mp_similar_impl; + +template<> struct mp_similar_impl<> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_false; +}; + +template class L, class... T1, class... T2> struct mp_similar_impl, L> +{ + using type = mp_true; +}; + +template class L, class... T> struct mp_similar_impl, L> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_all< typename mp_similar_impl::type, typename mp_similar_impl::type, typename mp_similar_impl::type... >; +}; + +} // namespace detail + +template using mp_similar = typename detail::mp_similar_impl::type; + +#if BOOST_MP11_GCC +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-compare" +#endif + +// mp_less +template using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>; + +#if BOOST_MP11_GCC +# pragma GCC diagnostic pop +#endif + +// mp_min +template using mp_min = mp_min_element, mp_less>; + +// mp_max +template using mp_max = mp_max_element, mp_less>; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED diff --git a/src/boost/mp11/integer_sequence.hpp b/src/boost/mp11/integer_sequence.hpp new file mode 100644 index 00000000..013991fa --- /dev/null +++ b/src/boost/mp11/integer_sequence.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED +#define BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED + +// Copyright 2015, 2017, 2019 Peter Dimov. +// +// 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 +#include + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma push_macro( "I" ) +# undef I +#endif + +#if defined(__has_builtin) +# if __has_builtin(__make_integer_seq) +# define BOOST_MP11_HAS_MAKE_INTEGER_SEQ +# endif +#endif + +namespace boost +{ +namespace mp11 +{ + +// integer_sequence +template struct integer_sequence +{ +}; + +#if defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ) + +template using make_integer_sequence = __make_integer_seq; + +#else + +// detail::make_integer_sequence_impl +namespace detail +{ + +// iseq_if_c +template struct iseq_if_c_impl; + +template struct iseq_if_c_impl +{ + using type = T; +}; + +template struct iseq_if_c_impl +{ + using type = E; +}; + +template using iseq_if_c = typename iseq_if_c_impl::type; + +// iseq_identity +template struct iseq_identity +{ + using type = T; +}; + +template struct append_integer_sequence; + +template struct append_integer_sequence, integer_sequence> +{ + using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >; +}; + +template struct make_integer_sequence_impl; + +template struct make_integer_sequence_impl_ +{ +private: + + static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); + + static T const M = N / 2; + static T const R = N % 2; + + using S1 = typename make_integer_sequence_impl::type; + using S2 = typename append_integer_sequence::type; + using S3 = typename make_integer_sequence_impl::type; + using S4 = typename append_integer_sequence::type; + +public: + + using type = S4; +}; + +template struct make_integer_sequence_impl: iseq_if_c>, iseq_if_c>, make_integer_sequence_impl_ > > +{ +}; + +} // namespace detail + +// make_integer_sequence +template using make_integer_sequence = typename detail::make_integer_sequence_impl::type; + +#endif // defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ) + +// index_sequence +template using index_sequence = integer_sequence; + +// make_index_sequence +template using make_index_sequence = make_integer_sequence; + +// index_sequence_for +template using index_sequence_for = make_integer_sequence; + +} // namespace mp11 +} // namespace boost + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma pop_macro( "I" ) +#endif + +#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED diff --git a/src/boost/mp11/integral.hpp b/src/boost/mp11/integral.hpp new file mode 100644 index 00000000..4848ac80 --- /dev/null +++ b/src/boost/mp11/integral.hpp @@ -0,0 +1,51 @@ +#ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED +#define BOOST_MP11_INTEGRAL_HPP_INCLUDED + +// Copyright 2015 Peter Dimov. +// +// 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 +#include +#include +#include + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma push_macro( "I" ) +# undef I +#endif + +namespace boost +{ +namespace mp11 +{ + +// mp_bool +template using mp_bool = std::integral_constant; + +using mp_true = mp_bool; +using mp_false = mp_bool; + +// mp_to_bool +template using mp_to_bool = mp_bool( T::value )>; + +// mp_not +template using mp_not = mp_bool< !T::value >; + +// mp_int +template using mp_int = std::integral_constant; + +// mp_size_t +template using mp_size_t = std::integral_constant; + +} // namespace mp11 +} // namespace boost + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma pop_macro( "I" ) +#endif + +#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED diff --git a/src/boost/mp11/list.hpp b/src/boost/mp11/list.hpp new file mode 100644 index 00000000..46b56053 --- /dev/null +++ b/src/boost/mp11/list.hpp @@ -0,0 +1,481 @@ +#ifndef BOOST_MP11_LIST_HPP_INCLUDED +#define BOOST_MP11_LIST_HPP_INCLUDED + +// Copyright 2015-2023 Peter Dimov. +// +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma push_macro( "I" ) +# undef I +#endif + +namespace boost +{ +namespace mp11 +{ + +// mp_list +// in detail/mp_list.hpp + +// mp_list_c +template using mp_list_c = mp_list...>; + +// mp_list_v +// in detail/mp_list_v.hpp + +// mp_is_list +// in detail/mp_is_list.hpp + +// mp_is_value_list +// in detail/mp_is_value_list.hpp + +// mp_size +namespace detail +{ + +template struct mp_size_impl +{ +// An error "no type named 'type'" here means that the argument to mp_size is not a list +}; + +template class L, class... T> struct mp_size_impl> +{ + using type = mp_size_t; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A> struct mp_size_impl> +{ + using type = mp_size_t; +}; + +#endif + +} // namespace detail + +template using mp_size = typename detail::mp_size_impl::type; + +// mp_empty +template using mp_empty = mp_bool< mp_size::value == 0 >; + +// mp_assign +namespace detail +{ + +template struct mp_assign_impl +{ +// An error "no type named 'type'" here means that the arguments to mp_assign aren't lists +}; + +template class L1, class... T, template class L2, class... U> struct mp_assign_impl, L2> +{ + using type = L1; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L1, auto... A, template class L2, class... U> struct mp_assign_impl, L2> +{ + using type = L1; +}; + +template class L1, class... T, template class L2, auto... B> struct mp_assign_impl, L2> +{ + using type = L1...>; +}; + +template class L1, auto... A, template class L2, auto... B> struct mp_assign_impl, L2> +{ + using type = L1; +}; + +#endif + +} // namespace detail + +template using mp_assign = typename detail::mp_assign_impl::type; + +// mp_clear +template using mp_clear = mp_assign>; + +// mp_front +// in detail/mp_front.hpp + +// mp_pop_front +namespace detail +{ + +template struct mp_pop_front_impl +{ +// An error "no type named 'type'" here means that the argument to mp_pop_front +// is either not a list, or is an empty list +}; + +template class L, class T1, class... T> struct mp_pop_front_impl> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A> struct mp_pop_front_impl> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_pop_front = typename detail::mp_pop_front_impl::type; + +// mp_first +template using mp_first = mp_front; + +// mp_rest +template using mp_rest = mp_pop_front; + +// mp_second +namespace detail +{ + +template struct mp_second_impl +{ +// An error "no type named 'type'" here means that the argument to mp_second +// is either not a list, or has fewer than two elements +}; + +template class L, class T1, class T2, class... T> struct mp_second_impl> +{ + using type = T2; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto... A> struct mp_second_impl> +{ + using type = mp_value; +}; + +#endif + +} // namespace detail + +template using mp_second = typename detail::mp_second_impl::type; + +// mp_third +namespace detail +{ + +template struct mp_third_impl +{ +// An error "no type named 'type'" here means that the argument to mp_third +// is either not a list, or has fewer than three elements +}; + +template class L, class T1, class T2, class T3, class... T> struct mp_third_impl> +{ + using type = T3; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto A3, auto... A> struct mp_third_impl> +{ + using type = mp_value; +}; + +#endif + +} // namespace detail + +template using mp_third = typename detail::mp_third_impl::type; + +// mp_push_front +namespace detail +{ + +template struct mp_push_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_push_front is not a list +}; + +template class L, class... U, class... T> struct mp_push_front_impl, T...> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, class... T> struct mp_push_front_impl, T...> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_push_front = typename detail::mp_push_front_impl::type; + +// mp_push_back +namespace detail +{ + +template struct mp_push_back_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_push_back is not a list +}; + +template class L, class... U, class... T> struct mp_push_back_impl, T...> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A, class... T> struct mp_push_back_impl, T...> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_push_back = typename detail::mp_push_back_impl::type; + +// mp_rename +// mp_apply +// mp_apply_q +// in detail/mp_rename.hpp + +// mp_rename_v +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +namespace detail +{ + +template class B> struct mp_rename_v_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_rename_v is not a list +}; + +template class L, class... T, template class B> struct mp_rename_v_impl, B> +{ + using type = B; +}; + +template class L, auto... A, template class B> struct mp_rename_v_impl, B> +{ + using type = B; +}; + +} // namespace detail + +template class B> using mp_rename_v = typename detail::mp_rename_v_impl::type; + +#endif + +// mp_replace_front +namespace detail +{ + +template struct mp_replace_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_front +// is either not a list, or is an empty list +}; + +template class L, class U1, class... U, class T> struct mp_replace_front_impl, T> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A, class T> struct mp_replace_front_impl, T> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_replace_front = typename detail::mp_replace_front_impl::type; + +// mp_replace_first +template using mp_replace_first = typename detail::mp_replace_front_impl::type; + +// mp_replace_second +namespace detail +{ + +template struct mp_replace_second_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_second +// is either not a list, or has fewer than two elements +}; + +template class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl, T> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto... A, class T> struct mp_replace_second_impl, T> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_replace_second = typename detail::mp_replace_second_impl::type; + +// mp_replace_third +namespace detail +{ + +template struct mp_replace_third_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_replace_third +// is either not a list, or has fewer than three elements +}; + +template class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl, T> +{ + using type = L; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto A3, auto... A, class T> struct mp_replace_third_impl, T> +{ + using type = L; +}; + +#endif + +} // namespace detail + +template using mp_replace_third = typename detail::mp_replace_third_impl::type; + +// mp_transform_front +namespace detail +{ + +template class F> struct mp_transform_front_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_front +// is either not a list, or is an empty list +}; + +template class L, class U1, class... U, template class F> struct mp_transform_front_impl, F> +{ + using type = L, U...>; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto... A, template class F> struct mp_transform_front_impl, F> +{ + using type = L>::value, A...>; +}; + +#endif + +} // namespace detail + +template class F> using mp_transform_front = typename detail::mp_transform_front_impl::type; +template using mp_transform_front_q = mp_transform_front; + +// mp_transform_first +template class F> using mp_transform_first = typename detail::mp_transform_front_impl::type; +template using mp_transform_first_q = mp_transform_first; + +// mp_transform_second +namespace detail +{ + +template class F> struct mp_transform_second_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_second +// is either not a list, or has fewer than two elements +}; + +template class L, class U1, class U2, class... U, template class F> struct mp_transform_second_impl, F> +{ + using type = L, U...>; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto... A, template class F> struct mp_transform_second_impl, F> +{ + using type = L>::value, A...>; +}; + +#endif + +} // namespace detail + +template class F> using mp_transform_second = typename detail::mp_transform_second_impl::type; +template using mp_transform_second_q = mp_transform_second; + +// mp_transform_third +namespace detail +{ + +template class F> struct mp_transform_third_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_transform_third +// is either not a list, or has fewer than three elements +}; + +template class L, class U1, class U2, class U3, class... U, template class F> struct mp_transform_third_impl, F> +{ + using type = L, U...>; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto A1, auto A2, auto A3, auto... A, template class F> struct mp_transform_third_impl, F> +{ + using type = L>::value, A...>; +}; + +#endif + +} // namespace detail + +template class F> using mp_transform_third = typename detail::mp_transform_third_impl::type; +template using mp_transform_third_q = mp_transform_third; + +} // namespace mp11 +} // namespace boost + +#if defined(_MSC_VER) || defined(__GNUC__) +# pragma pop_macro( "I" ) +#endif + +#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED diff --git a/src/boost/mp11/set.hpp b/src/boost/mp11/set.hpp new file mode 100644 index 00000000..d65e4aeb --- /dev/null +++ b/src/boost/mp11/set.hpp @@ -0,0 +1,220 @@ +#ifndef BOOST_MP11_SET_HPP_INCLUDED +#define BOOST_MP11_SET_HPP_INCLUDED + +// Copyright 2015, 2019, 2024 Peter Dimov. +// +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_set_contains +namespace detail +{ + +template struct mp_set_contains_impl +{ +}; + +template class L, class... T, class V> struct mp_set_contains_impl, V> +{ + using type = mp_to_bool, mp_inherit...> > >; +}; + +} // namespace detail + +template using mp_set_contains = typename detail::mp_set_contains_impl::type; + +// mp_set_push_back +namespace detail +{ + +template struct mp_set_push_back_impl +{ +}; + +template class L, class... U> struct mp_set_push_back_impl> +{ + using type = L; +}; + +template class L, class... U, class T1, class... T> struct mp_set_push_back_impl, T1, T...> +{ + using S = mp_if, T1>, L, L>; + using type = typename mp_set_push_back_impl::type; +}; + +} // namespace detail + +template using mp_set_push_back = typename detail::mp_set_push_back_impl::type; + +// mp_set_push_front +namespace detail +{ + +template struct mp_set_push_front_impl +{ +}; + +template class L, class... U> struct mp_set_push_front_impl> +{ + using type = L; +}; + +template class L, class... U, class T1> struct mp_set_push_front_impl, T1> +{ + using type = mp_if, T1>, L, L>; +}; + +template class L, class... U, class T1, class... T> struct mp_set_push_front_impl, T1, T...> +{ + using S = typename mp_set_push_front_impl, T...>::type; + using type = typename mp_set_push_front_impl::type; +}; + +} // namespace detail + +template using mp_set_push_front = typename detail::mp_set_push_front_impl::type; + +// mp_is_set +namespace detail +{ + +#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +struct mp_is_set_helper_start +{ + static constexpr bool value = true; + template static mp_false contains( T ); +}; + +template +struct mp_is_set_helper: Base +{ + static constexpr bool value = Base::value && !decltype( Base::contains( mp_identity{} ) )::value; + using Base::contains; + static mp_true contains( mp_identity ); +}; + +template struct mp_is_set_impl +{ + using type = mp_false; +}; + +template class L, class... T> struct mp_is_set_impl> +{ + using type = mp_bool, detail::mp_is_set_helper_start, detail::mp_is_set_helper>::value>; +}; + +#else + +template struct mp_is_set_impl +{ + using type = mp_false; +}; + +template class L, class... T> struct mp_is_set_impl> +{ + using type = mp_to_bool, mp_set_push_back, T...> > >; +}; + +#endif // !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +} // namespace detail + +template using mp_is_set = typename detail::mp_is_set_impl::type; + +// mp_set_union +namespace detail +{ + +template struct mp_set_union_impl +{ +}; + +template<> struct mp_set_union_impl<> +{ + using type = mp_list<>; +}; + +template class L, class... T> struct mp_set_union_impl> +{ + using type = L; +}; + +template class L1, class... T1, template class L2, class... T2> struct mp_set_union_impl, L2> +{ + using type = mp_set_push_back, T2...>; +}; + +template using mp_set_union_ = typename mp_set_union_impl, L...>>::type; + +template struct mp_set_union_impl: mp_defer +{ +}; + +} // namespace detail + +template using mp_set_union = typename detail::mp_set_union_impl::type; + +// mp_set_intersection +namespace detail +{ + +template struct in_all_sets +{ + template using fn = mp_all< mp_set_contains... >; +}; + +template using mp_set_intersection_ = mp_if< mp_all...>, mp_copy_if_q> >; + +template struct mp_set_intersection_impl +{ +}; + +template<> struct mp_set_intersection_impl<> +{ + using type = mp_list<>; +}; + +template struct mp_set_intersection_impl: mp_defer +{ +}; + +} // namespace detail + +template using mp_set_intersection = typename detail::mp_set_intersection_impl::type; + +// mp_set_difference +namespace detail +{ + +template struct in_any_set +{ + template using fn = mp_any< mp_set_contains... >; +}; + +} // namespace detail + +template using mp_set_difference = mp_if< mp_all...>, mp_remove_if_q> >; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED diff --git a/src/boost/mp11/tuple.hpp b/src/boost/mp11/tuple.hpp new file mode 100644 index 00000000..044801d5 --- /dev/null +++ b/src/boost/mp11/tuple.hpp @@ -0,0 +1,183 @@ +#ifndef BOOST_MP11_TUPLE_HPP_INCLUDED +#define BOOST_MP11_TUPLE_HPP_INCLUDED + +// Copyright 2015-2020 Peter Dimov. +// +// 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 +#include +#include +#include +#include +#include +#include +#include + +#if BOOST_MP11_MSVC +# pragma warning( push ) +# pragma warning( disable: 4100 ) // unreferenced formal parameter 'tp' +#endif + +namespace boost +{ +namespace mp11 +{ + +// tuple_apply +namespace detail +{ + +using std::get; + +template BOOST_MP11_CONSTEXPR auto tuple_apply_impl( F && f, Tp && tp, integer_sequence ) + -> decltype( std::forward(f)( get(std::forward(tp))... ) ) +{ + return std::forward(f)( get(std::forward(tp))... ); +} + +} // namespace detail + +template::type>::value>> +BOOST_MP11_CONSTEXPR auto tuple_apply( F && f, Tp && tp ) + -> decltype( detail::tuple_apply_impl( std::forward(f), std::forward(tp), Seq() ) ) +{ + return detail::tuple_apply_impl( std::forward(f), std::forward(tp), Seq() ); +} + +// construct_from_tuple +namespace detail +{ + +template BOOST_MP11_CONSTEXPR T construct_from_tuple_impl( Tp && tp, integer_sequence ) +{ + return T( get(std::forward(tp))... ); +} + +} // namespace detail + +template::type>::value>> +BOOST_MP11_CONSTEXPR T construct_from_tuple( Tp && tp ) +{ + return detail::construct_from_tuple_impl( std::forward(tp), Seq() ); +} + +// tuple_for_each +namespace detail +{ + +template BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence, F && f ) +{ + using A = int[sizeof...(J)]; + return (void)A{ ((void)f(get(std::forward(tp))), 0)... }, std::forward(f); +} + +template BOOST_MP11_CONSTEXPR F tuple_for_each_impl( Tp && /*tp*/, integer_sequence, F && f ) +{ + return std::forward(f); +} + +} // namespace detail + +template BOOST_MP11_CONSTEXPR F tuple_for_each( Tp && tp, F && f ) +{ + using seq = make_index_sequence::type>::value>; + return detail::tuple_for_each_impl( std::forward(tp), seq(), std::forward(f) ); +} + +// tuple_transform + +namespace detail +{ + +// std::forward_as_tuple is not constexpr in C++11 or libstdc++ 5.x +template BOOST_MP11_CONSTEXPR auto tp_forward_r( T&&... t ) -> std::tuple +{ + return std::tuple( std::forward( t )... ); +} + +template BOOST_MP11_CONSTEXPR auto tp_forward_v( T&&... t ) -> std::tuple +{ + return std::tuple( std::forward( t )... ); +} + +template +BOOST_MP11_CONSTEXPR auto tp_extract( Tp&&... tp ) + -> decltype( tp_forward_r( get( std::forward( tp ) )... ) ) +{ + return tp_forward_r( get( std::forward( tp ) )... ); +} + +#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +template +BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence, F const& f, Tp&&... tp ) + -> decltype( tp_forward_v( tuple_apply( f, tp_extract( std::forward(tp)... ) )... ) ) +{ + return tp_forward_v( tuple_apply( f, tp_extract( std::forward(tp)... ) )... ); +} + +#else + +template +BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence, F const& f, Tp1&& tp1 ) + -> decltype( tp_forward_v( f( get( std::forward(tp1) ) )... ) ) +{ + return tp_forward_v( f( get( std::forward(tp1) ) )... ); +} + +template +BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence, F const& f, Tp1&& tp1, Tp2&& tp2 ) + -> decltype( tp_forward_v( f( get( std::forward(tp1) ), get( std::forward(tp2) ) )... ) ) +{ + return tp_forward_v( f( get( std::forward(tp1) ), get( std::forward(tp2) ) )... ); +} + +template +BOOST_MP11_CONSTEXPR auto tuple_transform_impl( integer_sequence, F const& f, Tp1&& tp1, Tp2&& tp2, Tp3&& tp3 ) + -> decltype( tp_forward_v( f( get( std::forward(tp1) ), get( std::forward(tp2) ), get( std::forward(tp3) ) )... ) ) +{ + return tp_forward_v( f( get( std::forward(tp1) ), get( std::forward(tp2) ), get( std::forward(tp3) ) )... ); +} + +#endif // !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +} // namespace detail + +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 ) + +template::type>::value>> +BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp1&& tp1, Tp&&... tp ) + -> decltype( detail::tuple_transform_impl( Seq(), f, std::forward(tp1), std::forward(tp)... ) ) +{ + return detail::tuple_transform_impl( Seq(), f, std::forward(tp1), std::forward(tp)... ); +} + +#else + +template::type>::value>...>, + class E = mp_if, mp_front>, + class Seq = make_index_sequence> +BOOST_MP11_CONSTEXPR auto tuple_transform( F const& f, Tp&&... tp ) + -> decltype( detail::tuple_transform_impl( Seq(), f, std::forward(tp)... ) ) +{ + return detail::tuple_transform_impl( Seq(), f, std::forward(tp)... ); +} + +#endif // BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 ) + +} // namespace mp11 +} // namespace boost + +#if BOOST_MP11_MSVC +# pragma warning( pop ) +#endif + +#endif // #ifndef BOOST_TUPLE_HPP_INCLUDED diff --git a/src/boost/mp11/utility.hpp b/src/boost/mp11/utility.hpp new file mode 100644 index 00000000..4010aee2 --- /dev/null +++ b/src/boost/mp11/utility.hpp @@ -0,0 +1,169 @@ +#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED +#define BOOST_MP11_UTILITY_HPP_INCLUDED + +// Copyright 2015-2020 Peter Dimov. +// +// 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 +#include +#include +#include +#include +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_identity +template struct mp_identity +{ + using type = T; +}; + +// mp_identity_t +template using mp_identity_t = typename mp_identity::type; + +// mp_inherit +template struct mp_inherit: T... {}; + +// mp_if, mp_if_c +// mp_valid +// mp_defer +// moved to detail/mp_defer.hpp + +// mp_eval_if, mp_eval_if_c +namespace detail +{ + +template class F, class... U> struct mp_eval_if_c_impl; + +template class F, class... U> struct mp_eval_if_c_impl +{ + using type = T; +}; + +template class F, class... U> struct mp_eval_if_c_impl: mp_defer +{ +}; + +} // namespace detail + +template class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl::type; +template class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl(C::value), T, F, U...>::type; +template using mp_eval_if_q = typename detail::mp_eval_if_c_impl(C::value), T, Q::template fn, U...>::type; + +// mp_eval_if_not +template class F, class... U> using mp_eval_if_not = mp_eval_if, T, F, U...>; +template using mp_eval_if_not_q = mp_eval_if, T, Q::template fn, U...>; + +// mp_eval_or +template class F, class... U> using mp_eval_or = mp_eval_if_not, T, F, U...>; +template using mp_eval_or_q = mp_eval_or; + +// mp_valid_and_true +template class F, class... T> using mp_valid_and_true = mp_eval_or; +template using mp_valid_and_true_q = mp_valid_and_true; + +// mp_cond + +// so elegant; so doesn't work +// template using mp_cond = mp_eval_if; + +namespace detail +{ + +template struct mp_cond_impl; + +} // namespace detail + +template using mp_cond = typename detail::mp_cond_impl::type; + +namespace detail +{ + +template using mp_cond_ = mp_eval_if; + +template struct mp_cond_impl: mp_defer +{ +}; + +} // namespace detail + +// mp_quote +template class F> struct mp_quote +{ + // the indirection through mp_defer works around the language inability + // to expand T... into a fixed parameter list of an alias template + + template using fn = typename mp_defer::type; +}; + +// mp_quote_trait +template class F> struct mp_quote_trait +{ + template using fn = typename F::type; +}; + +// mp_invoke_q +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +namespace detail +{ + +template struct mp_invoke_q_impl: mp_defer {}; + +} // namespace detail + +template using mp_invoke_q = typename detail::mp_invoke_q_impl::type; + +#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 ) + +template using mp_invoke_q = typename mp_defer::type; + +#else + +template using mp_invoke_q = typename Q::template fn; + +#endif + +// mp_not_fn

+template class P> struct mp_not_fn +{ + template using fn = mp_not< mp_invoke_q, T...> >; +}; + +template using mp_not_fn_q = mp_not_fn; + +// mp_compose +namespace detail +{ + +template using mp_compose_helper = mp_list< mp_apply_q >; + +} // namespace detail + +#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +template class... F> struct mp_compose +{ + template using fn = mp_front< mp_fold...>, mp_list, detail::mp_compose_helper> >; +}; + +#endif + +template struct mp_compose_q +{ + template using fn = mp_front< mp_fold, mp_list, detail::mp_compose_helper> >; +}; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED diff --git a/src/boost/mp11/version.hpp b/src/boost/mp11/version.hpp new file mode 100644 index 00000000..4c00cbd3 --- /dev/null +++ b/src/boost/mp11/version.hpp @@ -0,0 +1,16 @@ +#ifndef BOOST_MP11_VERSION_HPP_INCLUDED +#define BOOST_MP11_VERSION_HPP_INCLUDED + +// Copyright 2019 Peter Dimov +// +// 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 + +// Same format as BOOST_VERSION: +// major * 100000 + minor * 100 + patch + +#define BOOST_MP11_VERSION 108800 + +#endif // #ifndef BOOST_MP11_VERSION_HPP_INCLUDED diff --git a/src/boost/predef.h b/src/boost/predef.h new file mode 100644 index 00000000..49653378 --- /dev/null +++ b/src/boost/predef.h @@ -0,0 +1,24 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#if !defined(BOOST_PREDEF_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_H +#define BOOST_PREDEF_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#endif diff --git a/src/boost/predef/architecture.h b/src/boost/predef/architecture.h new file mode 100644 index 00000000..b131a892 --- /dev/null +++ b/src/boost/predef/architecture.h @@ -0,0 +1,35 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#if !defined(BOOST_PREDEF_ARCHITECTURE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_ARCHITECTURE_H +#define BOOST_PREDEF_ARCHITECTURE_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/src/boost/predef/architecture/alpha.h b/src/boost/predef/architecture/alpha.h new file mode 100644 index 00000000..64d3dad3 --- /dev/null +++ b/src/boost/predef/architecture/alpha.h @@ -0,0 +1,65 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_ALPHA_H +#define BOOST_PREDEF_ARCHITECTURE_ALPHA_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_ALPHA` + +http://en.wikipedia.org/wiki/DEC_Alpha[DEC Alpha] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} +| `+__alpha__+` | {predef_detection} +| `+__alpha+` | {predef_detection} +| `+_M_ALPHA+` | {predef_detection} + +| `+__alpha_ev4__+` | 4.0.0 +| `+__alpha_ev5__+` | 5.0.0 +| `+__alpha_ev6__+` | 6.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__alpha__) || defined(__alpha) || \ + defined(_M_ALPHA) +# undef BOOST_ARCH_ALPHA +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev4__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev5__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev6__) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_ALPHA) +# define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_ALPHA +# define BOOST_ARCH_ALPHA_AVAILABLE +#endif + +#if BOOST_ARCH_ALPHA +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_ALPHA_NAME "DEC Alpha" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ALPHA,BOOST_ARCH_ALPHA_NAME) diff --git a/src/boost/predef/architecture/arm.h b/src/boost/predef/architecture/arm.h new file mode 100644 index 00000000..8ab20b2d --- /dev/null +++ b/src/boost/predef/architecture/arm.h @@ -0,0 +1,144 @@ +/* +Copyright Rene Rivera 2008-2019 +Copyright Franz Detro 2014 +Copyright (c) Microsoft Corporation 2014 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_ARM_H +#define BOOST_PREDEF_ARCHITECTURE_ARM_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_ARM` + +http://en.wikipedia.org/wiki/ARM_architecture[ARM] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__ARM_ARCH+` | {predef_detection} +| `+__TARGET_ARCH_ARM+` | {predef_detection} +| `+__TARGET_ARCH_THUMB+` | {predef_detection} +| `+_M_ARM+` | {predef_detection} +| `+__arm__+` | {predef_detection} +| `+__arm64+` | {predef_detection} +| `+__thumb__+` | {predef_detection} +| `+_M_ARM64+` | {predef_detection} +| `+__aarch64__+` | {predef_detection} +| `+__AARCH64EL__+` | {predef_detection} +| `+__ARM_ARCH_7__+` | {predef_detection} +| `+__ARM_ARCH_7A__+` | {predef_detection} +| `+__ARM_ARCH_7R__+` | {predef_detection} +| `+__ARM_ARCH_7M__+` | {predef_detection} +| `+__ARM_ARCH_6K__+` | {predef_detection} +| `+__ARM_ARCH_6Z__+` | {predef_detection} +| `+__ARM_ARCH_6KZ__+` | {predef_detection} +| `+__ARM_ARCH_6T2__+` | {predef_detection} +| `+__ARM_ARCH_5TE__+` | {predef_detection} +| `+__ARM_ARCH_5TEJ__+` | {predef_detection} +| `+__ARM_ARCH_4T__+` | {predef_detection} +| `+__ARM_ARCH_4__+` | {predef_detection} + +| `+__ARM_ARCH+` | V.0.0 +| `+__TARGET_ARCH_ARM+` | V.0.0 +| `+__TARGET_ARCH_THUMB+` | V.0.0 +| `+_M_ARM+` | V.0.0 +| `+__arm64+` | 8.0.0 +| `+_M_ARM64+` | 8.0.0 +| `+__aarch64__+` | 8.0.0 +| `+__AARCH64EL__+` | 8.0.0 +| `+__ARM_ARCH_7__+` | 7.0.0 +| `+__ARM_ARCH_7A__+` | 7.0.0 +| `+__ARM_ARCH_7R__+` | 7.0.0 +| `+__ARM_ARCH_7M__+` | 7.0.0 +| `+__ARM_ARCH_6K__+` | 6.0.0 +| `+__ARM_ARCH_6Z__+` | 6.0.0 +| `+__ARM_ARCH_6KZ__+` | 6.0.0 +| `+__ARM_ARCH_6T2__+` | 6.0.0 +| `+__ARM_ARCH_5TE__+` | 5.0.0 +| `+__ARM_ARCH_5TEJ__+` | 5.0.0 +| `+__ARM_ARCH_4T__+` | 4.0.0 +| `+__ARM_ARCH_4__+` | 4.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if \ + defined(__ARM_ARCH) || defined(__TARGET_ARCH_ARM) || \ + defined(__TARGET_ARCH_THUMB) || defined(_M_ARM) || \ + defined(__arm__) || defined(__arm64) || defined(__thumb__) || \ + defined(_M_ARM64) || defined(__aarch64__) || defined(__AARCH64EL__) || \ + defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || \ + defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \ + defined(__ARM_ARCH_6KZ__) || defined(__ARM_ARCH_6T2__) || \ + defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) || \ + defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_4__) +# undef BOOST_ARCH_ARM +# if !defined(BOOST_ARCH_ARM) && defined(__ARM_ARCH) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__ARM_ARCH,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_ARM,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_THUMB) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_THUMB,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && defined(_M_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(_M_ARM,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && ( \ + defined(__arm64) || defined(_M_ARM64) || defined(__aarch64__) || \ + defined(__AARCH64EL__) ) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(8,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && ( \ + defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) ) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(7,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && ( \ + defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \ + defined(__ARM_ARCH_6KZ__) || defined(__ARM_ARCH_6T2__) ) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && ( \ + defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) ) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) && ( \ + defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_4__) ) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_ARM) +# define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_ARM +# define BOOST_ARCH_ARM_AVAILABLE +#endif + +#if BOOST_ARCH_ARM +# if BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(8,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#define BOOST_ARCH_ARM_NAME "ARM" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ARM,BOOST_ARCH_ARM_NAME) diff --git a/src/boost/predef/architecture/blackfin.h b/src/boost/predef/architecture/blackfin.h new file mode 100644 index 00000000..5c94b448 --- /dev/null +++ b/src/boost/predef/architecture/blackfin.h @@ -0,0 +1,52 @@ +/* +Copyright Rene Rivera 2013-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H +#define BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_BLACKFIN` + +Blackfin Processors from Analog Devices. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__bfin__+` | {predef_detection} +| `+__BFIN__+` | {predef_detection} +| `bfin` | {predef_detection} +| `BFIN` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__bfin__) || defined(__BFIN__) || \ + defined(bfin) || defined(BFIN) +# undef BOOST_ARCH_BLACKFIN +# define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_BLACKFIN +# define BOOST_ARCH_BLACKFIN_AVAILABLE +#endif + +#if BOOST_ARCH_BLACKFIN +# undef BOOST_ARCH_WORD_BITS_16 +# define BOOST_ARCH_WORD_BITS_16 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_BLACKFIN_NAME "Blackfin" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_BLACKFIN,BOOST_ARCH_BLACKFIN_NAME) diff --git a/src/boost/predef/architecture/convex.h b/src/boost/predef/architecture/convex.h new file mode 100644 index 00000000..eb73d083 --- /dev/null +++ b/src/boost/predef/architecture/convex.h @@ -0,0 +1,71 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_CONVEX_H +#define BOOST_PREDEF_ARCHITECTURE_CONVEX_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_CONVEX` + +http://en.wikipedia.org/wiki/Convex_Computer[Convex Computer] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__convex__+` | {predef_detection} + +| `+__convex_c1__+` | 1.0.0 +| `+__convex_c2__+` | 2.0.0 +| `+__convex_c32__+` | 3.2.0 +| `+__convex_c34__+` | 3.4.0 +| `+__convex_c38__+` | 3.8.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__convex__) +# undef BOOST_ARCH_CONVEX +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c1__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c2__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c32__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c34__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,4,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c38__) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,8,0) +# endif +# if !defined(BOOST_ARCH_CONVEX) +# define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_CONVEX +# define BOOST_ARCH_CONVEX_AVAILABLE +#endif + +#if BOOST_ARCH_CONVEX +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_CONVEX_NAME "Convex Computer" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_CONVEX,BOOST_ARCH_CONVEX_NAME) diff --git a/src/boost/predef/architecture/e2k.h b/src/boost/predef/architecture/e2k.h new file mode 100644 index 00000000..92edc9e2 --- /dev/null +++ b/src/boost/predef/architecture/e2k.h @@ -0,0 +1,54 @@ +/* +Copyright Konstantin Ivlev 2021 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_E2K_H +#define BOOST_PREDEF_ARCHITECTURE_E2K_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_E2K` + +https://en.wikipedia.org/wiki/Elbrus_2000[E2K] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__e2k__+` | {predef_detection} + +| `+__e2k__+` | V.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_E2K BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__e2k__) +# undef BOOST_ARCH_E2K +# if !defined(BOOST_ARCH_E2K) && defined(__iset__) +# define BOOST_ARCH_E2K BOOST_VERSION_NUMBER(__iset__,0,0) +# endif +# if !defined(BOOST_ARCH_E2K) +# define BOOST_ARCH_E2K BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_E2K +# define BOOST_ARCH_E2K_AVAILABLE +#endif + +#if BOOST_ARCH_E2K +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_E2K_NAME "E2K" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_E2K,BOOST_ARCH_E2K_NAME) diff --git a/src/boost/predef/architecture/ia64.h b/src/boost/predef/architecture/ia64.h new file mode 100644 index 00000000..1f4b58a0 --- /dev/null +++ b/src/boost/predef/architecture/ia64.h @@ -0,0 +1,55 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_IA64_H +#define BOOST_PREDEF_ARCHITECTURE_IA64_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_IA64` + +http://en.wikipedia.org/wiki/Ia64[Intel Itanium 64] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__ia64__+` | {predef_detection} +| `+_IA64+` | {predef_detection} +| `+__IA64__+` | {predef_detection} +| `+__ia64+` | {predef_detection} +| `+_M_IA64+` | {predef_detection} +| `+__itanium__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__ia64__) || defined(_IA64) || \ + defined(__IA64__) || defined(__ia64) || \ + defined(_M_IA64) || defined(__itanium__) +# undef BOOST_ARCH_IA64 +# define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_IA64 +# define BOOST_ARCH_IA64_AVAILABLE +#endif + +#if BOOST_ARCH_IA64 +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_IA64_NAME "Intel Itanium 64" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_IA64,BOOST_ARCH_IA64_NAME) diff --git a/src/boost/predef/architecture/loongarch.h b/src/boost/predef/architecture/loongarch.h new file mode 100644 index 00000000..e3e163bd --- /dev/null +++ b/src/boost/predef/architecture/loongarch.h @@ -0,0 +1,41 @@ +/* +Copyright Zhang Na 2022 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_LOONGARCH_H +#define BOOST_PREDEF_ARCHITECTURE_LOONGARCH_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_LOONGARCH` + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__loongarch__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_LOONGARCH BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__loongarch__) +# undef BOOST_ARCH_LOONGARCH +# define BOOST_ARCH_LOONGARCH BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_LOONGARCH +# define BOOST_ARCH_LOONGARCH_AVAILABLE +#endif + +#define BOOST_ARCH_LOONGARCH_NAME "LoongArch" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_LOONGARCH,BOOST_ARCH_LOONGARCH_NAME) diff --git a/src/boost/predef/architecture/m68k.h b/src/boost/predef/architecture/m68k.h new file mode 100644 index 00000000..a5945378 --- /dev/null +++ b/src/boost/predef/architecture/m68k.h @@ -0,0 +1,88 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_M68K_H +#define BOOST_PREDEF_ARCHITECTURE_M68K_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_M68K` + +http://en.wikipedia.org/wiki/M68k[Motorola 68k] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__m68k__+` | {predef_detection} +| `M68000` | {predef_detection} + +| `+__mc68060__+` | 6.0.0 +| `mc68060` | 6.0.0 +| `+__mc68060+` | 6.0.0 +| `+__mc68040__+` | 4.0.0 +| `mc68040` | 4.0.0 +| `+__mc68040+` | 4.0.0 +| `+__mc68030__+` | 3.0.0 +| `mc68030` | 3.0.0 +| `+__mc68030+` | 3.0.0 +| `+__mc68020__+` | 2.0.0 +| `mc68020` | 2.0.0 +| `+__mc68020+` | 2.0.0 +| `+__mc68010__+` | 1.0.0 +| `mc68010` | 1.0.0 +| `+__mc68010+` | 1.0.0 +| `+__mc68000__+` | 0.0.1 +| `mc68000` | 0.0.1 +| `+__mc68000+` | 0.0.1 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__m68k__) || defined(M68000) +# undef BOOST_ARCH_M68K +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68060__) || defined(mc68060) || defined(__mc68060)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68040__) || defined(mc68040) || defined(__mc68040)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68030__) || defined(mc68030) || defined(__mc68030)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68020__) || defined(mc68020) || defined(__mc68020)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68010__) || defined(mc68010) || defined(__mc68010)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_M68K) && (defined(__mc68000__) || defined(mc68000) || defined(__mc68000)) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if !defined(BOOST_ARCH_M68K) +# define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_M68K +# define BOOST_ARCH_M68K_AVAILABLE +#endif + +#if BOOST_ARCH_M68K +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_M68K_NAME "Motorola 68k" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_M68K,BOOST_ARCH_M68K_NAME) diff --git a/src/boost/predef/architecture/mips.h b/src/boost/predef/architecture/mips.h new file mode 100644 index 00000000..e35d23ab --- /dev/null +++ b/src/boost/predef/architecture/mips.h @@ -0,0 +1,84 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_MIPS_H +#define BOOST_PREDEF_ARCHITECTURE_MIPS_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_MIPS` + +http://en.wikipedia.org/wiki/MIPS_architecture[MIPS] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__mips__+` | {predef_detection} +| `+__mips+` | {predef_detection} +| `+__MIPS__+` | {predef_detection} + +| `+__mips+` | V.0.0 +| `+_MIPS_ISA_MIPS1+` | 1.0.0 +| `+_R3000+` | 1.0.0 +| `+_MIPS_ISA_MIPS2+` | 2.0.0 +| `+__MIPS_ISA2__+` | 2.0.0 +| `+_R4000+` | 2.0.0 +| `+_MIPS_ISA_MIPS3+` | 3.0.0 +| `+__MIPS_ISA3__+` | 3.0.0 +| `+_MIPS_ISA_MIPS4+` | 4.0.0 +| `+__MIPS_ISA4__+` | 4.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__mips__) || defined(__mips) || \ + defined(__MIPS__) +# undef BOOST_ARCH_MIPS +# if !defined(BOOST_ARCH_MIPS) && (defined(__mips)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(__mips,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS1) || defined(_R3000)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS2) || defined(__MIPS_ISA2__) || defined(_R4000)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS3) || defined(__MIPS_ISA3__)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS4) || defined(__MIPS_ISA4__)) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_MIPS) +# define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_MIPS +# define BOOST_ARCH_MIPS_AVAILABLE +#endif + +#if BOOST_ARCH_MIPS +# if BOOST_ARCH_MIPS >= BOOST_VERSION_NUMBER(3,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#define BOOST_ARCH_MIPS_NAME "MIPS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_MIPS,BOOST_ARCH_MIPS_NAME) diff --git a/src/boost/predef/architecture/parisc.h b/src/boost/predef/architecture/parisc.h new file mode 100644 index 00000000..b93bfd9e --- /dev/null +++ b/src/boost/predef/architecture/parisc.h @@ -0,0 +1,70 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PARISC_H +#define BOOST_PREDEF_ARCHITECTURE_PARISC_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_PARISC` + +http://en.wikipedia.org/wiki/PA-RISC_family[HP/PA RISC] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__hppa__+` | {predef_detection} +| `+__hppa+` | {predef_detection} +| `+__HPPA__+` | {predef_detection} + +| `+_PA_RISC1_0+` | 1.0.0 +| `+_PA_RISC1_1+` | 1.1.0 +| `+__HPPA11__+` | 1.1.0 +| `+__PA7100__+` | 1.1.0 +| `+_PA_RISC2_0+` | 2.0.0 +| `+__RISC2_0__+` | 2.0.0 +| `+__HPPA20__+` | 2.0.0 +| `+__PA8000__+` | 2.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__hppa__) || defined(__hppa) || defined(__HPPA__) +# undef BOOST_ARCH_PARISC +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_0)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_1) || defined(__HPPA11__) || defined(__PA7100__)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,1,0) +# endif +# if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC2_0) || defined(__RISC2_0__) || defined(__HPPA20__) || defined(__PA8000__)) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_PARISC) +# define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_PARISC +# define BOOST_ARCH_PARISC_AVAILABLE +#endif + +#if BOOST_ARCH_PARISC +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_PARISC_NAME "HP/PA RISC" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PARISC,BOOST_ARCH_PARISC_NAME) diff --git a/src/boost/predef/architecture/ppc.h b/src/boost/predef/architecture/ppc.h new file mode 100644 index 00000000..73d99f33 --- /dev/null +++ b/src/boost/predef/architecture/ppc.h @@ -0,0 +1,124 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PPC_H +#define BOOST_PREDEF_ARCHITECTURE_PPC_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_PPC` + +http://en.wikipedia.org/wiki/PowerPC[PowerPC] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__powerpc+` | {predef_detection} +| `+__powerpc__+` | {predef_detection} +| `+__powerpc64__+` | {predef_detection} +| `+__POWERPC__+` | {predef_detection} +| `+__ppc__+` | {predef_detection} +| `+__ppc64__+` | {predef_detection} +| `+__PPC__+` | {predef_detection} +| `+__PPC64__+` | {predef_detection} +| `+_M_PPC+` | {predef_detection} +| `+_ARCH_PPC+` | {predef_detection} +| `+_ARCH_PPC64+` | {predef_detection} +| `+__PPCGECKO__+` | {predef_detection} +| `+__PPCBROADWAY__+` | {predef_detection} +| `+_XENON+` | {predef_detection} +| `+__ppc+` | {predef_detection} + +| `+__ppc601__+` | 6.1.0 +| `+_ARCH_601+` | 6.1.0 +| `+__ppc603__+` | 6.3.0 +| `+_ARCH_603+` | 6.3.0 +| `+__ppc604__+` | 6.4.0 +| `+__ppc604__+` | 6.4.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__) || \ + defined(__POWERPC__) || defined(__ppc__) || defined(__ppc64__) || \ + defined(__PPC__) || defined(__PPC64__) || \ + defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \ + defined(_XENON) || \ + defined(__ppc) +# undef BOOST_ARCH_PPC +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc601__) || defined(_ARCH_601)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,1,0) +# endif +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc603__) || defined(_ARCH_603)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,3,0) +# endif +# if !defined (BOOST_ARCH_PPC) && (defined(__ppc604__) || defined(__ppc604__)) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,4,0) +# endif +# if !defined (BOOST_ARCH_PPC) +# define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_PPC +# define BOOST_ARCH_PPC_AVAILABLE +#endif + +#define BOOST_ARCH_PPC_NAME "PowerPC" + + +/* tag::reference[] += `BOOST_ARCH_PPC_64` + +http://en.wikipedia.org/wiki/PowerPC[PowerPC] 64 bit architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__powerpc64__+` | {predef_detection} +| `+__ppc64__+` | {predef_detection} +| `+__PPC64__+` | {predef_detection} +| `+_ARCH_PPC64+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_PPC_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \ + defined(_ARCH_PPC64) +# undef BOOST_ARCH_PPC_64 +# define BOOST_ARCH_PPC_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_PPC_64 +# define BOOST_ARCH_PPC_64_AVAILABLE +#endif + +#define BOOST_ARCH_PPC_64_NAME "PowerPC64" + + +#if BOOST_ARCH_PPC_64 +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC,BOOST_ARCH_PPC_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC_64,BOOST_ARCH_PPC_64_NAME) diff --git a/src/boost/predef/architecture/ptx.h b/src/boost/predef/architecture/ptx.h new file mode 100644 index 00000000..77372136 --- /dev/null +++ b/src/boost/predef/architecture/ptx.h @@ -0,0 +1,50 @@ +/* +Copyright Benjamin Worpitz 2018 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PTX_H +#define BOOST_PREDEF_ARCHITECTURE_PTX_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_PTX` + +https://en.wikipedia.org/wiki/Parallel_Thread_Execution[PTX] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__CUDA_ARCH__+` | {predef_detection} + +| `+__CUDA_ARCH__+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_PTX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__CUDA_ARCH__) +# undef BOOST_ARCH_PTX +# define BOOST_ARCH_PTX BOOST_PREDEF_MAKE_10_VR0(__CUDA_ARCH__) +#endif + +#if BOOST_ARCH_PTX +# define BOOST_ARCH_PTX_AVAILABLE +#endif + +#if BOOST_ARCH_PTX +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_PTX_NAME "PTX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PTX,BOOST_ARCH_PTX_NAME) diff --git a/src/boost/predef/architecture/pyramid.h b/src/boost/predef/architecture/pyramid.h new file mode 100644 index 00000000..40c5359b --- /dev/null +++ b/src/boost/predef/architecture/pyramid.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_PYRAMID_H +#define BOOST_PREDEF_ARCHITECTURE_PYRAMID_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_PYRAMID` + +Pyramid 9810 architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `pyr` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(pyr) +# undef BOOST_ARCH_PYRAMID +# define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_PYRAMID +# define BOOST_ARCH_PYRAMID_AVAILABLE +#endif + +#if BOOST_ARCH_PYRAMID +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_PYRAMID_NAME "Pyramid 9810" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PYRAMID,BOOST_ARCH_PYRAMID_NAME) diff --git a/src/boost/predef/architecture/riscv.h b/src/boost/predef/architecture/riscv.h new file mode 100644 index 00000000..8b819d77 --- /dev/null +++ b/src/boost/predef/architecture/riscv.h @@ -0,0 +1,48 @@ +/* +Copyright Andreas Schwab 2019 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_RISCV_H +#define BOOST_PREDEF_ARCHITECTURE_RISCV_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_RISCV` + +http://en.wikipedia.org/wiki/RISC-V[RISC-V] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__riscv+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_RISCV BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__riscv) +# undef BOOST_ARCH_RISCV +# define BOOST_ARCH_RISCV BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_RISCV +# define BOOST_ARCH_RISCV_AVAILABLE +#endif + +#if BOOST_ARCH_RISCV +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_RISCV_NAME "RISC-V" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RISCV,BOOST_ARCH_RISCV_NAME) diff --git a/src/boost/predef/architecture/rs6k.h b/src/boost/predef/architecture/rs6k.h new file mode 100644 index 00000000..1c6d987d --- /dev/null +++ b/src/boost/predef/architecture/rs6k.h @@ -0,0 +1,67 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_RS6K_H +#define BOOST_PREDEF_ARCHITECTURE_RS6K_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_RS6000` + +http://en.wikipedia.org/wiki/RS/6000[RS/6000] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__THW_RS6000+` | {predef_detection} +| `+_IBMR2+` | {predef_detection} +| `+_POWER+` | {predef_detection} +| `+_ARCH_PWR+` | {predef_detection} +| `+_ARCH_PWR2+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__THW_RS6000) || defined(_IBMR2) || \ + defined(_POWER) || defined(_ARCH_PWR) || \ + defined(_ARCH_PWR2) +# undef BOOST_ARCH_RS6000 +# define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_RS6000 +# define BOOST_ARCH_RS6000_AVAILABLE +#endif + +#if BOOST_ARCH_RS6000 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_RS6000_NAME "RS/6000" + +#define BOOST_ARCH_PWR BOOST_ARCH_RS6000 + +#if BOOST_ARCH_PWR +# define BOOST_ARCH_PWR_AVAILABLE +#endif + +#if BOOST_ARCH_PWR +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_PWR_NAME BOOST_ARCH_RS6000_NAME + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RS6000,BOOST_ARCH_RS6000_NAME) diff --git a/src/boost/predef/architecture/sparc.h b/src/boost/predef/architecture/sparc.h new file mode 100644 index 00000000..d01605e8 --- /dev/null +++ b/src/boost/predef/architecture/sparc.h @@ -0,0 +1,67 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SPARC_H +#define BOOST_PREDEF_ARCHITECTURE_SPARC_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_SPARC` + +http://en.wikipedia.org/wiki/SPARC[SPARC] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__sparc__+` | {predef_detection} +| `+__sparc+` | {predef_detection} + +| `+__sparcv9+` | 9.0.0 +| `+__sparc_v9__+` | 9.0.0 +| `+__sparcv8+` | 8.0.0 +| `+__sparc_v8__+` | 8.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sparc__) || defined(__sparc) +# undef BOOST_ARCH_SPARC +# if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv9) || defined(__sparc_v9__)) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(9,0,0) +# endif +# if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv8) || defined(__sparc_v8__)) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(8,0,0) +# endif +# if !defined(BOOST_ARCH_SPARC) +# define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_SPARC +# define BOOST_ARCH_SPARC_AVAILABLE +#endif + +#if BOOST_ARCH_SPARC +# if BOOST_ARCH_SPARC >= BOOST_VERSION_NUMBER(9,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#define BOOST_ARCH_SPARC_NAME "SPARC" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SPARC,BOOST_ARCH_SPARC_NAME) diff --git a/src/boost/predef/architecture/superh.h b/src/boost/predef/architecture/superh.h new file mode 100644 index 00000000..f72dc8b1 --- /dev/null +++ b/src/boost/predef/architecture/superh.h @@ -0,0 +1,81 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SUPERH_H +#define BOOST_PREDEF_ARCHITECTURE_SUPERH_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_SH` + +http://en.wikipedia.org/wiki/SuperH[SuperH] architecture: +If available versions [1-5] are specifically detected. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__sh__+` | {predef_detection} + +| `+__SH5__+` | 5.0.0 +| `+__SH4__+` | 4.0.0 +| `+__sh3__+` | 3.0.0 +| `+__SH3__+` | 3.0.0 +| `+__sh2__+` | 2.0.0 +| `+__sh1__+` | 1.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_SH BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sh__) +# undef BOOST_ARCH_SH +# if !defined(BOOST_ARCH_SH) && (defined(__SH5__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__SH4__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh3__) || defined(__SH3__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh2__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_ARCH_SH) && (defined(__sh1__)) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_ARCH_SH) +# define BOOST_ARCH_SH BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_SH +# define BOOST_ARCH_SH_AVAILABLE +#endif + +#if BOOST_ARCH_SH +# if BOOST_ARCH_SH >= BOOST_VERSION_NUMBER(5,0,0) +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +# elif BOOST_ARCH_SH >= BOOST_VERSION_NUMBER(3,0,0) +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_ARCH_WORD_BITS_16 +# define BOOST_ARCH_WORD_BITS_16 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#define BOOST_ARCH_SH_NAME "SuperH" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SH,BOOST_ARCH_SH_NAME) diff --git a/src/boost/predef/architecture/sys370.h b/src/boost/predef/architecture/sys370.h new file mode 100644 index 00000000..5500d253 --- /dev/null +++ b/src/boost/predef/architecture/sys370.h @@ -0,0 +1,49 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SYS370_H +#define BOOST_PREDEF_ARCHITECTURE_SYS370_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_SYS370` + +http://en.wikipedia.org/wiki/System/370[System/370] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__370__+` | {predef_detection} +| `+__THW_370__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__370__) || defined(__THW_370__) +# undef BOOST_ARCH_SYS370 +# define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_SYS370 +# define BOOST_ARCH_SYS370_AVAILABLE +#endif + +#if BOOST_ARCH_SYS370 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_SYS370_NAME "System/370" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS370,BOOST_ARCH_SYS370_NAME) diff --git a/src/boost/predef/architecture/sys390.h b/src/boost/predef/architecture/sys390.h new file mode 100644 index 00000000..9aba5685 --- /dev/null +++ b/src/boost/predef/architecture/sys390.h @@ -0,0 +1,49 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_SYS390_H +#define BOOST_PREDEF_ARCHITECTURE_SYS390_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_SYS390` + +http://en.wikipedia.org/wiki/System/390[System/390] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__s390__+` | {predef_detection} +| `+__s390x__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__s390__) || defined(__s390x__) +# undef BOOST_ARCH_SYS390 +# define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_SYS390 +# define BOOST_ARCH_SYS390_AVAILABLE +#endif + +#if BOOST_ARCH_SYS390 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_SYS390_NAME "System/390" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS390,BOOST_ARCH_SYS390_NAME) diff --git a/src/boost/predef/architecture/x86.h b/src/boost/predef/architecture/x86.h new file mode 100644 index 00000000..9827ef3a --- /dev/null +++ b/src/boost/predef/architecture/x86.h @@ -0,0 +1,38 @@ +/* +Copyright Rene Rivera 2008-2015 +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 +#include + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_H +#define BOOST_PREDEF_ARCHITECTURE_X86_H + +/* tag::reference[] += `BOOST_ARCH_X86` + +http://en.wikipedia.org/wiki/X86[Intel x86] architecture. This is +a category to indicate that either `BOOST_ARCH_X86_32` or +`BOOST_ARCH_X86_64` is detected. +*/ // end::reference[] + +#define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_ARCH_X86_32 || BOOST_ARCH_X86_64 +# undef BOOST_ARCH_X86 +# define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_X86 +# define BOOST_ARCH_X86_AVAILABLE +#endif + +#define BOOST_ARCH_X86_NAME "Intel x86" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86,BOOST_ARCH_X86_NAME) diff --git a/src/boost/predef/architecture/x86/32.h b/src/boost/predef/architecture/x86/32.h new file mode 100644 index 00000000..b20fed9d --- /dev/null +++ b/src/boost/predef/architecture/x86/32.h @@ -0,0 +1,93 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_32_H +#define BOOST_PREDEF_ARCHITECTURE_X86_32_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_X86_32` + +http://en.wikipedia.org/wiki/X86[Intel x86] architecture: +If available versions [3-6] are specifically detected. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `i386` | {predef_detection} +| `+__i386__+` | {predef_detection} +| `+__i486__+` | {predef_detection} +| `+__i586__+` | {predef_detection} +| `+__i686__+` | {predef_detection} +| `+__i386+` | {predef_detection} +| `+_M_IX86+` | {predef_detection} +| `+_X86_+` | {predef_detection} +| `+__THW_INTEL__+` | {predef_detection} +| `+__I86__+` | {predef_detection} +| `+__INTEL__+` | {predef_detection} + +| `+__I86__+` | V.0.0 +| `+_M_IX86+` | V.0.0 +| `+__i686__+` | 6.0.0 +| `+__i586__+` | 5.0.0 +| `+__i486__+` | 4.0.0 +| `+__i386__+` | 3.0.0 +|=== +*/ // end::reference[] + +#define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(i386) || defined(__i386__) || \ + defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(__i386) || \ + defined(_M_IX86) || defined(_X86_) || \ + defined(__THW_INTEL__) || defined(__I86__) || \ + defined(__INTEL__) +# undef BOOST_ARCH_X86_32 +# if !defined(BOOST_ARCH_X86_32) && defined(__I86__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(__I86__,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(_M_IX86) +# define BOOST_ARCH_X86_32 BOOST_PREDEF_MAKE_10_VV00(_M_IX86) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i686__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i586__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i486__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) && defined(__i386__) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_ARCH_X86_32) +# define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_ARCH_X86_32 +# define BOOST_ARCH_X86_32_AVAILABLE +#endif + +#if BOOST_ARCH_X86_32 +# undef BOOST_ARCH_WORD_BITS_32 +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_X86_32_NAME "Intel x86-32" + +#include + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_32,BOOST_ARCH_X86_32_NAME) diff --git a/src/boost/predef/architecture/x86/64.h b/src/boost/predef/architecture/x86/64.h new file mode 100644 index 00000000..6f59722b --- /dev/null +++ b/src/boost/predef/architecture/x86/64.h @@ -0,0 +1,56 @@ +/* +Copyright Rene Rivera 2008-2021 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_X86_64_H +#define BOOST_PREDEF_ARCHITECTURE_X86_64_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_X86_64` + +https://en.wikipedia.org/wiki/X86-64[X86-64] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__x86_64+` | {predef_detection} +| `+__x86_64__+` | {predef_detection} +| `+__amd64__+` | {predef_detection} +| `+__amd64+` | {predef_detection} +| `+_M_X64+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__x86_64) || defined(__x86_64__) || \ + defined(__amd64__) || defined(__amd64) || \ + defined(_M_X64) +# undef BOOST_ARCH_X86_64 +# define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_X86_64 +# define BOOST_ARCH_X86_64_AVAILABLE +#endif + +#if BOOST_ARCH_X86_64 +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_X86_64_NAME "Intel x86-64" + +#include + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_64,BOOST_ARCH_X86_64_NAME) diff --git a/src/boost/predef/architecture/z.h b/src/boost/predef/architecture/z.h new file mode 100644 index 00000000..a5f79796 --- /dev/null +++ b/src/boost/predef/architecture/z.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ARCHITECTURE_Z_H +#define BOOST_PREDEF_ARCHITECTURE_Z_H + +#include +#include + +/* tag::reference[] += `BOOST_ARCH_Z` + +http://en.wikipedia.org/wiki/Z/Architecture[z/Architecture] architecture. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SYSC_ZARCH__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_ARCH_Z BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SYSC_ZARCH__) +# undef BOOST_ARCH_Z +# define BOOST_ARCH_Z BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_ARCH_Z +# define BOOST_ARCH_Z_AVAILABLE +#endif + +#if BOOST_ARCH_Z +# undef BOOST_ARCH_WORD_BITS_64 +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#define BOOST_ARCH_Z_NAME "z/Architecture" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_Z,BOOST_ARCH_Z_NAME) diff --git a/src/boost/predef/compiler.h b/src/boost/predef/compiler.h new file mode 100644 index 00000000..de1b4ab5 --- /dev/null +++ b/src/boost/predef/compiler.h @@ -0,0 +1,44 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#if !defined(BOOST_PREDEF_COMPILER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_COMPILER_H +#define BOOST_PREDEF_COMPILER_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/src/boost/predef/compiler/borland.h b/src/boost/predef/compiler/borland.h new file mode 100644 index 00000000..64daf909 --- /dev/null +++ b/src/boost/predef/compiler/borland.h @@ -0,0 +1,64 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_BORLAND_H +#define BOOST_PREDEF_COMPILER_BORLAND_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_BORLAND` + +http://en.wikipedia.org/wiki/C_plus_plus_builder[Borland {CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__BORLANDC__+` | {predef_detection} +| `+__CODEGEARC__+` | {predef_detection} + +| `+__BORLANDC__+` | V.R.P +| `+__CODEGEARC__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_BORLAND BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__BORLANDC__) || defined(__CODEGEARC__) +# if !defined(BOOST_COMP_BORLAND_DETECTION) && (defined(__CODEGEARC__)) +# define BOOST_COMP_BORLAND_DETECTION BOOST_PREDEF_MAKE_0X_VVRP(__CODEGEARC__) +# endif +# if !defined(BOOST_COMP_BORLAND_DETECTION) +# define BOOST_COMP_BORLAND_DETECTION BOOST_PREDEF_MAKE_0X_VVRP(__BORLANDC__) +# endif +#endif + +#ifdef BOOST_COMP_BORLAND_DETECTION +# define BOOST_COMP_BORLAND_AVAILABLE +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_BORLAND_EMULATED BOOST_COMP_BORLAND_DETECTION +# else +# undef BOOST_COMP_BORLAND +# define BOOST_COMP_BORLAND BOOST_COMP_BORLAND_DETECTION +# endif +# include +#endif + +#define BOOST_COMP_BORLAND_NAME "Borland C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND,BOOST_COMP_BORLAND_NAME) + +#ifdef BOOST_COMP_BORLAND_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND_EMULATED,BOOST_COMP_BORLAND_NAME) +#endif diff --git a/src/boost/predef/compiler/clang.h b/src/boost/predef/compiler/clang.h new file mode 100644 index 00000000..5e62da25 --- /dev/null +++ b/src/boost/predef/compiler/clang.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_CLANG_H +#define BOOST_PREDEF_COMPILER_CLANG_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_CLANG` + +http://en.wikipedia.org/wiki/Clang[Clang] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__clang__+` | {predef_detection} + +| `+__clang_major__+`, `+__clang_minor__+`, `+__clang_patchlevel__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_CLANG BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__clang__) +# define BOOST_COMP_CLANG_DETECTION BOOST_VERSION_NUMBER(__clang_major__,__clang_minor__,__clang_patchlevel__) +#endif + +#ifdef BOOST_COMP_CLANG_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_CLANG_EMULATED BOOST_COMP_CLANG_DETECTION +# else +# undef BOOST_COMP_CLANG +# define BOOST_COMP_CLANG BOOST_COMP_CLANG_DETECTION +# endif +# define BOOST_COMP_CLANG_AVAILABLE +# include +#endif + +#define BOOST_COMP_CLANG_NAME "Clang" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG,BOOST_COMP_CLANG_NAME) + +#ifdef BOOST_COMP_CLANG_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG_EMULATED,BOOST_COMP_CLANG_NAME) +#endif diff --git a/src/boost/predef/compiler/comeau.h b/src/boost/predef/compiler/comeau.h new file mode 100644 index 00000000..749694d0 --- /dev/null +++ b/src/boost/predef/compiler/comeau.h @@ -0,0 +1,62 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_COMEAU_H +#define BOOST_PREDEF_COMPILER_COMEAU_H + +#include +#include + +#define BOOST_COMP_COMO BOOST_VERSION_NUMBER_NOT_AVAILABLE + +/* tag::reference[] += `BOOST_COMP_COMO` + +http://en.wikipedia.org/wiki/Comeau_C/C%2B%2B[Comeau {CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__COMO__+` | {predef_detection} + +| `+__COMO_VERSION__+` | V.R.P +|=== +*/ // end::reference[] + +#if defined(__COMO__) +# if !defined(BOOST_COMP_COMO_DETECTION) && defined(__COMO_VERSION__) +# define BOOST_COMP_COMO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__COMO_VERSION__) +# endif +# if !defined(BOOST_COMP_COMO_DETECTION) +# define BOOST_COMP_COMO_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_COMO_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_COMO_EMULATED BOOST_COMP_COMO_DETECTION +# else +# undef BOOST_COMP_COMO +# define BOOST_COMP_COMO BOOST_COMP_COMO_DETECTION +# endif +# define BOOST_COMP_COMO_AVAILABLE +# include +#endif + +#define BOOST_COMP_COMO_NAME "Comeau C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO,BOOST_COMP_COMO_NAME) + +#ifdef BOOST_COMP_COMO_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO_EMULATED,BOOST_COMP_COMO_NAME) +#endif diff --git a/src/boost/predef/compiler/compaq.h b/src/boost/predef/compiler/compaq.h new file mode 100644 index 00000000..a2a403ff --- /dev/null +++ b/src/boost/predef/compiler/compaq.h @@ -0,0 +1,67 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_COMPAQ_H +#define BOOST_PREDEF_COMPILER_COMPAQ_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_DEC` + +http://www.openvms.compaq.com/openvms/brochures/deccplus/[Compaq C/{CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__DECCXX+` | {predef_detection} +| `+__DECC+` | {predef_detection} + +| `+__DECCXX_VER+` | V.R.P +| `+__DECC_VER+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_DEC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__DECC) || defined(__DECCXX) +# if !defined(BOOST_COMP_DEC_DETECTION) && defined(__DECCXX_VER) +# define BOOST_COMP_DEC_DETECTION BOOST_PREDEF_MAKE_10_VVRR0PP00(__DECCXX_VER) +# endif +# if !defined(BOOST_COMP_DEC_DETECTION) && defined(__DECC_VER) +# define BOOST_COMP_DEC_DETECTION BOOST_PREDEF_MAKE_10_VVRR0PP00(__DECC_VER) +# endif +# if !defined(BOOST_COMP_DEC_DETECTION) +# define BOOST_COMP_DEC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_DEC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_DEC_EMULATED BOOST_COMP_DEC_DETECTION +# else +# undef BOOST_COMP_DEC +# define BOOST_COMP_DEC BOOST_COMP_DEC_DETECTION +# endif +# define BOOST_COMP_DEC_AVAILABLE +# include +#endif + +#define BOOST_COMP_DEC_NAME "Compaq C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC,BOOST_COMP_DEC_NAME) + +#ifdef BOOST_COMP_DEC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC_EMULATED,BOOST_COMP_DEC_NAME) +#endif diff --git a/src/boost/predef/compiler/diab.h b/src/boost/predef/compiler/diab.h new file mode 100644 index 00000000..9be1d1ae --- /dev/null +++ b/src/boost/predef/compiler/diab.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_DIAB_H +#define BOOST_PREDEF_COMPILER_DIAB_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_DIAB` + +http://www.windriver.com/products/development_suite/wind_river_compiler/[Diab C/{CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__DCC__+` | {predef_detection} + +| `+__VERSION_NUMBER__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_DIAB BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__DCC__) +# define BOOST_COMP_DIAB_DETECTION BOOST_PREDEF_MAKE_10_VRPP(__VERSION_NUMBER__) +#endif + +#ifdef BOOST_COMP_DIAB_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_DIAB_EMULATED BOOST_COMP_DIAB_DETECTION +# else +# undef BOOST_COMP_DIAB +# define BOOST_COMP_DIAB BOOST_COMP_DIAB_DETECTION +# endif +# define BOOST_COMP_DIAB_AVAILABLE +# include +#endif + +#define BOOST_COMP_DIAB_NAME "Diab C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB,BOOST_COMP_DIAB_NAME) + +#ifdef BOOST_COMP_DIAB_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB_EMULATED,BOOST_COMP_DIAB_NAME) +#endif diff --git a/src/boost/predef/compiler/digitalmars.h b/src/boost/predef/compiler/digitalmars.h new file mode 100644 index 00000000..3b2d53f7 --- /dev/null +++ b/src/boost/predef/compiler/digitalmars.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_DIGITALMARS_H +#define BOOST_PREDEF_COMPILER_DIGITALMARS_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_DMC` + +http://en.wikipedia.org/wiki/Digital_Mars[Digital Mars] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__DMC__+` | {predef_detection} + +| `+__DMC__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_DMC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__DMC__) +# define BOOST_COMP_DMC_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__DMC__) +#endif + +#ifdef BOOST_COMP_DMC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_DMC_EMULATED BOOST_COMP_DMC_DETECTION +# else +# undef BOOST_COMP_DMC +# define BOOST_COMP_DMC BOOST_COMP_DMC_DETECTION +# endif +# define BOOST_COMP_DMC_AVAILABLE +# include +#endif + +#define BOOST_COMP_DMC_NAME "Digital Mars" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC,BOOST_COMP_DMC_NAME) + +#ifdef BOOST_COMP_DMC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC_EMULATED,BOOST_COMP_DMC_NAME) +#endif diff --git a/src/boost/predef/compiler/dignus.h b/src/boost/predef/compiler/dignus.h new file mode 100644 index 00000000..8177cc76 --- /dev/null +++ b/src/boost/predef/compiler/dignus.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_DIGNUS_H +#define BOOST_PREDEF_COMPILER_DIGNUS_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_SYSC` + +http://www.dignus.com/dcxx/[Dignus Systems/{CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SYSC__+` | {predef_detection} + +| `+__SYSC_VER__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_SYSC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SYSC__) +# define BOOST_COMP_SYSC_DETECTION BOOST_PREDEF_MAKE_10_VRRPP(__SYSC_VER__) +#endif + +#ifdef BOOST_COMP_SYSC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_SYSC_EMULATED BOOST_COMP_SYSC_DETECTION +# else +# undef BOOST_COMP_SYSC +# define BOOST_COMP_SYSC BOOST_COMP_SYSC_DETECTION +# endif +# define BOOST_COMP_SYSC_AVAILABLE +# include +#endif + +#define BOOST_COMP_SYSC_NAME "Dignus Systems/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC,BOOST_COMP_SYSC_NAME) + +#ifdef BOOST_COMP_SYSC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC_EMULATED,BOOST_COMP_SYSC_NAME) +#endif diff --git a/src/boost/predef/compiler/edg.h b/src/boost/predef/compiler/edg.h new file mode 100644 index 00000000..6e0f97a2 --- /dev/null +++ b/src/boost/predef/compiler/edg.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_EDG_H +#define BOOST_PREDEF_COMPILER_EDG_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_EDG` + +http://en.wikipedia.org/wiki/Edison_Design_Group[EDG {CPP} Frontend] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__EDG__+` | {predef_detection} + +| `+__EDG_VERSION__+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_COMP_EDG BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__EDG__) +# define BOOST_COMP_EDG_DETECTION BOOST_PREDEF_MAKE_10_VRR(__EDG_VERSION__) +#endif + +#ifdef BOOST_COMP_EDG_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_EDG_EMULATED BOOST_COMP_EDG_DETECTION +# else +# undef BOOST_COMP_EDG +# define BOOST_COMP_EDG BOOST_COMP_EDG_DETECTION +# endif +# define BOOST_COMP_EDG_AVAILABLE +# include +#endif + +#define BOOST_COMP_EDG_NAME "EDG C++ Frontend" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG,BOOST_COMP_EDG_NAME) + +#ifdef BOOST_COMP_EDG_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG_EMULATED,BOOST_COMP_EDG_NAME) +#endif diff --git a/src/boost/predef/compiler/ekopath.h b/src/boost/predef/compiler/ekopath.h new file mode 100644 index 00000000..f91c9dce --- /dev/null +++ b/src/boost/predef/compiler/ekopath.h @@ -0,0 +1,58 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_EKOPATH_H +#define BOOST_PREDEF_COMPILER_EKOPATH_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_PATH` + +http://en.wikipedia.org/wiki/PathScale[EKOpath] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__PATHCC__+` | {predef_detection} + +| `+__PATHCC__+`, `+__PATHCC_MINOR__+`, `+__PATHCC_PATCHLEVEL__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_PATH BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__PATHCC__) +# define BOOST_COMP_PATH_DETECTION \ + BOOST_VERSION_NUMBER(__PATHCC__,__PATHCC_MINOR__,__PATHCC_PATCHLEVEL__) +#endif + +#ifdef BOOST_COMP_PATH_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_PATH_EMULATED BOOST_COMP_PATH_DETECTION +# else +# undef BOOST_COMP_PATH +# define BOOST_COMP_PATH BOOST_COMP_PATH_DETECTION +# endif +# define BOOST_COMP_PATH_AVAILABLE +# include +#endif + +#define BOOST_COMP_PATH_NAME "EKOpath" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH,BOOST_COMP_PATH_NAME) + +#ifdef BOOST_COMP_PATH_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH_EMULATED,BOOST_COMP_PATH_NAME) +#endif diff --git a/src/boost/predef/compiler/gcc.h b/src/boost/predef/compiler/gcc.h new file mode 100644 index 00000000..88698d21 --- /dev/null +++ b/src/boost/predef/compiler/gcc.h @@ -0,0 +1,69 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_GCC_H +#define BOOST_PREDEF_COMPILER_GCC_H + +/* Other compilers that emulate this one need to be detected first. */ + +#include + +#include +#include + +/* tag::reference[] += `BOOST_COMP_GNUC` + +http://en.wikipedia.org/wiki/GNU_Compiler_Collection[Gnu GCC C/{CPP}] compiler. +Version number available as major, minor, and patch (if available). + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__GNUC__+` | {predef_detection} + +| `+__GNUC__+`, `+__GNUC_MINOR__+`, `+__GNUC_PATCHLEVEL__+` | V.R.P +| `+__GNUC__+`, `+__GNUC_MINOR__+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_COMP_GNUC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GNUC__) +# if !defined(BOOST_COMP_GNUC_DETECTION) && defined(__GNUC_PATCHLEVEL__) +# define BOOST_COMP_GNUC_DETECTION \ + BOOST_VERSION_NUMBER(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +# endif +# if !defined(BOOST_COMP_GNUC_DETECTION) +# define BOOST_COMP_GNUC_DETECTION \ + BOOST_VERSION_NUMBER(__GNUC__,__GNUC_MINOR__,0) +# endif +#endif + +#ifdef BOOST_COMP_GNUC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_GNUC_EMULATED BOOST_COMP_GNUC_DETECTION +# else +# undef BOOST_COMP_GNUC +# define BOOST_COMP_GNUC BOOST_COMP_GNUC_DETECTION +# endif +# define BOOST_COMP_GNUC_AVAILABLE +# include +#endif + +#define BOOST_COMP_GNUC_NAME "Gnu GCC C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC,BOOST_COMP_GNUC_NAME) + +#ifdef BOOST_COMP_GNUC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC_EMULATED,BOOST_COMP_GNUC_NAME) +#endif diff --git a/src/boost/predef/compiler/gcc_xml.h b/src/boost/predef/compiler/gcc_xml.h new file mode 100644 index 00000000..a9253370 --- /dev/null +++ b/src/boost/predef/compiler/gcc_xml.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_GCC_XML_H +#define BOOST_PREDEF_COMPILER_GCC_XML_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_GCCXML` + +http://www.gccxml.org/[GCC XML] compiler. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__GCCXML__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_COMP_GCCXML BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GCCXML__) +# define BOOST_COMP_GCCXML_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_GCCXML_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_GCCXML_EMULATED BOOST_COMP_GCCXML_DETECTION +# else +# undef BOOST_COMP_GCCXML +# define BOOST_COMP_GCCXML BOOST_COMP_GCCXML_DETECTION +# endif +# define BOOST_COMP_GCCXML_AVAILABLE +# include +#endif + +#define BOOST_COMP_GCCXML_NAME "GCC XML" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML,BOOST_COMP_GCCXML_NAME) + +#ifdef BOOST_COMP_GCCXML_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML_EMULATED,BOOST_COMP_GCCXML_NAME) +#endif diff --git a/src/boost/predef/compiler/greenhills.h b/src/boost/predef/compiler/greenhills.h new file mode 100644 index 00000000..9bf5bf17 --- /dev/null +++ b/src/boost/predef/compiler/greenhills.h @@ -0,0 +1,67 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_GREENHILLS_H +#define BOOST_PREDEF_COMPILER_GREENHILLS_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_GHS` + +http://en.wikipedia.org/wiki/Green_Hills_Software[Green Hills C/{CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__ghs+` | {predef_detection} +| `+__ghs__+` | {predef_detection} + +| `+__GHS_VERSION_NUMBER__+` | V.R.P +| `+__ghs+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_GHS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__ghs) || defined(__ghs__) +# if !defined(BOOST_COMP_GHS_DETECTION) && defined(__GHS_VERSION_NUMBER__) +# define BOOST_COMP_GHS_DETECTION BOOST_PREDEF_MAKE_10_VRP(__GHS_VERSION_NUMBER__) +# endif +# if !defined(BOOST_COMP_GHS_DETECTION) && defined(__ghs) +# define BOOST_COMP_GHS_DETECTION BOOST_PREDEF_MAKE_10_VRP(__ghs) +# endif +# if !defined(BOOST_COMP_GHS_DETECTION) +# define BOOST_COMP_GHS_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_GHS_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_GHS_EMULATED BOOST_COMP_GHS_DETECTION +# else +# undef BOOST_COMP_GHS +# define BOOST_COMP_GHS BOOST_COMP_GHS_DETECTION +# endif +# define BOOST_COMP_GHS_AVAILABLE +# include +#endif + +#define BOOST_COMP_GHS_NAME "Green Hills C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS,BOOST_COMP_GHS_NAME) + +#ifdef BOOST_COMP_GHS_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS_EMULATED,BOOST_COMP_GHS_NAME) +#endif diff --git a/src/boost/predef/compiler/hp_acc.h b/src/boost/predef/compiler/hp_acc.h new file mode 100644 index 00000000..7a825cd5 --- /dev/null +++ b/src/boost/predef/compiler/hp_acc.h @@ -0,0 +1,62 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_HP_ACC_H +#define BOOST_PREDEF_COMPILER_HP_ACC_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_HPACC` + +HP a{CPP} compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__HP_aCC+` | {predef_detection} + +| `+__HP_aCC+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_HPACC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__HP_aCC) +# if !defined(BOOST_COMP_HPACC_DETECTION) && (__HP_aCC > 1) +# define BOOST_COMP_HPACC_DETECTION BOOST_PREDEF_MAKE_10_VVRRPP(__HP_aCC) +# endif +# if !defined(BOOST_COMP_HPACC_DETECTION) +# define BOOST_COMP_HPACC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_HPACC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_HPACC_EMULATED BOOST_COMP_HPACC_DETECTION +# else +# undef BOOST_COMP_HPACC +# define BOOST_COMP_HPACC BOOST_COMP_HPACC_DETECTION +# endif +# define BOOST_COMP_HPACC_AVAILABLE +# include +#endif + +#define BOOST_COMP_HPACC_NAME "HP aC++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC,BOOST_COMP_HPACC_NAME) + +#ifdef BOOST_COMP_HPACC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC_EMULATED,BOOST_COMP_HPACC_NAME) +#endif diff --git a/src/boost/predef/compiler/iar.h b/src/boost/predef/compiler/iar.h new file mode 100644 index 00000000..1140b0b4 --- /dev/null +++ b/src/boost/predef/compiler/iar.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_IAR_H +#define BOOST_PREDEF_COMPILER_IAR_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_IAR` + +IAR C/{CPP} compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__IAR_SYSTEMS_ICC__+` | {predef_detection} + +| `+__VER__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_IAR BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__IAR_SYSTEMS_ICC__) +# define BOOST_COMP_IAR_DETECTION BOOST_PREDEF_MAKE_10_VVRR(__VER__) +#endif + +#ifdef BOOST_COMP_IAR_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_IAR_EMULATED BOOST_COMP_IAR_DETECTION +# else +# undef BOOST_COMP_IAR +# define BOOST_COMP_IAR BOOST_COMP_IAR_DETECTION +# endif +# define BOOST_COMP_IAR_AVAILABLE +# include +#endif + +#define BOOST_COMP_IAR_NAME "IAR C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR,BOOST_COMP_IAR_NAME) + +#ifdef BOOST_COMP_IAR_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR_EMULATED,BOOST_COMP_IAR_NAME) +#endif diff --git a/src/boost/predef/compiler/ibm.h b/src/boost/predef/compiler/ibm.h new file mode 100644 index 00000000..6820677f --- /dev/null +++ b/src/boost/predef/compiler/ibm.h @@ -0,0 +1,73 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_IBM_H +#define BOOST_PREDEF_COMPILER_IBM_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_IBM` + +http://en.wikipedia.org/wiki/VisualAge[IBM XL C/{CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__IBMCPP__+` | {predef_detection} +| `+__xlC__+` | {predef_detection} +| `+__xlc__+` | {predef_detection} + +| `+__COMPILER_VER__+` | V.R.P +| `+__xlC__+` | V.R.P +| `+__xlc__+` | V.R.P +| `+__IBMCPP__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_IBM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__IBMCPP__) || defined(__xlC__) || defined(__xlc__) +# if !defined(BOOST_COMP_IBM_DETECTION) && defined(__COMPILER_VER__) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VRRPPPP(__COMPILER_VER__) +# endif +# if !defined(BOOST_COMP_IBM_DETECTION) && defined(__xlC__) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__xlC__) +# endif +# if !defined(BOOST_COMP_IBM_DETECTION) && defined(__xlc__) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__xlc__) +# endif +# if !defined(BOOST_COMP_IBM_DETECTION) +# define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_10_VRP(__IBMCPP__) +# endif +#endif + +#ifdef BOOST_COMP_IBM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_IBM_EMULATED BOOST_COMP_IBM_DETECTION +# else +# undef BOOST_COMP_IBM +# define BOOST_COMP_IBM BOOST_COMP_IBM_DETECTION +# endif +# define BOOST_COMP_IBM_AVAILABLE +# include +#endif + +#define BOOST_COMP_IBM_NAME "IBM XL C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM,BOOST_COMP_IBM_NAME) + +#ifdef BOOST_COMP_IBM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM_EMULATED,BOOST_COMP_IBM_NAME) +#endif diff --git a/src/boost/predef/compiler/intel.h b/src/boost/predef/compiler/intel.h new file mode 100644 index 00000000..62d510ab --- /dev/null +++ b/src/boost/predef/compiler/intel.h @@ -0,0 +1,80 @@ +/* +Copyright Rene Rivera 2008-2017 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_INTEL_H +#define BOOST_PREDEF_COMPILER_INTEL_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_INTEL` + +http://en.wikipedia.org/wiki/Intel_C%2B%2B[Intel C/{CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__INTEL_COMPILER+` | {predef_detection} +| `+__ICL+` | {predef_detection} +| `+__ICC+` | {predef_detection} +| `+__ECC+` | {predef_detection} + +| `+__INTEL_COMPILER+` | V.R +| `+__INTEL_COMPILER+` and `+__INTEL_COMPILER_UPDATE+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_INTEL BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || \ + defined(__ECC) +/* tag::reference[] +NOTE: Because of an Intel mistake in the release version numbering when +`__INTEL_COMPILER` is `9999` it is detected as version 12.1.0. +*/ // end::reference[] +# if !defined(BOOST_COMP_INTEL_DETECTION) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 9999) +# define BOOST_COMP_INTEL_DETECTION BOOST_VERSION_NUMBER(12,1,0) +# endif +# if !defined(BOOST_COMP_INTEL_DETECTION) && defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) +# define BOOST_COMP_INTEL_DETECTION BOOST_VERSION_NUMBER( \ + BOOST_VERSION_NUMBER_MAJOR(BOOST_PREDEF_MAKE_10_VVRR(__INTEL_COMPILER)), \ + BOOST_VERSION_NUMBER_MINOR(BOOST_PREDEF_MAKE_10_VVRR(__INTEL_COMPILER)), \ + __INTEL_COMPILER_UPDATE) +# endif +# if !defined(BOOST_COMP_INTEL_DETECTION) && defined(__INTEL_COMPILER) +# define BOOST_COMP_INTEL_DETECTION BOOST_PREDEF_MAKE_10_VVRR(__INTEL_COMPILER) +# endif +# if !defined(BOOST_COMP_INTEL_DETECTION) +# define BOOST_COMP_INTEL_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_INTEL_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_INTEL_EMULATED BOOST_COMP_INTEL_DETECTION +# else +# undef BOOST_COMP_INTEL +# define BOOST_COMP_INTEL BOOST_COMP_INTEL_DETECTION +# endif +# define BOOST_COMP_INTEL_AVAILABLE +# include +#endif + +#define BOOST_COMP_INTEL_NAME "Intel C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL,BOOST_COMP_INTEL_NAME) + +#ifdef BOOST_COMP_INTEL_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL_EMULATED,BOOST_COMP_INTEL_NAME) +#endif diff --git a/src/boost/predef/compiler/kai.h b/src/boost/predef/compiler/kai.h new file mode 100644 index 00000000..1980cc84 --- /dev/null +++ b/src/boost/predef/compiler/kai.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_KAI_H +#define BOOST_PREDEF_COMPILER_KAI_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_KCC` + +Kai {CPP} compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__KCC+` | {predef_detection} + +| `+__KCC_VERSION+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_KCC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__KCC) +# define BOOST_COMP_KCC_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__KCC_VERSION) +#endif + +#ifdef BOOST_COMP_KCC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_KCC_EMULATED BOOST_COMP_KCC_DETECTION +# else +# undef BOOST_COMP_KCC +# define BOOST_COMP_KCC BOOST_COMP_KCC_DETECTION +# endif +# define BOOST_COMP_KCC_AVAILABLE +# include +#endif + +#define BOOST_COMP_KCC_NAME "Kai C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC,BOOST_COMP_KCC_NAME) + +#ifdef BOOST_COMP_KCC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC_EMULATED,BOOST_COMP_KCC_NAME) +#endif diff --git a/src/boost/predef/compiler/llvm.h b/src/boost/predef/compiler/llvm.h new file mode 100644 index 00000000..09f2b804 --- /dev/null +++ b/src/boost/predef/compiler/llvm.h @@ -0,0 +1,58 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_LLVM_H +#define BOOST_PREDEF_COMPILER_LLVM_H + +/* Other compilers that emulate this one need to be detected first. */ + +#include + +#include +#include + +/* tag::reference[] += `BOOST_COMP_LLVM` + +http://en.wikipedia.org/wiki/LLVM[LLVM] compiler. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__llvm__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_COMP_LLVM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__llvm__) +# define BOOST_COMP_LLVM_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_LLVM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_LLVM_EMULATED BOOST_COMP_LLVM_DETECTION +# else +# undef BOOST_COMP_LLVM +# define BOOST_COMP_LLVM BOOST_COMP_LLVM_DETECTION +# endif +# define BOOST_COMP_LLVM_AVAILABLE +# include +#endif + +#define BOOST_COMP_LLVM_NAME "LLVM" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM,BOOST_COMP_LLVM_NAME) + +#ifdef BOOST_COMP_LLVM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM_EMULATED,BOOST_COMP_LLVM_NAME) +#endif diff --git a/src/boost/predef/compiler/metaware.h b/src/boost/predef/compiler/metaware.h new file mode 100644 index 00000000..e210943d --- /dev/null +++ b/src/boost/predef/compiler/metaware.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_METAWARE_H +#define BOOST_PREDEF_COMPILER_METAWARE_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_HIGHC` + +MetaWare High C/{CPP} compiler. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__HIGHC__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_COMP_HIGHC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__HIGHC__) +# define BOOST_COMP_HIGHC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_HIGHC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_HIGHC_EMULATED BOOST_COMP_HIGHC_DETECTION +# else +# undef BOOST_COMP_HIGHC +# define BOOST_COMP_HIGHC BOOST_COMP_HIGHC_DETECTION +# endif +# define BOOST_COMP_HIGHC_AVAILABLE +# include +#endif + +#define BOOST_COMP_HIGHC_NAME "MetaWare High C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC,BOOST_COMP_HIGHC_NAME) + +#ifdef BOOST_COMP_HIGHC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC_EMULATED,BOOST_COMP_HIGHC_NAME) +#endif diff --git a/src/boost/predef/compiler/metrowerks.h b/src/boost/predef/compiler/metrowerks.h new file mode 100644 index 00000000..98cb751d --- /dev/null +++ b/src/boost/predef/compiler/metrowerks.h @@ -0,0 +1,78 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_METROWERKS_H +#define BOOST_PREDEF_COMPILER_METROWERKS_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_MWERKS` + +http://en.wikipedia.org/wiki/CodeWarrior[Metrowerks CodeWarrior] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__MWERKS__+` | {predef_detection} +| `+__CWCC__+` | {predef_detection} + +| `+__CWCC__+` | V.R.P +| `+__MWERKS__+` | V.R.P >= 4.2.0 +| `+__MWERKS__+` | 9.R.0 +| `+__MWERKS__+` | 8.R.0 +|=== +*/ // end::reference[] + +#define BOOST_COMP_MWERKS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MWERKS__) || defined(__CWCC__) +# if !defined(BOOST_COMP_MWERKS_DETECTION) && defined(__CWCC__) +# define BOOST_COMP_MWERKS_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__CWCC__) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x4200) +# define BOOST_COMP_MWERKS_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__MWERKS__) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3204) // note the "skip": 04->9.3 +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(9,(__MWERKS__)%100-1,0) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3200) +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(9,(__MWERKS__)%100,0) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3000) +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(8,(__MWERKS__)%100,0) +# endif +# if !defined(BOOST_COMP_MWERKS_DETECTION) +# define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_MWERKS_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MWERKS_EMULATED BOOST_COMP_MWERKS_DETECTION +# else +# undef BOOST_COMP_MWERKS +# define BOOST_COMP_MWERKS BOOST_COMP_MWERKS_DETECTION +# endif +# define BOOST_COMP_MWERKS_AVAILABLE +# include +#endif + +#define BOOST_COMP_MWERKS_NAME "Metrowerks CodeWarrior" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS,BOOST_COMP_MWERKS_NAME) + +#ifdef BOOST_COMP_MWERKS_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS_EMULATED,BOOST_COMP_MWERKS_NAME) +#endif diff --git a/src/boost/predef/compiler/microtec.h b/src/boost/predef/compiler/microtec.h new file mode 100644 index 00000000..93c7e910 --- /dev/null +++ b/src/boost/predef/compiler/microtec.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_MICROTEC_H +#define BOOST_PREDEF_COMPILER_MICROTEC_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_MRI` + +http://www.mentor.com/microtec/[Microtec C/{CPP}] compiler. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_MRI+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_COMP_MRI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_MRI) +# define BOOST_COMP_MRI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_MRI_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MRI_EMULATED BOOST_COMP_MRI_DETECTION +# else +# undef BOOST_COMP_MRI +# define BOOST_COMP_MRI BOOST_COMP_MRI_DETECTION +# endif +# define BOOST_COMP_MRI_AVAILABLE +# include +#endif + +#define BOOST_COMP_MRI_NAME "Microtec C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI,BOOST_COMP_MRI_NAME) + +#ifdef BOOST_COMP_MRI_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI_EMULATED,BOOST_COMP_MRI_NAME) +#endif diff --git a/src/boost/predef/compiler/mpw.h b/src/boost/predef/compiler/mpw.h new file mode 100644 index 00000000..963f7567 --- /dev/null +++ b/src/boost/predef/compiler/mpw.h @@ -0,0 +1,64 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_MPW_H +#define BOOST_PREDEF_COMPILER_MPW_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_MPW` + +http://en.wikipedia.org/wiki/Macintosh_Programmer%27s_Workshop[MPW {CPP}] compiler. +Version number available as major, and minor. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__MRC__+` | {predef_detection} +| `MPW_C` | {predef_detection} +| `MPW_CPLUS` | {predef_detection} + +| `+__MRC__+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_COMP_MPW BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MRC__) || defined(MPW_C) || defined(MPW_CPLUS) +# if !defined(BOOST_COMP_MPW_DETECTION) && defined(__MRC__) +# define BOOST_COMP_MPW_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__MRC__) +# endif +# if !defined(BOOST_COMP_MPW_DETECTION) +# define BOOST_COMP_MPW_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_MPW_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MPW_EMULATED BOOST_COMP_MPW_DETECTION +# else +# undef BOOST_COMP_MPW +# define BOOST_COMP_MPW BOOST_COMP_MPW_DETECTION +# endif +# define BOOST_COMP_MPW_AVAILABLE +# include +#endif + +#define BOOST_COMP_MPW_NAME "MPW C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW,BOOST_COMP_MPW_NAME) + +#ifdef BOOST_COMP_MPW_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW_EMULATED,BOOST_COMP_MPW_NAME) +#endif diff --git a/src/boost/predef/compiler/nvcc.h b/src/boost/predef/compiler/nvcc.h new file mode 100644 index 00000000..3690c535 --- /dev/null +++ b/src/boost/predef/compiler/nvcc.h @@ -0,0 +1,74 @@ +/* +Copyright Benjamin Worpitz 2018 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_NVCC_H +#define BOOST_PREDEF_COMPILER_NVCC_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_NVCC` + +https://en.wikipedia.org/wiki/NVIDIA_CUDA_Compiler[NVCC] compiler. +Version number available as major, minor, and patch beginning with version 7.5. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__NVCC__+` | {predef_detection} + +| `+__CUDACC_VER_MAJOR__+`, `+__CUDACC_VER_MINOR__+`, `+__CUDACC_VER_BUILD__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_NVCC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__NVCC__) +# if !defined(__CUDACC_VER_MAJOR__) || !defined(__CUDACC_VER_MINOR__) || !defined(__CUDACC_VER_BUILD__) +# define BOOST_COMP_NVCC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# else +# define BOOST_COMP_NVCC_DETECTION BOOST_VERSION_NUMBER(__CUDACC_VER_MAJOR__, __CUDACC_VER_MINOR__, __CUDACC_VER_BUILD__) +# endif +#endif + +#ifdef BOOST_COMP_NVCC_DETECTION +/* +Always define BOOST_COMP_NVCC instead of BOOST_COMP_NVCC_EMULATED +The nvcc compilation process is somewhat special as can be read here: +https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#cuda-compilation-trajectory +The nvcc compiler precompiles the input two times. Once for the device code +being compiled by the cicc device compiler and once for the host code +compiled by the real host compiler. NVCC uses gcc/clang/msvc/... +depending on the host compiler being set on the command line. + +Predef (as a preprocessor only lib) detects the one doing the preprocessing +as compiler and expects it to be the one doing the real compilation. +This is not true for NVCC which is only doing the preprocessing and which +is using another compiler for parts of its work. So for NVCC it should be +allowed to set BOOST_COMP_NVCC additionally to the already detected host +compiler because both is true: It is gcc/clang/... compiling the code, but it +is also NVCC doing the preprocessing and adding some other quirks you may +want to detect. + +This behavior is similar to what boost config is doing in `select_compiler_config.hpp`. +There the NVCC detection is not handled as a real compiler (part of the +#if-#elif) but as additional option before the real compiler. +*/ +# undef BOOST_COMP_NVCC +# define BOOST_COMP_NVCC BOOST_COMP_NVCC_DETECTION +# define BOOST_COMP_NVCC_AVAILABLE +# include +#endif + +#define BOOST_COMP_NVCC_NAME "NVCC" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_NVCC,BOOST_COMP_NVCC_NAME) diff --git a/src/boost/predef/compiler/palm.h b/src/boost/predef/compiler/palm.h new file mode 100644 index 00000000..7f182151 --- /dev/null +++ b/src/boost/predef/compiler/palm.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_PALM_H +#define BOOST_PREDEF_COMPILER_PALM_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_PALM` + +Palm C/{CPP} compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_PACC_VER+` | {predef_detection} + +| `+_PACC_VER+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_PALM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_PACC_VER) +# define BOOST_COMP_PALM_DETECTION BOOST_PREDEF_MAKE_0X_VRRPP000(_PACC_VER) +#endif + +#ifdef BOOST_COMP_PALM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_PALM_EMULATED BOOST_COMP_PALM_DETECTION +# else +# undef BOOST_COMP_PALM +# define BOOST_COMP_PALM BOOST_COMP_PALM_DETECTION +# endif +# define BOOST_COMP_PALM_AVAILABLE +# include +#endif + +#define BOOST_COMP_PALM_NAME "Palm C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM,BOOST_COMP_PALM_NAME) + +#ifdef BOOST_COMP_PALM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM_EMULATED,BOOST_COMP_PALM_NAME) +#endif diff --git a/src/boost/predef/compiler/pgi.h b/src/boost/predef/compiler/pgi.h new file mode 100644 index 00000000..649e87ad --- /dev/null +++ b/src/boost/predef/compiler/pgi.h @@ -0,0 +1,61 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_PGI_H +#define BOOST_PREDEF_COMPILER_PGI_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_PGI` + +http://en.wikipedia.org/wiki/The_Portland_Group[Portland Group C/{CPP}] compiler. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__PGI+` | {predef_detection} + +| `+__PGIC__+`, `+__PGIC_MINOR__+`, `+__PGIC_PATCHLEVEL__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_PGI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__PGI) +# if !defined(BOOST_COMP_PGI_DETECTION) && (defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)) +# define BOOST_COMP_PGI_DETECTION BOOST_VERSION_NUMBER(__PGIC__,__PGIC_MINOR__,__PGIC_PATCHLEVEL__) +# endif +# if !defined(BOOST_COMP_PGI_DETECTION) +# define BOOST_COMP_PGI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_PGI_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_PGI_EMULATED BOOST_COMP_PGI_DETECTION +# else +# undef BOOST_COMP_PGI +# define BOOST_COMP_PGI BOOST_COMP_PGI_DETECTION +# endif +# define BOOST_COMP_PGI_AVAILABLE +# include +#endif + +#define BOOST_COMP_PGI_NAME "Portland Group C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI,BOOST_COMP_PGI_NAME) + +#ifdef BOOST_COMP_PGI_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI_EMULATED,BOOST_COMP_PGI_NAME) +#endif diff --git a/src/boost/predef/compiler/sgi_mipspro.h b/src/boost/predef/compiler/sgi_mipspro.h new file mode 100644 index 00000000..7bfdc9c6 --- /dev/null +++ b/src/boost/predef/compiler/sgi_mipspro.h @@ -0,0 +1,67 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_SGI_MIPSPRO_H +#define BOOST_PREDEF_COMPILER_SGI_MIPSPRO_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_SGI` + +http://en.wikipedia.org/wiki/MIPSpro[SGI MIPSpro] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__sgi+` | {predef_detection} +| `sgi` | {predef_detection} + +| `+_SGI_COMPILER_VERSION+` | V.R.P +| `+_COMPILER_VERSION+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_SGI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sgi) || defined(sgi) +# if !defined(BOOST_COMP_SGI_DETECTION) && defined(_SGI_COMPILER_VERSION) +# define BOOST_COMP_SGI_DETECTION BOOST_PREDEF_MAKE_10_VRP(_SGI_COMPILER_VERSION) +# endif +# if !defined(BOOST_COMP_SGI_DETECTION) && defined(_COMPILER_VERSION) +# define BOOST_COMP_SGI_DETECTION BOOST_PREDEF_MAKE_10_VRP(_COMPILER_VERSION) +# endif +# if !defined(BOOST_COMP_SGI_DETECTION) +# define BOOST_COMP_SGI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_SGI_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_SGI_EMULATED BOOST_COMP_SGI_DETECTION +# else +# undef BOOST_COMP_SGI +# define BOOST_COMP_SGI BOOST_COMP_SGI_DETECTION +# endif +# define BOOST_COMP_SGI_AVAILABLE +# include +#endif + +#define BOOST_COMP_SGI_NAME "SGI MIPSpro" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI,BOOST_COMP_SGI_NAME) + +#ifdef BOOST_COMP_SGI_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI_EMULATED,BOOST_COMP_SGI_NAME) +#endif diff --git a/src/boost/predef/compiler/sunpro.h b/src/boost/predef/compiler/sunpro.h new file mode 100644 index 00000000..b44d0bb3 --- /dev/null +++ b/src/boost/predef/compiler/sunpro.h @@ -0,0 +1,77 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_SUNPRO_H +#define BOOST_PREDEF_COMPILER_SUNPRO_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_SUNPRO` + +http://en.wikipedia.org/wiki/Oracle_Solaris_Studio[Oracle Solaris Studio] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SUNPRO_CC+` | {predef_detection} +| `+__SUNPRO_C+` | {predef_detection} + +| `+__SUNPRO_CC+` | V.R.P +| `+__SUNPRO_C+` | V.R.P +| `+__SUNPRO_CC+` | VV.RR.P +| `+__SUNPRO_C+` | VV.RR.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_SUNPRO BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SUNPRO_CC) || defined(__SUNPRO_C) +# if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_CC) +# if (__SUNPRO_CC < 0x5100) +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_CC) +# else +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_CC) +# endif +# endif +# if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_C) +# if (__SUNPRO_C < 0x5100) +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_C) +# else +# define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_C) +# endif +# endif +# if !defined(BOOST_COMP_SUNPRO_DETECTION) +# define BOOST_COMP_SUNPRO_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_COMP_SUNPRO_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_SUNPRO_EMULATED BOOST_COMP_SUNPRO_DETECTION +# else +# undef BOOST_COMP_SUNPRO +# define BOOST_COMP_SUNPRO BOOST_COMP_SUNPRO_DETECTION +# endif +# define BOOST_COMP_SUNPRO_AVAILABLE +# include +#endif + +#define BOOST_COMP_SUNPRO_NAME "Oracle Solaris Studio" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO,BOOST_COMP_SUNPRO_NAME) + +#ifdef BOOST_COMP_SUNPRO_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO_EMULATED,BOOST_COMP_SUNPRO_NAME) +#endif diff --git a/src/boost/predef/compiler/tendra.h b/src/boost/predef/compiler/tendra.h new file mode 100644 index 00000000..bb896c07 --- /dev/null +++ b/src/boost/predef/compiler/tendra.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_TENDRA_H +#define BOOST_PREDEF_COMPILER_TENDRA_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_TENDRA` + +http://en.wikipedia.org/wiki/TenDRA_Compiler[TenDRA C/{CPP}] compiler. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__TenDRA__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_COMP_TENDRA BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__TenDRA__) +# define BOOST_COMP_TENDRA_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#ifdef BOOST_COMP_TENDRA_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_TENDRA_EMULATED BOOST_COMP_TENDRA_DETECTION +# else +# undef BOOST_COMP_TENDRA +# define BOOST_COMP_TENDRA BOOST_COMP_TENDRA_DETECTION +# endif +# define BOOST_COMP_TENDRA_AVAILABLE +# include +#endif + +#define BOOST_COMP_TENDRA_NAME "TenDRA C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA,BOOST_COMP_TENDRA_NAME) + +#ifdef BOOST_COMP_TENDRA_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA_EMULATED,BOOST_COMP_TENDRA_NAME) +#endif diff --git a/src/boost/predef/compiler/visualc.h b/src/boost/predef/compiler/visualc.h new file mode 100644 index 00000000..5b0f2b83 --- /dev/null +++ b/src/boost/predef/compiler/visualc.h @@ -0,0 +1,106 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_VISUALC_H +#define BOOST_PREDEF_COMPILER_VISUALC_H + +/* Other compilers that emulate this one need to be detected first. */ + +#include + +#include +#include + +/* tag::reference[] += `BOOST_COMP_MSVC` + +http://en.wikipedia.org/wiki/Visual_studio[Microsoft Visual C/{CPP}] compiler. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_MSC_VER+` | {predef_detection} + +| `+_MSC_FULL_VER+` | V.R.P +| `+_MSC_VER+` | V.R.0 +|=== + +NOTE: Release of Visual Studio after 2015 will no longer be identified +by Boost Predef as the marketing version number. Instead we use the +compiler version number directly, i.e. the _MSC_VER number. +*/ // end::reference[] + +#define BOOST_COMP_MSVC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_MSC_VER) +# if !defined (_MSC_FULL_VER) +# define BOOST_COMP_MSVC_BUILD 0 +# else + /* how many digits does the build number have? */ +# if _MSC_FULL_VER / 10000 == _MSC_VER + /* four digits */ +# define BOOST_COMP_MSVC_BUILD (_MSC_FULL_VER % 10000) +# elif _MSC_FULL_VER / 100000 == _MSC_VER + /* five digits */ +# define BOOST_COMP_MSVC_BUILD (_MSC_FULL_VER % 100000) +# else +# error "Cannot determine build number from _MSC_FULL_VER" +# endif +# endif + /* + VS2014 was skipped in the release sequence for MS. Which + means that the compiler and VS product versions are no longer + in sync. Hence we need to use different formulas for + mapping from MSC version to VS product version. + + VS2017 is a total nightmare when it comes to version numbers. + Hence to avoid arguments relating to that both present and + future.. Any version after VS2015 will use solely the compiler + version, i.e. cl.exe, as the version number here. + */ +# if (_MSC_VER > 1900) +# define BOOST_COMP_MSVC_DETECTION BOOST_VERSION_NUMBER(\ + _MSC_VER/100,\ + _MSC_VER%100,\ + BOOST_COMP_MSVC_BUILD) +# elif (_MSC_VER >= 1900) +# define BOOST_COMP_MSVC_DETECTION BOOST_VERSION_NUMBER(\ + _MSC_VER/100-5,\ + _MSC_VER%100,\ + BOOST_COMP_MSVC_BUILD) +# else +# define BOOST_COMP_MSVC_DETECTION BOOST_VERSION_NUMBER(\ + _MSC_VER/100-6,\ + _MSC_VER%100,\ + BOOST_COMP_MSVC_BUILD) +# endif +#endif + +#ifdef BOOST_COMP_MSVC_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_MSVC_EMULATED BOOST_COMP_MSVC_DETECTION +# else +# undef BOOST_COMP_MSVC +# define BOOST_COMP_MSVC BOOST_COMP_MSVC_DETECTION +# endif +# define BOOST_COMP_MSVC_AVAILABLE +# include +#endif + +#define BOOST_COMP_MSVC_NAME "Microsoft Visual C/C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC,BOOST_COMP_MSVC_NAME) + +#ifdef BOOST_COMP_MSVC_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC_EMULATED,BOOST_COMP_MSVC_NAME) +#endif diff --git a/src/boost/predef/compiler/watcom.h b/src/boost/predef/compiler/watcom.h new file mode 100644 index 00000000..1f8c069d --- /dev/null +++ b/src/boost/predef/compiler/watcom.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_COMPILER_WATCOM_H +#define BOOST_PREDEF_COMPILER_WATCOM_H + +#include +#include + +/* tag::reference[] += `BOOST_COMP_WATCOM` + +http://en.wikipedia.org/wiki/Watcom[Watcom {CPP}] compiler. +Version number available as major, and minor. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__WATCOMC__+` | {predef_detection} + +| `+__WATCOMC__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_COMP_WATCOM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__WATCOMC__) +# define BOOST_COMP_WATCOM_DETECTION BOOST_PREDEF_MAKE_10_VVRR(__WATCOMC__) +#endif + +#ifdef BOOST_COMP_WATCOM_DETECTION +# if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED) +# define BOOST_COMP_WATCOM_EMULATED BOOST_COMP_WATCOM_DETECTION +# else +# undef BOOST_COMP_WATCOM +# define BOOST_COMP_WATCOM BOOST_COMP_WATCOM_DETECTION +# endif +# define BOOST_COMP_WATCOM_AVAILABLE +# include +#endif + +#define BOOST_COMP_WATCOM_NAME "Watcom C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM,BOOST_COMP_WATCOM_NAME) + +#ifdef BOOST_COMP_WATCOM_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM_EMULATED,BOOST_COMP_WATCOM_NAME) +#endif diff --git a/src/boost/predef/detail/_cassert.h b/src/boost/predef/detail/_cassert.h new file mode 100644 index 00000000..940e944e --- /dev/null +++ b/src/boost/predef/detail/_cassert.h @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2012 +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) +*/ + +#ifndef BOOST_PREDEF_DETAIL__CASSERT_H +#define BOOST_PREDEF_DETAIL__CASSERT_H + +#if defined(__cplusplus) +#include +#else +#include +#endif + +#endif diff --git a/src/boost/predef/detail/_exception.h b/src/boost/predef/detail/_exception.h new file mode 100644 index 00000000..f5a6687a --- /dev/null +++ b/src/boost/predef/detail/_exception.h @@ -0,0 +1,15 @@ +/* +Copyright Rene Rivera 2011-2012 +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) +*/ + +#ifndef BOOST_PREDEF_DETAIL__EXCEPTION_H +#define BOOST_PREDEF_DETAIL__EXCEPTION_H + +#if defined(__cplusplus) +#include +#endif + +#endif diff --git a/src/boost/predef/detail/comp_detected.h b/src/boost/predef/detail/comp_detected.h new file mode 100644 index 00000000..fda1801b --- /dev/null +++ b/src/boost/predef/detail/comp_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Rene Rivera 2014 +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) +*/ + +#ifndef BOOST_PREDEF_DETAIL_COMP_DETECTED +#define BOOST_PREDEF_DETAIL_COMP_DETECTED 1 +#endif diff --git a/src/boost/predef/detail/os_detected.h b/src/boost/predef/detail/os_detected.h new file mode 100644 index 00000000..08e10f99 --- /dev/null +++ b/src/boost/predef/detail/os_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Rene Rivera 2013 +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) +*/ + +#ifndef BOOST_PREDEF_DETAIL_OS_DETECTED +#define BOOST_PREDEF_DETAIL_OS_DETECTED 1 +#endif diff --git a/src/boost/predef/detail/platform_detected.h b/src/boost/predef/detail/platform_detected.h new file mode 100644 index 00000000..4faf6938 --- /dev/null +++ b/src/boost/predef/detail/platform_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Rene Rivera 2014 +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) +*/ + +#ifndef BOOST_PREDEF_DETAIL_PLAT_DETECTED +#define BOOST_PREDEF_DETAIL_PLAT_DETECTED 1 +#endif diff --git a/src/boost/predef/detail/test.h b/src/boost/predef/detail/test.h new file mode 100644 index 00000000..546a9e40 --- /dev/null +++ b/src/boost/predef/detail/test.h @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2012 +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) +*/ + +#ifndef BOOST_PREDEF_DETAIL_TEST_H +#define BOOST_PREDEF_DETAIL_TEST_H + +#if !defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) + +#define BOOST_PREDEF_DECLARE_TEST(x,s) + +#endif + +#endif diff --git a/src/boost/predef/hardware.h b/src/boost/predef/hardware.h new file mode 100644 index 00000000..972b73af --- /dev/null +++ b/src/boost/predef/hardware.h @@ -0,0 +1,16 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#if !defined(BOOST_PREDEF_HARDWARE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_HARDWARE_H +#define BOOST_PREDEF_HARDWARE_H +#endif + +#include + +#endif diff --git a/src/boost/predef/hardware/simd.h b/src/boost/predef/hardware/simd.h new file mode 100644 index 00000000..b671fa3b --- /dev/null +++ b/src/boost/predef/hardware/simd.h @@ -0,0 +1,168 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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 +#include +#include +#include + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_H +#define BOOST_PREDEF_HARDWARE_SIMD_H + +#include + +/* tag::reference[] += Using the `BOOST_HW_SIMD_*` predefs + +SIMD predefs depend on compiler options. For example, you will have to add the +option `-msse3` to clang or gcc to enable SSE3. SIMD predefs are also inclusive. +This means that if SSE3 is enabled, then every other extensions with a lower +version number will implicitly be enabled and detected. However, some extensions +are CPU specific, they may not be detected nor enabled when an upper version is +enabled. + +NOTE: SSE(1) and SSE2 are automatically enabled by default when using x86-64 +architecture. + +To check if any SIMD extension has been enabled, you can use: + +[source] +---- +#include +#include + +int main() +{ +#if defined(BOOST_HW_SIMD_AVAILABLE) + std::cout << "SIMD detected!" << std::endl; +#endif + return 0; +} +---- + +When writing SIMD specific code, you may want to check if a particular extension +has been detected. To do so you have to use the right architecture predef and +compare it. Those predef are of the form `BOOST_HW_SIMD_"ARCH"` (where `"ARCH"` +is either `ARM`, `PPC`, or `X86`). For example, if you compile code for x86 +architecture, you will have to use `BOOST_HW_SIMD_X86`. Its value will be the +version number of the most recent SIMD extension detected for the architecture. + +To check if an extension has been enabled: + +[source] +---- +#include +#include + +int main() +{ +#if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE3_VERSION + std::cout << "This is SSE3!" << std::endl; +#endif + return 0; +} +---- + +NOTE: The *_VERSION* defines that map version number to actual real +identifiers. This way it is easier to write comparisons without messing up with +version numbers. + +To *"strictly"* check the most recent detected extension: + +[source] +---- +#include +#include + +int main() +{ +#if BOOST_HW_SIMD_X86 == BOOST_HW_SIMD_X86_SSE3_VERSION + std::cout << "This is SSE3 and this is the most recent enabled extension!" + << std::endl; +#endif + return 0; +} +---- + +Because of the version systems of predefs and of the inclusive property of SIMD +extensions macros, you can easily check for ranges of supported extensions: + +[source] +---- +#include +#include + +int main() +{ +#if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE2_VERSION &&\ + BOOST_HW_SIMD_X86 <= BOOST_HW_SIMD_X86_SSSE3_VERSION + std::cout << "This is SSE2, SSE3 and SSSE3!" << std::endl; +#endif + return 0; +} +---- + +NOTE: Unlike gcc and clang, Visual Studio does not allow you to specify precisely +the SSE variants you want to use, the only detections that will take place are +SSE, SSE2, AVX and AVX2. For more informations, + see [@https://msdn.microsoft.com/en-us/library/b0084kay.aspx here]. + + +*/ // end::reference[] + +// We check if SIMD extension of multiples architectures have been detected, +// if yes, then this is an error! +// +// NOTE: _X86_AMD implies _X86, so there is no need to check for it here! +// +#if defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_PPC_AVAILABLE) ||\ + defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) ||\ + defined(BOOST_HW_SIMD_PPC_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) +# error "Multiple SIMD architectures detected, this cannot happen!" +#endif + +#if defined(BOOST_HW_SIMD_X86_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE) + // If both standard _X86 and _X86_AMD are available, + // then take the biggest version of the two! +# if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_AMD +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86 +# else +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD +# endif +#endif + +#if !defined(BOOST_HW_SIMD) + // At this point, only one of these two is defined +# if defined(BOOST_HW_SIMD_X86_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86 +# endif +# if defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD +# endif +#endif + +#if defined(BOOST_HW_SIMD_ARM_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_ARM +#endif + +#if defined(BOOST_HW_SIMD_PPC_AVAILABLE) +# define BOOST_HW_SIMD BOOST_HW_SIMD_PPC +#endif + +#if defined(BOOST_HW_SIMD) +# define BOOST_HW_SIMD_AVAILABLE +#else +# define BOOST_HW_SIMD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#endif + +#define BOOST_HW_SIMD_NAME "Hardware SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD, BOOST_HW_SIMD_NAME) diff --git a/src/boost/predef/hardware/simd/arm.h b/src/boost/predef/hardware/simd/arm.h new file mode 100644 index 00000000..24e4c1b0 --- /dev/null +++ b/src/boost/predef/hardware/simd/arm.h @@ -0,0 +1,61 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_ARM_H +#define BOOST_PREDEF_HARDWARE_SIMD_ARM_H + +#include +#include + +/* tag::reference[] += `BOOST_HW_SIMD_ARM` + +The SIMD extension for ARM (*if detected*). +Version number depends on the most recent detected extension. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__ARM_NEON__+` | {predef_detection} +| `+__aarch64__+` | {predef_detection} +| `+_M_ARM+` | {predef_detection} +| `+_M_ARM64+` | {predef_detection} +|=== + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__ARM_NEON__+` | BOOST_HW_SIMD_ARM_NEON_VERSION +| `+__aarch64__+` | BOOST_HW_SIMD_ARM_NEON_VERSION +| `+_M_ARM+` | BOOST_HW_SIMD_ARM_NEON_VERSION +| `+_M_ARM64+` | BOOST_HW_SIMD_ARM_NEON_VERSION +|=== + +*/ // end::reference[] + +#define BOOST_HW_SIMD_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#undef BOOST_HW_SIMD_ARM +#if !defined(BOOST_HW_SIMD_ARM) && (defined(__ARM_NEON__) || defined(__aarch64__) || defined (_M_ARM) || defined (_M_ARM64)) +# define BOOST_HW_SIMD_ARM BOOST_HW_SIMD_ARM_NEON_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_ARM) +# define BOOST_HW_SIMD_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else +# define BOOST_HW_SIMD_ARM_AVAILABLE +#endif + +#define BOOST_HW_SIMD_ARM_NAME "ARM SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_ARM, BOOST_HW_SIMD_ARM_NAME) diff --git a/src/boost/predef/hardware/simd/arm/versions.h b/src/boost/predef/hardware/simd/arm/versions.h new file mode 100644 index 00000000..92071a6b --- /dev/null +++ b/src/boost/predef/hardware/simd/arm/versions.h @@ -0,0 +1,38 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_ARM_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_ARM_VERSIONS_H + +#include + +/* tag::reference[] += `BOOST_HW_SIMD_ARM_*_VERSION` + +Those defines represent ARM SIMD extensions versions. + +NOTE: You *MUST* compare them with the predef `BOOST_HW_SIMD_ARM`. +*/ // end::reference[] + +// --------------------------------- + +/* tag::reference[] += `BOOST_HW_SIMD_ARM_NEON_VERSION` + +The https://en.wikipedia.org/wiki/ARM_architecture#Advanced_SIMD_.28NEON.29[NEON] +ARM extension version number. + +Version number is: *1.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_ARM_NEON_VERSION BOOST_VERSION_NUMBER(1, 0, 0) + +/* tag::reference[] + +*/ // end::reference[] + +#endif diff --git a/src/boost/predef/hardware/simd/ppc.h b/src/boost/predef/hardware/simd/ppc.h new file mode 100644 index 00000000..bf30cc1e --- /dev/null +++ b/src/boost/predef/hardware/simd/ppc.h @@ -0,0 +1,71 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_PPC_H +#define BOOST_PREDEF_HARDWARE_SIMD_PPC_H + +#include +#include + +/* tag::reference[] += `BOOST_HW_SIMD_PPC` + +The SIMD extension for PowerPC (*if detected*). +Version number depends on the most recent detected extension. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__VECTOR4DOUBLE__+` | {predef_detection} + +| `+__ALTIVEC__+` | {predef_detection} +| `+__VEC__+` | {predef_detection} + +| `+__VSX__+` | {predef_detection} +|=== + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__VECTOR4DOUBLE__+` | BOOST_HW_SIMD_PPC_QPX_VERSION + +| `+__ALTIVEC__+` | BOOST_HW_SIMD_PPC_VMX_VERSION +| `+__VEC__+` | BOOST_HW_SIMD_PPC_VMX_VERSION + +| `+__VSX__+` | BOOST_HW_SIMD_PPC_VSX_VERSION +|=== + +*/ // end::reference[] + +#define BOOST_HW_SIMD_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#undef BOOST_HW_SIMD_PPC +#if !defined(BOOST_HW_SIMD_PPC) && defined(__VECTOR4DOUBLE__) +# define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_QPX_VERSION +#endif +#if !defined(BOOST_HW_SIMD_PPC) && defined(__VSX__) +# define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_VSX_VERSION +#endif +#if !defined(BOOST_HW_SIMD_PPC) && (defined(__ALTIVEC__) || defined(__VEC__)) +# define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_VMX_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_PPC) +# define BOOST_HW_SIMD_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else +# define BOOST_HW_SIMD_PPC_AVAILABLE +#endif + +#define BOOST_HW_SIMD_PPC_NAME "PPC SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_PPC, BOOST_HW_SIMD_PPC_NAME) diff --git a/src/boost/predef/hardware/simd/ppc/versions.h b/src/boost/predef/hardware/simd/ppc/versions.h new file mode 100644 index 00000000..3cf8319c --- /dev/null +++ b/src/boost/predef/hardware/simd/ppc/versions.h @@ -0,0 +1,57 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_PPC_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_PPC_VERSIONS_H + +#include + +/* tag::reference[] += `BOOST_HW_SIMD_PPC_*_VERSION` + +Those defines represent Power PC SIMD extensions versions. + +NOTE: You *MUST* compare them with the predef `BOOST_HW_SIMD_PPC`. +*/ // end::reference[] + +// --------------------------------- + +/* tag::reference[] += `BOOST_HW_SIMD_PPC_VMX_VERSION` + +The https://en.wikipedia.org/wiki/AltiVec#VMX128[VMX] powerpc extension +version number. + +Version number is: *1.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_PPC_VMX_VERSION BOOST_VERSION_NUMBER(1, 0, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_PPC_VSX_VERSION` + +The https://en.wikipedia.org/wiki/AltiVec#VSX[VSX] powerpc extension version +number. + +Version number is: *1.1.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_PPC_VSX_VERSION BOOST_VERSION_NUMBER(1, 1, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_PPC_QPX_VERSION` + +The QPX powerpc extension version number. + +Version number is: *2.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_PPC_QPX_VERSION BOOST_VERSION_NUMBER(2, 0, 0) + +/* tag::reference[] + +*/ // end::reference[] + +#endif diff --git a/src/boost/predef/hardware/simd/x86.h b/src/boost/predef/hardware/simd/x86.h new file mode 100644 index 00000000..6c9a0fb8 --- /dev/null +++ b/src/boost/predef/hardware/simd/x86.h @@ -0,0 +1,125 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_H + +#include +#include + +/* tag::reference[] += `BOOST_HW_SIMD_X86` + +The SIMD extension for x86 (*if detected*). +Version number depends on the most recent detected extension. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SSE__+` | {predef_detection} +| `+_M_X64+` | {predef_detection} +| `_M_IX86_FP >= 1` | {predef_detection} + +| `+__SSE2__+` | {predef_detection} +| `+_M_X64+` | {predef_detection} +| `_M_IX86_FP >= 2` | {predef_detection} + +| `+__SSE3__+` | {predef_detection} + +| `+__SSSE3__+` | {predef_detection} + +| `+__SSE4_1__+` | {predef_detection} + +| `+__SSE4_2__+` | {predef_detection} + +| `+__AVX__+` | {predef_detection} + +| `+__FMA__+` | {predef_detection} + +| `+__AVX2__+` | {predef_detection} +|=== + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SSE__+` | BOOST_HW_SIMD_X86_SSE_VERSION +| `+_M_X64+` | BOOST_HW_SIMD_X86_SSE_VERSION +| `_M_IX86_FP >= 1` | BOOST_HW_SIMD_X86_SSE_VERSION + +| `+__SSE2__+` | BOOST_HW_SIMD_X86_SSE2_VERSION +| `+_M_X64+` | BOOST_HW_SIMD_X86_SSE2_VERSION +| `_M_IX86_FP >= 2` | BOOST_HW_SIMD_X86_SSE2_VERSION + +| `+__SSE3__+` | BOOST_HW_SIMD_X86_SSE3_VERSION + +| `+__SSSE3__+` | BOOST_HW_SIMD_X86_SSSE3_VERSION + +| `+__SSE4_1__+` | BOOST_HW_SIMD_X86_SSE4_1_VERSION + +| `+__SSE4_2__+` | BOOST_HW_SIMD_X86_SSE4_2_VERSION + +| `+__AVX__+` | BOOST_HW_SIMD_X86_AVX_VERSION + +| `+__FMA__+` | BOOST_HW_SIMD_X86_FMA3_VERSION + +| `+__AVX2__+` | BOOST_HW_SIMD_X86_AVX2_VERSION +|=== + +*/ // end::reference[] + +#define BOOST_HW_SIMD_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#undef BOOST_HW_SIMD_X86 +#if !defined(BOOST_HW_SIMD_X86) && defined(__MIC__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_MIC_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__AVX2__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_AVX2_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__AVX__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_AVX_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__FMA__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_FMA_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE4_2__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE4_2_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE4_1__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE4_1_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSSE3__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSSE3_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE3__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE3_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && (defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE2_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && (defined(__SSE__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86) && defined(__MMX__) +# define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_MMX_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_X86) +# define BOOST_HW_SIMD_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else +# define BOOST_HW_SIMD_X86_AVAILABLE +#endif + +#define BOOST_HW_SIMD_X86_NAME "x86 SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_X86, BOOST_HW_SIMD_X86_NAME) diff --git a/src/boost/predef/hardware/simd/x86/versions.h b/src/boost/predef/hardware/simd/x86/versions.h new file mode 100644 index 00000000..ef5b002d --- /dev/null +++ b/src/boost/predef/hardware/simd/x86/versions.h @@ -0,0 +1,135 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_VERSIONS_H + +#include + +/* tag::reference[] += `BOOST_HW_SIMD_X86_*_VERSION` + +Those defines represent x86 SIMD extensions versions. + +NOTE: You *MUST* compare them with the predef `BOOST_HW_SIMD_X86`. +*/ // end::reference[] + +// --------------------------------- + +/* tag::reference[] += `BOOST_HW_SIMD_X86_MMX_VERSION` + +The https://en.wikipedia.org/wiki/MMX_(instruction_set)[MMX] x86 extension +version number. + +Version number is: *0.99.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_MMX_VERSION BOOST_VERSION_NUMBER(0, 99, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_SSE_VERSION` + +The https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions[SSE] x86 extension +version number. + +Version number is: *1.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_SSE_VERSION BOOST_VERSION_NUMBER(1, 0, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_SSE2_VERSION` + +The https://en.wikipedia.org/wiki/SSE2[SSE2] x86 extension version number. + +Version number is: *2.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_SSE2_VERSION BOOST_VERSION_NUMBER(2, 0, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_SSE3_VERSION` + +The https://en.wikipedia.org/wiki/SSE3[SSE3] x86 extension version number. + +Version number is: *3.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_SSE3_VERSION BOOST_VERSION_NUMBER(3, 0, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_SSSE3_VERSION` + +The https://en.wikipedia.org/wiki/SSSE3[SSSE3] x86 extension version number. + +Version number is: *3.1.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_SSSE3_VERSION BOOST_VERSION_NUMBER(3, 1, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_SSE4_1_VERSION` + +The https://en.wikipedia.org/wiki/SSE4#SSE4.1[SSE4_1] x86 extension version +number. + +Version number is: *4.1.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_SSE4_1_VERSION BOOST_VERSION_NUMBER(4, 1, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_SSE4_2_VERSION` + +The https://en.wikipedia.org/wiki/SSE4##SSE4.2[SSE4_2] x86 extension version +number. + +Version number is: *4.2.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_SSE4_2_VERSION BOOST_VERSION_NUMBER(4, 2, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_AVX_VERSION` + +The https://en.wikipedia.org/wiki/Advanced_Vector_Extensions[AVX] x86 +extension version number. + +Version number is: *5.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_AVX_VERSION BOOST_VERSION_NUMBER(5, 0, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_FMA3_VERSION` + +The https://en.wikipedia.org/wiki/FMA_instruction_set[FMA3] x86 extension +version number. + +Version number is: *5.2.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_FMA3_VERSION BOOST_VERSION_NUMBER(5, 2, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_AVX2_VERSION` + +The https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2[AVX2] +x86 extension version number. + +Version number is: *5.3.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_AVX2_VERSION BOOST_VERSION_NUMBER(5, 3, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_MIC_VERSION` + +The https://en.wikipedia.org/wiki/Xeon_Phi[MIC] (Xeon Phi) x86 extension +version number. + +Version number is: *9.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_MIC_VERSION BOOST_VERSION_NUMBER(9, 0, 0) + +/* tag::reference[] + +*/ // end::reference[] + +#endif diff --git a/src/boost/predef/hardware/simd/x86_amd.h b/src/boost/predef/hardware/simd/x86_amd.h new file mode 100644 index 00000000..ed96af35 --- /dev/null +++ b/src/boost/predef/hardware/simd/x86_amd.h @@ -0,0 +1,89 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_H + +#include +#include + +/* tag::reference[] += `BOOST_HW_SIMD_X86_AMD` + +The SIMD extension for x86 (AMD) (*if detected*). +Version number depends on the most recent detected extension. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SSE4A__+` | {predef_detection} + +| `+__FMA4__+` | {predef_detection} + +| `+__XOP__+` | {predef_detection} + +| `BOOST_HW_SIMD_X86` | {predef_detection} +|=== + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SSE4A__+` | BOOST_HW_SIMD_X86_SSE4A_VERSION + +| `+__FMA4__+` | BOOST_HW_SIMD_X86_FMA4_VERSION + +| `+__XOP__+` | BOOST_HW_SIMD_X86_XOP_VERSION + +| `BOOST_HW_SIMD_X86` | BOOST_HW_SIMD_X86 +|=== + +NOTE: This predef includes every other x86 SIMD extensions and also has other +more specific extensions (FMA4, XOP, SSE4a). You should use this predef +instead of `BOOST_HW_SIMD_X86` to test if those specific extensions have +been detected. + +*/ // end::reference[] + +#define BOOST_HW_SIMD_X86_AMD BOOST_VERSION_NUMBER_NOT_AVAILABLE + +// AMD CPUs also use x86 architecture. We first try to detect if any AMD +// specific extension are detected, if yes, then try to detect more recent x86 +// common extensions. + +#undef BOOST_HW_SIMD_X86_AMD +#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__XOP__) +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_XOP_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__FMA4__) +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_FMA4_VERSION +#endif +#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__SSE4A__) +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION +#endif + +#if !defined(BOOST_HW_SIMD_X86_AMD) +# define BOOST_HW_SIMD_X86_AMD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#else + // At this point, we know that we have an AMD CPU, we do need to check for + // other x86 extensions to determine the final version number. +# include +# if BOOST_HW_SIMD_X86 > BOOST_HW_SIMD_X86_AMD +# undef BOOST_HW_SIMD_X86_AMD +# define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86 +# endif +# define BOOST_HW_SIMD_X86_AMD_AVAILABLE +#endif + +#define BOOST_HW_SIMD_X86_AMD_NAME "x86 (AMD) SIMD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_X86_AMD, BOOST_HW_SIMD_X86_AMD_NAME) diff --git a/src/boost/predef/hardware/simd/x86_amd/versions.h b/src/boost/predef/hardware/simd/x86_amd/versions.h new file mode 100644 index 00000000..aa54a5cb --- /dev/null +++ b/src/boost/predef/hardware/simd/x86_amd/versions.h @@ -0,0 +1,56 @@ +/* +Copyright Charly Chevalier 2015 +Copyright Joel Falcou 2015 +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) +*/ + +#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_VERSIONS_H +#define BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_VERSIONS_H + +#include + +/* tag::reference[] += `BOOST_HW_SIMD_X86_AMD_*_VERSION` + +Those defines represent x86 (AMD specific) SIMD extensions versions. + +NOTE: You *MUST* compare them with the predef `BOOST_HW_SIMD_X86_AMD`. +*/ // end::reference[] + + +// --------------------------------- + +/* tag::reference[] += `BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION` + +https://en.wikipedia.org/wiki/SSE4##SSE4A[SSE4A] x86 extension (AMD specific). + +Version number is: *4.0.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION BOOST_VERSION_NUMBER(4, 0, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_AMD_FMA4_VERSION` + +https://en.wikipedia.org/wiki/FMA_instruction_set#FMA4_instruction_set[FMA4] x86 extension (AMD specific). + +Version number is: *5.1.0*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_AMD_FMA4_VERSION BOOST_VERSION_NUMBER(5, 1, 0) + +/* tag::reference[] += `BOOST_HW_SIMD_X86_AMD_XOP_VERSION` + +https://en.wikipedia.org/wiki/XOP_instruction_set[XOP] x86 extension (AMD specific). + +Version number is: *5.1.1*. +*/ // end::reference[] +#define BOOST_HW_SIMD_X86_AMD_XOP_VERSION BOOST_VERSION_NUMBER(5, 1, 1) + +/* tag::reference[] + +*/ // end::reference[] + +#endif diff --git a/src/boost/predef/language.h b/src/boost/predef/language.h new file mode 100644 index 00000000..9ce3cc98 --- /dev/null +++ b/src/boost/predef/language.h @@ -0,0 +1,18 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#if !defined(BOOST_PREDEF_LANGUAGE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LANGUAGE_H +#define BOOST_PREDEF_LANGUAGE_H +#endif + +#include +#include +#include +#include + +#endif diff --git a/src/boost/predef/language/cuda.h b/src/boost/predef/language/cuda.h new file mode 100644 index 00000000..1159af49 --- /dev/null +++ b/src/boost/predef/language/cuda.h @@ -0,0 +1,53 @@ +/* +Copyright Benjamin Worpitz 2018 +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) +*/ + +#ifndef BOOST_PREDEF_LANGUAGE_CUDA_H +#define BOOST_PREDEF_LANGUAGE_CUDA_H + +#include +#include + +/* tag::reference[] += `BOOST_LANG_CUDA` + +https://en.wikipedia.org/wiki/CUDA[CUDA C/{CPP}] language. +If available, the version is detected as VV.RR.P. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__CUDACC__+` | {predef_detection} +| `+__CUDA__+` | {predef_detection} + +| `CUDA_VERSION` | VV.RR.P +|=== +*/ // end::reference[] + +#define BOOST_LANG_CUDA BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__CUDACC__) || defined(__CUDA__) +# undef BOOST_LANG_CUDA +# include +# if defined(CUDA_VERSION) +# define BOOST_LANG_CUDA BOOST_PREDEF_MAKE_10_VVRRP(CUDA_VERSION) +# else +# define BOOST_LANG_CUDA BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LANG_CUDA +# define BOOST_LANG_CUDA_AVAILABLE +#endif + +#define BOOST_LANG_CUDA_NAME "CUDA C/C++" + + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_CUDA,BOOST_LANG_CUDA_NAME) diff --git a/src/boost/predef/language/objc.h b/src/boost/predef/language/objc.h new file mode 100644 index 00000000..c521371d --- /dev/null +++ b/src/boost/predef/language/objc.h @@ -0,0 +1,43 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LANGUAGE_OBJC_H +#define BOOST_PREDEF_LANGUAGE_OBJC_H + +#include +#include + +/* tag::reference[] += `BOOST_LANG_OBJC` + +http://en.wikipedia.org/wiki/Objective-C[Objective-C] language. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__OBJC__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_LANG_OBJC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__OBJC__) +# undef BOOST_LANG_OBJC +# define BOOST_LANG_OBJC BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LANG_OBJC +# define BOOST_LANG_OBJC_AVAILABLE +#endif + +#define BOOST_LANG_OBJC_NAME "Objective-C" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_OBJC,BOOST_LANG_OBJC_NAME) diff --git a/src/boost/predef/language/stdc.h b/src/boost/predef/language/stdc.h new file mode 100644 index 00000000..8cbd6a10 --- /dev/null +++ b/src/boost/predef/language/stdc.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LANGUAGE_STDC_H +#define BOOST_PREDEF_LANGUAGE_STDC_H + +#include +#include + +/* tag::reference[] += `BOOST_LANG_STDC` + +http://en.wikipedia.org/wiki/C_(programming_language)[Standard C] language. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoch date. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__STDC__+` | {predef_detection} + +| `+__STDC_VERSION__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LANG_STDC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__STDC__) +# undef BOOST_LANG_STDC +# if defined(__STDC_VERSION__) +# if (__STDC_VERSION__ > 100) +# define BOOST_LANG_STDC BOOST_PREDEF_MAKE_YYYYMM(__STDC_VERSION__) +# else +# define BOOST_LANG_STDC BOOST_VERSION_NUMBER_AVAILABLE +# endif +# else +# define BOOST_LANG_STDC BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LANG_STDC +# define BOOST_LANG_STDC_AVAILABLE +#endif + +#define BOOST_LANG_STDC_NAME "Standard C" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDC,BOOST_LANG_STDC_NAME) diff --git a/src/boost/predef/language/stdcpp.h b/src/boost/predef/language/stdcpp.h new file mode 100644 index 00000000..daa14cfc --- /dev/null +++ b/src/boost/predef/language/stdcpp.h @@ -0,0 +1,128 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LANGUAGE_STDCPP_H +#define BOOST_PREDEF_LANGUAGE_STDCPP_H + +#include +#include + +/* tag::reference[] += `BOOST_LANG_STDCPP` + +http://en.wikipedia.org/wiki/C%2B%2B[Standard {CPP}] language. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoch date. +Because of the way the {CPP} standardization process works the +defined version year will not be the commonly known year of the standard. +Specifically the defined versions are: + +.Detected Version Number vs. {CPP} Standard Year +[options="header"] +|=== +| Detected Version Number | Standard Year | {CPP} Standard +| 27.11.1 | 1998 | ISO/IEC 14882:1998 +| 41.3.1 | 2011 | ISO/IEC 14882:2011 +| 44.2.1 | 2014 | ISO/IEC 14882:2014 +| 47.3.1 | 2017 | ISO/IEC 14882:2017 +|=== + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__cplusplus+` | {predef_detection} + +| `+__cplusplus+` | YYYY.MM.1 +|=== +*/ // end::reference[] + +#define BOOST_LANG_STDCPP BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__cplusplus) +# undef BOOST_LANG_STDCPP +# if (__cplusplus > 100) +# define BOOST_LANG_STDCPP BOOST_PREDEF_MAKE_YYYYMM(__cplusplus) +# else +# define BOOST_LANG_STDCPP BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LANG_STDCPP +# define BOOST_LANG_STDCPP_AVAILABLE +#endif + +#define BOOST_LANG_STDCPP_NAME "Standard C++" + +/* tag::reference[] += `BOOST_LANG_STDCPPCLI` + +http://en.wikipedia.org/wiki/C%2B%2B/CLI[Standard {CPP}/CLI] language. +If available, the year of the standard is detected as YYYY.MM.1 from the Epoch date. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__cplusplus_cli+` | {predef_detection} + +| `+__cplusplus_cli+` | YYYY.MM.1 +|=== +*/ // end::reference[] + +#define BOOST_LANG_STDCPPCLI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__cplusplus_cli) +# undef BOOST_LANG_STDCPPCLI +# if (__cplusplus_cli > 100) +# define BOOST_LANG_STDCPPCLI BOOST_PREDEF_MAKE_YYYYMM(__cplusplus_cli) +# else +# define BOOST_LANG_STDCPPCLI BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LANG_STDCPPCLI +# define BOOST_LANG_STDCPPCLI_AVAILABLE +#endif + +#define BOOST_LANG_STDCPPCLI_NAME "Standard C++/CLI" + +/* tag::reference[] += `BOOST_LANG_STDECPP` + +http://en.wikipedia.org/wiki/Embedded_C%2B%2B[Standard Embedded {CPP}] language. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__embedded_cplusplus+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_LANG_STDECPP BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__embedded_cplusplus) +# undef BOOST_LANG_STDECPP +# define BOOST_LANG_STDECPP BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LANG_STDECPP +# define BOOST_LANG_STDECPP_AVAILABLE +#endif + +#define BOOST_LANG_STDECPP_NAME "Standard Embedded C++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPP,BOOST_LANG_STDCPP_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPPCLI,BOOST_LANG_STDCPPCLI_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDECPP,BOOST_LANG_STDECPP_NAME) diff --git a/src/boost/predef/library.h b/src/boost/predef/library.h new file mode 100644 index 00000000..40518a90 --- /dev/null +++ b/src/boost/predef/library.h @@ -0,0 +1,16 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#if !defined(BOOST_PREDEF_LIBRARY_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LIBRARY_H +#define BOOST_PREDEF_LIBRARY_H +#endif + +#include +#include + +#endif diff --git a/src/boost/predef/library/c.h b/src/boost/predef/library/c.h new file mode 100644 index 00000000..7ca84cc0 --- /dev/null +++ b/src/boost/predef/library/c.h @@ -0,0 +1,21 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#if !defined(BOOST_PREDEF_LIBRARY_C_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LIBRARY_C_H +#define BOOST_PREDEF_LIBRARY_C_H +#endif + +#include + +#include +#include +#include +#include +#include + +#endif diff --git a/src/boost/predef/library/c/_prefix.h b/src/boost/predef/library/c/_prefix.h new file mode 100644 index 00000000..12bcb0fb --- /dev/null +++ b/src/boost/predef/library/c/_prefix.h @@ -0,0 +1,13 @@ +/* +Copyright Rene Rivera 2008-2013 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C__PREFIX_H +#define BOOST_PREDEF_LIBRARY_C__PREFIX_H + +#include + +#endif diff --git a/src/boost/predef/library/c/cloudabi.h b/src/boost/predef/library/c/cloudabi.h new file mode 100644 index 00000000..80ce81ca --- /dev/null +++ b/src/boost/predef/library/c/cloudabi.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 James E. King III + * + * 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) + */ + +#ifndef BOOST_PREDEF_LIBRARY_C_CLOUDABI_H +#define BOOST_PREDEF_LIBRARY_C_CLOUDABI_H + +#include +#include + +#include + +#if defined(__CloudABI__) +#include +#endif + +/* tag::reference[] += `BOOST_LIB_C_CLOUDABI` + +https://github.com/NuxiNL/cloudlibc[cloudlibc] - CloudABI's standard C library. +Version number available as major, and minor. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__cloudlibc__+` | {predef_detection} + +| `+__cloudlibc_major__+`, `+__cloudlibc_minor__+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_LIB_C_CLOUDABI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__cloudlibc__) +# undef BOOST_LIB_C_CLOUDABI +# define BOOST_LIB_C_CLOUDABI \ + BOOST_VERSION_NUMBER(__cloudlibc_major__,__cloudlibc_minor__,0) +#endif + +#if BOOST_LIB_C_CLOUDABI +# define BOOST_LIB_C_CLOUDABI_AVAILABLE +#endif + +#define BOOST_LIB_C_CLOUDABI_NAME "cloudlibc" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_CLOUDABI,BOOST_LIB_C_CLOUDABI_NAME) diff --git a/src/boost/predef/library/c/gnu.h b/src/boost/predef/library/c/gnu.h new file mode 100644 index 00000000..dd7a2052 --- /dev/null +++ b/src/boost/predef/library/c/gnu.h @@ -0,0 +1,62 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_GNU_H +#define BOOST_PREDEF_LIBRARY_C_GNU_H + +#include +#include + +#include + +#if defined(__STDC__) +#include +#elif defined(__cplusplus) +#include +#endif + +/* tag::reference[] += `BOOST_LIB_C_GNU` + +http://en.wikipedia.org/wiki/Glibc[GNU glibc] Standard C library. +Version number available as major, and minor. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__GLIBC__+` | {predef_detection} +| `+__GNU_LIBRARY__+` | {predef_detection} + +| `+__GLIBC__+`, `+__GLIBC_MINOR__+` | V.R.0 +| `+__GNU_LIBRARY__+`, `+__GNU_LIBRARY_MINOR__+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_LIB_C_GNU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) +# undef BOOST_LIB_C_GNU +# if defined(__GLIBC__) +# define BOOST_LIB_C_GNU \ + BOOST_VERSION_NUMBER(__GLIBC__,__GLIBC_MINOR__,0) +# else +# define BOOST_LIB_C_GNU \ + BOOST_VERSION_NUMBER(__GNU_LIBRARY__,__GNU_LIBRARY_MINOR__,0) +# endif +#endif + +#if BOOST_LIB_C_GNU +# define BOOST_LIB_C_GNU_AVAILABLE +#endif + +#define BOOST_LIB_C_GNU_NAME "GNU" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_GNU,BOOST_LIB_C_GNU_NAME) diff --git a/src/boost/predef/library/c/uc.h b/src/boost/predef/library/c/uc.h new file mode 100644 index 00000000..6eb22f0c --- /dev/null +++ b/src/boost/predef/library/c/uc.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_UC_H +#define BOOST_PREDEF_LIBRARY_C_UC_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_C_UC` + +http://en.wikipedia.org/wiki/Uclibc[uClibc] Standard C library. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__UCLIBC__+` | {predef_detection} + +| `+__UCLIBC_MAJOR__+`, `+__UCLIBC_MINOR__+`, `+__UCLIBC_SUBLEVEL__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_C_UC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__UCLIBC__) +# undef BOOST_LIB_C_UC +# define BOOST_LIB_C_UC BOOST_VERSION_NUMBER(\ + __UCLIBC_MAJOR__,__UCLIBC_MINOR__,__UCLIBC_SUBLEVEL__) +#endif + +#if BOOST_LIB_C_UC +# define BOOST_LIB_C_UC_AVAILABLE +#endif + +#define BOOST_LIB_C_UC_NAME "uClibc" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_UC,BOOST_LIB_C_UC_NAME) diff --git a/src/boost/predef/library/c/vms.h b/src/boost/predef/library/c/vms.h new file mode 100644 index 00000000..ca9050f8 --- /dev/null +++ b/src/boost/predef/library/c/vms.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_VMS_H +#define BOOST_PREDEF_LIBRARY_C_VMS_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_C_VMS` + +VMS libc Standard C library. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__CRTL_VER+` | {predef_detection} + +| `+__CRTL_VER+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_C_VMS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__CRTL_VER) +# undef BOOST_LIB_C_VMS +# define BOOST_LIB_C_VMS BOOST_PREDEF_MAKE_10_VVRR0PP00(__CRTL_VER) +#endif + +#if BOOST_LIB_C_VMS +# define BOOST_LIB_C_VMS_AVAILABLE +#endif + +#define BOOST_LIB_C_VMS_NAME "VMS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_VMS,BOOST_LIB_C_VMS_NAME) diff --git a/src/boost/predef/library/c/zos.h b/src/boost/predef/library/c/zos.h new file mode 100644 index 00000000..83907621 --- /dev/null +++ b/src/boost/predef/library/c/zos.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_C_ZOS_H +#define BOOST_PREDEF_LIBRARY_C_ZOS_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_C_ZOS` + +z/OS libc Standard C library. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__LIBREL__+` | {predef_detection} + +| `+__LIBREL__+` | V.R.P +| `+__TARGET_LIB__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_C_ZOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__LIBREL__) +# undef BOOST_LIB_C_ZOS +# if !defined(BOOST_LIB_C_ZOS) && defined(__LIBREL__) +# define BOOST_LIB_C_ZOS BOOST_PREDEF_MAKE_0X_VRRPPPP(__LIBREL__) +# endif +# if !defined(BOOST_LIB_C_ZOS) && defined(__TARGET_LIB__) +# define BOOST_LIB_C_ZOS BOOST_PREDEF_MAKE_0X_VRRPPPP(__TARGET_LIB__) +# endif +# if !defined(BOOST_LIB_C_ZOS) +# define BOOST_LIB_C_ZOS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_C_ZOS +# define BOOST_LIB_C_ZOS_AVAILABLE +#endif + +#define BOOST_LIB_C_ZOS_NAME "z/OS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_ZOS,BOOST_LIB_C_ZOS_NAME) diff --git a/src/boost/predef/library/std.h b/src/boost/predef/library/std.h new file mode 100644 index 00000000..f8d34b45 --- /dev/null +++ b/src/boost/predef/library/std.h @@ -0,0 +1,26 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ +#if !defined(BOOST_PREDEF_LIBRARY_STD_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_LIBRARY_STD_H +#define BOOST_PREDEF_LIBRARY_STD_H +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/src/boost/predef/library/std/_prefix.h b/src/boost/predef/library/std/_prefix.h new file mode 100644 index 00000000..932b8557 --- /dev/null +++ b/src/boost/predef/library/std/_prefix.h @@ -0,0 +1,23 @@ +/* +Copyright Rene Rivera 2008-2013 +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) +*/ +#ifndef BOOST_PREDEF_LIBRARY_STD__PREFIX_H +#define BOOST_PREDEF_LIBRARY_STD__PREFIX_H + +/* +We need to include an STD header to gives us the context +of which library we are using. The "smallest" code-wise header +seems to be . Boost uses but as far +as I can tell (RR) it's not a stand-alone header in most +implementations. Using also has the benefit of +being available in EC++, so we get a chance to make this work +for embedded users. And since it's not a header impacted by TR1 +there's no magic needed for inclusion in the face of the +Boost.TR1 library. +*/ +#include + +#endif diff --git a/src/boost/predef/library/std/cxx.h b/src/boost/predef/library/std/cxx.h new file mode 100644 index 00000000..470c80da --- /dev/null +++ b/src/boost/predef/library/std/cxx.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_CXX_H +#define BOOST_PREDEF_LIBRARY_STD_CXX_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_CXX` + +http://libcxx.llvm.org/[libc++] {CPP} Standard Library. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_LIBCPP_VERSION+` | {predef_detection} + +| `+_LIBCPP_VERSION+` | V.0.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_CXX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_LIBCPP_VERSION) +# undef BOOST_LIB_STD_CXX +# define BOOST_LIB_STD_CXX BOOST_PREDEF_MAKE_10_VVPPP(_LIBCPP_VERSION) +#endif + +#if BOOST_LIB_STD_CXX +# define BOOST_LIB_STD_CXX_AVAILABLE +#endif + +#define BOOST_LIB_STD_CXX_NAME "libc++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_CXX,BOOST_LIB_STD_CXX_NAME) diff --git a/src/boost/predef/library/std/dinkumware.h b/src/boost/predef/library/std/dinkumware.h new file mode 100644 index 00000000..5a4bc57a --- /dev/null +++ b/src/boost/predef/library/std/dinkumware.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H +#define BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_DINKUMWARE` + +http://en.wikipedia.org/wiki/Dinkumware[Dinkumware] Standard {CPP} Library. +If available version number as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_YVALS+`, `+__IBMCPP__+` | {predef_detection} +| `+_CPPLIB_VER+` | {predef_detection} + +| `+_CPPLIB_VER+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +# undef BOOST_LIB_STD_DINKUMWARE +# if defined(_CPPLIB_VER) +# define BOOST_LIB_STD_DINKUMWARE BOOST_PREDEF_MAKE_10_VVRR(_CPPLIB_VER) +# else +# define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_STD_DINKUMWARE +# define BOOST_LIB_STD_DINKUMWARE_AVAILABLE +#endif + +#define BOOST_LIB_STD_DINKUMWARE_NAME "Dinkumware" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_DINKUMWARE,BOOST_LIB_STD_DINKUMWARE_NAME) diff --git a/src/boost/predef/library/std/libcomo.h b/src/boost/predef/library/std/libcomo.h new file mode 100644 index 00000000..a2116c85 --- /dev/null +++ b/src/boost/predef/library/std/libcomo.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_LIBCOMO_H +#define BOOST_PREDEF_LIBRARY_STD_LIBCOMO_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_COMO` + +http://www.comeaucomputing.com/libcomo/[Comeau Computing] Standard {CPP} Library. +Version number available as major. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__LIBCOMO__+` | {predef_detection} + +| `+__LIBCOMO_VERSION__+` | V.0.0 +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_COMO BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__LIBCOMO__) +# undef BOOST_LIB_STD_COMO +# define BOOST_LIB_STD_COMO BOOST_VERSION_NUMBER(__LIBCOMO_VERSION__,0,0) +#endif + +#if BOOST_LIB_STD_COMO +# define BOOST_LIB_STD_COMO_AVAILABLE +#endif + +#define BOOST_LIB_STD_COMO_NAME "Comeau Computing" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_COMO,BOOST_LIB_STD_COMO_NAME) diff --git a/src/boost/predef/library/std/modena.h b/src/boost/predef/library/std/modena.h new file mode 100644 index 00000000..4ce1cfcd --- /dev/null +++ b/src/boost/predef/library/std/modena.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_MODENA_H +#define BOOST_PREDEF_LIBRARY_STD_MODENA_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_MSIPL` + +http://modena.us/[Modena Software Lib++] Standard {CPP} Library. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `MSIPL_COMPILE_H` | {predef_detection} +| `+__MSIPL_COMPILE_H+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_MSIPL BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(MSIPL_COMPILE_H) || defined(__MSIPL_COMPILE_H) +# undef BOOST_LIB_STD_MSIPL +# define BOOST_LIB_STD_MSIPL BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LIB_STD_MSIPL +# define BOOST_LIB_STD_MSIPL_AVAILABLE +#endif + +#define BOOST_LIB_STD_MSIPL_NAME "Modena Software Lib++" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSIPL,BOOST_LIB_STD_MSIPL_NAME) diff --git a/src/boost/predef/library/std/msl.h b/src/boost/predef/library/std/msl.h new file mode 100644 index 00000000..932da795 --- /dev/null +++ b/src/boost/predef/library/std/msl.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_MSL_H +#define BOOST_PREDEF_LIBRARY_STD_MSL_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_MSL` + +http://www.freescale.com/[Metrowerks] Standard {CPP} Library. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__MSL_CPP__+` | {predef_detection} +| `+__MSL__+` | {predef_detection} + +| `+__MSL_CPP__+` | V.R.P +| `+__MSL__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_MSL BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MSL_CPP__) || defined(__MSL__) +# undef BOOST_LIB_STD_MSL +# if defined(__MSL_CPP__) +# define BOOST_LIB_STD_MSL BOOST_PREDEF_MAKE_0X_VRPP(__MSL_CPP__) +# else +# define BOOST_LIB_STD_MSL BOOST_PREDEF_MAKE_0X_VRPP(__MSL__) +# endif +#endif + +#if BOOST_LIB_STD_MSL +# define BOOST_LIB_STD_MSL_AVAILABLE +#endif + +#define BOOST_LIB_STD_MSL_NAME "Metrowerks" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSL,BOOST_LIB_STD_MSL_NAME) diff --git a/src/boost/predef/library/std/msvc.h b/src/boost/predef/library/std/msvc.h new file mode 100644 index 00000000..de336626 --- /dev/null +++ b/src/boost/predef/library/std/msvc.h @@ -0,0 +1,53 @@ +/* +Copyright Henrik S. Gaßmann 2023 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_MSVC_H +#define BOOST_PREDEF_LIBRARY_STD_MSVC_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_MSVC` + +https://github.com/microsoft/STL[Microsoft's {CPP} Standard Library]. +If available version number as major, minor, and patch. +The patch number is derived from `_MSVC_STL_UPDATE` by taking its five last +digits (see below). This implies that pasting a `_MSVC_STL_UPDATE` value into +`BOOST_VERSION_NUMBER` will produce a version number that is directly comparable +to `BOOST_LIB_STD_MSVC`. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_MSVC_STL_VERSION+` | {predef_detection} + +| `+_MSVC_STL_VERSION+` | VV.R.0 +| `+_MSVC_STL_UPDATE+` | 00.0.0YYYMM +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_MSVC BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(_MSVC_STL_VERSION) +# undef BOOST_LIB_STD_MSVC +# define BOOST_LIB_STD_MSVC BOOST_PREDEF_MAKE_10_VVR_0PPPPP(_MSVC_STL_VERSION, _MSVC_STL_UPDATE) +#endif + +#if BOOST_LIB_STD_MSVC +# define BOOST_LIB_STD_MSVC_AVAILABLE +#endif + +#define BOOST_LIB_STD_MSVC_NAME "Microsoft stdlib" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSVC, BOOST_LIB_STD_MSVC_NAME) diff --git a/src/boost/predef/library/std/roguewave.h b/src/boost/predef/library/std/roguewave.h new file mode 100644 index 00000000..c64cb061 --- /dev/null +++ b/src/boost/predef/library/std/roguewave.h @@ -0,0 +1,57 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_ROGUEWAVE_H +#define BOOST_PREDEF_LIBRARY_STD_ROGUEWAVE_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_RW` + +http://stdcxx.apache.org/[Roguewave] Standard {CPP} library. +If available version number as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__STD_RWCOMPILER_H__+` | {predef_detection} +| `+_RWSTD_VER+` | {predef_detection} + +| `+_RWSTD_VER+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_RW BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +# undef BOOST_LIB_STD_RW +# if defined(_RWSTD_VER) +# if _RWSTD_VER < 0x010000 +# define BOOST_LIB_STD_RW BOOST_PREDEF_MAKE_0X_VVRRP(_RWSTD_VER) +# else +# define BOOST_LIB_STD_RW BOOST_PREDEF_MAKE_0X_VVRRPP(_RWSTD_VER) +# endif +# else +# define BOOST_LIB_STD_RW BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_STD_RW +# define BOOST_LIB_STD_RW_AVAILABLE +#endif + +#define BOOST_LIB_STD_RW_NAME "Roguewave" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_RW,BOOST_LIB_STD_RW_NAME) diff --git a/src/boost/predef/library/std/sgi.h b/src/boost/predef/library/std/sgi.h new file mode 100644 index 00000000..3d11dd43 --- /dev/null +++ b/src/boost/predef/library/std/sgi.h @@ -0,0 +1,52 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_SGI_H +#define BOOST_PREDEF_LIBRARY_STD_SGI_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_SGI` + +http://www.sgi.com/tech/stl/[SGI] Standard {CPP} library. +If available version number as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__STL_CONFIG_H+` | {predef_detection} + +| `+__SGI_STL+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_SGI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__STL_CONFIG_H) +# undef BOOST_LIB_STD_SGI +# if defined(__SGI_STL) +# define BOOST_LIB_STD_SGI BOOST_PREDEF_MAKE_0X_VRP(__SGI_STL) +# else +# define BOOST_LIB_STD_SGI BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_LIB_STD_SGI +# define BOOST_LIB_STD_SGI_AVAILABLE +#endif + +#define BOOST_LIB_STD_SGI_NAME "SGI" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_SGI,BOOST_LIB_STD_SGI_NAME) diff --git a/src/boost/predef/library/std/stdcpp3.h b/src/boost/predef/library/std/stdcpp3.h new file mode 100644 index 00000000..90aa3d18 --- /dev/null +++ b/src/boost/predef/library/std/stdcpp3.h @@ -0,0 +1,54 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_STDCPP3_H +#define BOOST_PREDEF_LIBRARY_STD_STDCPP3_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_GNU` + +https://gcc.gnu.org/onlinedocs/libstdc%2b%2b/[GNU libstdc++] Standard {CPP} library. +Version number available as year (from 1970), month, and day. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__GLIBCXX__+` | {predef_detection} +| `+__GLIBCPP__+` | {predef_detection} + +| `+__GLIBCXX__+` | V.R.P +| `+__GLIBCPP__+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_GNU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__GLIBCPP__) || defined(__GLIBCXX__) +# undef BOOST_LIB_STD_GNU +# if defined(__GLIBCXX__) +# define BOOST_LIB_STD_GNU BOOST_PREDEF_MAKE_YYYYMMDD(__GLIBCXX__) +# else +# define BOOST_LIB_STD_GNU BOOST_PREDEF_MAKE_YYYYMMDD(__GLIBCPP__) +# endif +#endif + +#if BOOST_LIB_STD_GNU +# define BOOST_LIB_STD_GNU_AVAILABLE +#endif + +#define BOOST_LIB_STD_GNU_NAME "GNU" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_GNU,BOOST_LIB_STD_GNU_NAME) diff --git a/src/boost/predef/library/std/stlport.h b/src/boost/predef/library/std/stlport.h new file mode 100644 index 00000000..9d7f14f8 --- /dev/null +++ b/src/boost/predef/library/std/stlport.h @@ -0,0 +1,60 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_STLPORT_H +#define BOOST_PREDEF_LIBRARY_STD_STLPORT_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_STLPORT` + +http://sourceforge.net/projects/stlport/[STLport Standard {CPP}] library. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__SGI_STL_PORT+` | {predef_detection} +| `+_STLPORT_VERSION+` | {predef_detection} + +| `+_STLPORT_MAJOR+`, `+_STLPORT_MINOR+`, `+_STLPORT_PATCHLEVEL+` | V.R.P +| `+_STLPORT_VERSION+` | V.R.P +| `+__SGI_STL_PORT+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_STLPORT BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +# undef BOOST_LIB_STD_STLPORT +# if !defined(BOOST_LIB_STD_STLPORT) && defined(_STLPORT_MAJOR) +# define BOOST_LIB_STD_STLPORT \ + BOOST_VERSION_NUMBER(_STLPORT_MAJOR,_STLPORT_MINOR,_STLPORT_PATCHLEVEL) +# endif +# if !defined(BOOST_LIB_STD_STLPORT) && defined(_STLPORT_VERSION) +# define BOOST_LIB_STD_STLPORT BOOST_PREDEF_MAKE_0X_VRP(_STLPORT_VERSION) +# endif +# if !defined(BOOST_LIB_STD_STLPORT) +# define BOOST_LIB_STD_STLPORT BOOST_PREDEF_MAKE_0X_VRP(__SGI_STL_PORT) +# endif +#endif + +#if BOOST_LIB_STD_STLPORT +# define BOOST_LIB_STD_STLPORT_AVAILABLE +#endif + +#define BOOST_LIB_STD_STLPORT_NAME "STLport" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_STLPORT,BOOST_LIB_STD_STLPORT_NAME) diff --git a/src/boost/predef/library/std/vacpp.h b/src/boost/predef/library/std/vacpp.h new file mode 100644 index 00000000..6165feff --- /dev/null +++ b/src/boost/predef/library/std/vacpp.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_LIBRARY_STD_VACPP_H +#define BOOST_PREDEF_LIBRARY_STD_VACPP_H + +#include + +#include +#include + +/* tag::reference[] += `BOOST_LIB_STD_IBM` + +http://www.ibm.com/software/awdtools/xlcpp/[IBM VACPP Standard {CPP}] library. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__IBMCPP__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_LIB_STD_IBM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__IBMCPP__) +# undef BOOST_LIB_STD_IBM +# define BOOST_LIB_STD_IBM BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_LIB_STD_IBM +# define BOOST_LIB_STD_IBM_AVAILABLE +#endif + +#define BOOST_LIB_STD_IBM_NAME "IBM VACPP" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_IBM,BOOST_LIB_STD_IBM_NAME) diff --git a/src/boost/predef/make.h b/src/boost/predef/make.h new file mode 100644 index 00000000..c2aa8748 --- /dev/null +++ b/src/boost/predef/make.h @@ -0,0 +1,167 @@ +/* +Copyright Rene Rivera 2008-2015 +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 + +#ifndef BOOST_PREDEF_MAKE_H +#define BOOST_PREDEF_MAKE_H + +/* +Shorthands for the common version number formats used by vendors... +*/ + +/* tag::reference[] += `BOOST_PREDEF_MAKE_..` macros + +These set of macros decompose common vendor version number +macros which are composed version, revision, and patch digits. +The naming convention indicates: + +* The base of the specified version number. "`BOOST_PREDEF_MAKE_0X`" for + hexadecimal digits, and "`BOOST_PREDEF_MAKE_10`" for decimal digits. +* The format of the vendor version number. Where "`V`" indicates the version digits, + "`R`" indicates the revision digits, "`P`" indicates the patch digits, and "`0`" + indicates an ignored digit. + +Macros are: + +*/ // end::reference[] +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VRP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VRP(V) BOOST_VERSION_NUMBER((V&0xF00)>>8,(V&0xF0)>>4,(V&0xF)) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VVRP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VVRP(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xF0)>>4,(V&0xF)) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VRPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VRPP(V) BOOST_VERSION_NUMBER((V&0xF000)>>12,(V&0xF00)>>8,(V&0xFF)) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VVRR(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VVRR(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xFF),0) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VRRPPPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VRRPPPP(V) BOOST_VERSION_NUMBER((V&0xF000000)>>24,(V&0xFF0000)>>16,(V&0xFFFF)) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VVRRP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VVRRP(V) BOOST_VERSION_NUMBER((V&0xFF000)>>12,(V&0xFF0)>>4,(V&0xF)) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VRRPP000(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VRRPP000(V) BOOST_VERSION_NUMBER((V&0xF0000000)>>28,(V&0xFF00000)>>20,(V&0xFF000)>>12) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_0X_VVRRPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_0X_VVRRPP(V) BOOST_VERSION_NUMBER((V&0xFF0000)>>16,(V&0xFF00)>>8,(V&0xFF)) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VPPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,0,(V)%1000) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVPPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%100,0,(V)%1000) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VR0(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VR0(V) BOOST_VERSION_NUMBER(((V)/100)%10,((V)/10)%10,0) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VRP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VRP(V) BOOST_VERSION_NUMBER(((V)/100)%10,((V)/10)%10,(V)%10) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VRP000(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VRP000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/10000)%10,((V)/1000)%10) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VRPPPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VRPPPP(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/10000)%10,(V)%10000) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VRPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VRPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,((V)/100)%10,(V)%100) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VRR(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VRR(V) BOOST_VERSION_NUMBER(((V)/100)%10,(V)%100,0) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VRRPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%10,((V)/100)%100,(V)%100) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VRR000(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VRR000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/1000)%100,0) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VV00(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VV00(V) BOOST_VERSION_NUMBER(((V)/100)%100,0,0) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVR_0PPPPP(V, P)`, the second parameter specifies a year-month patch level with the first digit discarded +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVR_0PPPPP(V, P) BOOST_VERSION_NUMBER(((V)/10)%100,(V)%10,(P)%100000) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVRR(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVRR(V) BOOST_VERSION_NUMBER(((V)/100)%100,(V)%100,0) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVRRP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVRRP(V) BOOST_VERSION_NUMBER(((V)/1000)%100,((V)/10)%100,(V)%10) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVRRPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%100,((V)/100)%100,(V)%100) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVRRPPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVRRPPP(V) BOOST_VERSION_NUMBER(((V)/100000)%100,((V)/1000)%100,(V)%1000) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVRR0PP00(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVRR0PP00(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,((V)/100)%100) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVRR0PPPP(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVRR0PPPP(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,(V)%10000) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_10_VVRR00PP00(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_10_VVRR00PP00(V) BOOST_VERSION_NUMBER(((V)/100000000)%100,((V)/1000000)%100,((V)/100)%100) + +/* tag::reference[] + += `BOOST_PREDEF_MAKE_*..` date macros + +Date decomposition macros return a date in the relative to the 1970 +Epoch date. If the month is not available, January 1st is used as the month and day. +If the day is not available, but the month is, the 1st of the month is used as the day. + +*/ // end::reference[] +/* tag::reference[] +* `BOOST_PREDEF_MAKE_DATE(Y,M,D)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_DATE(Y,M,D) BOOST_VERSION_NUMBER((Y)%10000-1970,(M)%100,(D)%100) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_YYYYMMDD(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_YYYYMMDD(V) BOOST_PREDEF_MAKE_DATE(((V)/10000)%10000,((V)/100)%100,(V)%100) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_YYYY(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_YYYY(V) BOOST_PREDEF_MAKE_DATE(V,1,1) +/* tag::reference[] +* `BOOST_PREDEF_MAKE_YYYYMM(V)` +*/ // end::reference[] +#define BOOST_PREDEF_MAKE_YYYYMM(V) BOOST_PREDEF_MAKE_DATE((V)/100,(V)%100,1) + +#endif diff --git a/src/boost/predef/os.h b/src/boost/predef/os.h new file mode 100644 index 00000000..da28e1c4 --- /dev/null +++ b/src/boost/predef/os.h @@ -0,0 +1,32 @@ +/* +Copyright Rene Rivera 2008-2015 +Copyright Franz Detro 2014 +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) +*/ + +#if !defined(BOOST_PREDEF_OS_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_OS_H +#define BOOST_PREDEF_OS_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/src/boost/predef/os/aix.h b/src/boost/predef/os/aix.h new file mode 100644 index 00000000..9bfe740c --- /dev/null +++ b/src/boost/predef/os/aix.h @@ -0,0 +1,67 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_AIX_H +#define BOOST_PREDEF_OS_AIX_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_AIX` + +http://en.wikipedia.org/wiki/AIX_operating_system[IBM AIX] operating system. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_AIX+` | {predef_detection} +| `+__TOS_AIX__+` | {predef_detection} + +| `+_AIX43+` | 4.3.0 +| `+_AIX41+` | 4.1.0 +| `+_AIX32+` | 3.2.0 +| `+_AIX3+` | 3.0.0 +|=== +*/ // end::reference[] + +#define BOOST_OS_AIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(_AIX) || defined(__TOS_AIX__) \ + ) +# undef BOOST_OS_AIX +# if !defined(BOOST_OS_AIX) && defined(_AIX43) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX41) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,1,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX32) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX3) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_OS_AIX) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_AIX +# define BOOST_OS_AIX_AVAILABLE +# include +#endif + +#define BOOST_OS_AIX_NAME "IBM AIX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AIX,BOOST_OS_AIX_NAME) diff --git a/src/boost/predef/os/amigaos.h b/src/boost/predef/os/amigaos.h new file mode 100644 index 00000000..c6a1f71a --- /dev/null +++ b/src/boost/predef/os/amigaos.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_AMIGAOS_H +#define BOOST_PREDEF_OS_AMIGAOS_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_AMIGAOS` + +http://en.wikipedia.org/wiki/AmigaOS[AmigaOS] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `AMIGA` | {predef_detection} +| `+__amigaos__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(AMIGA) || defined(__amigaos__) \ + ) +# undef BOOST_OS_AMIGAOS +# define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_AMIGAOS +# define BOOST_OS_AMIGAOS_AVAILABLE +# include +#endif + +#define BOOST_OS_AMIGAOS_NAME "AmigaOS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AMIGAOS,BOOST_OS_AMIGAOS_NAME) diff --git a/src/boost/predef/os/beos.h b/src/boost/predef/os/beos.h new file mode 100644 index 00000000..8f764875 --- /dev/null +++ b/src/boost/predef/os/beos.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_BEOS_H +#define BOOST_PREDEF_OS_BEOS_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_BEOS` + +http://en.wikipedia.org/wiki/BeOS[BeOS] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__BEOS__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_BEOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__BEOS__) \ + ) +# undef BOOST_OS_BEOS +# define BOOST_OS_BEOS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_BEOS +# define BOOST_OS_BEOS_AVAILABLE +# include +#endif + +#define BOOST_OS_BEOS_NAME "BeOS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BEOS,BOOST_OS_BEOS_NAME) diff --git a/src/boost/predef/os/bsd.h b/src/boost/predef/os/bsd.h new file mode 100644 index 00000000..528a5972 --- /dev/null +++ b/src/boost/predef/os/bsd.h @@ -0,0 +1,102 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_H +#define BOOST_PREDEF_OS_BSD_H + +/* Special case: OSX will define BSD predefs if the sys/param.h + * header is included. We can guard against that, but only if we + * detect OSX first. Hence we will force include OSX detection + * before doing any BSD detection. + */ +#include + +#include +#include + +/* tag::reference[] += `BOOST_OS_BSD` + +http://en.wikipedia.org/wiki/Berkeley_Software_Distribution[BSD] operating system. + +BSD has various branch operating systems possible and each detected +individually. This detects the following variations and sets a specific +version number macro to match: + +* `BOOST_OS_BSD_DRAGONFLY` http://en.wikipedia.org/wiki/DragonFly_BSD[DragonFly BSD] +* `BOOST_OS_BSD_FREE` http://en.wikipedia.org/wiki/Freebsd[FreeBSD] +* `BOOST_OS_BSD_BSDI` http://en.wikipedia.org/wiki/BSD/OS[BSDi BSD/OS] +* `BOOST_OS_BSD_NET` http://en.wikipedia.org/wiki/Netbsd[NetBSD] +* `BOOST_OS_BSD_OPEN` http://en.wikipedia.org/wiki/Openbsd[OpenBSD] + +NOTE: The general `BOOST_OS_BSD` is set in all cases to indicate some form +of BSD. If the above variants is detected the corresponding macro is also set. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `BSD` | {predef_detection} +| `+_SYSTYPE_BSD+` | {predef_detection} + +| `BSD4_2` | 4.2.0 +| `BSD4_3` | 4.3.0 +| `BSD4_4` | 4.4.0 +| `BSD` | V.R.0 +|=== +*/ // end::reference[] + +#include +#include +#include +#include +#include + +#ifndef BOOST_OS_BSD +#define BOOST_OS_BSD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#endif + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(BSD) || \ + defined(_SYSTYPE_BSD) \ + ) +# undef BOOST_OS_BSD +# include +# if !defined(BOOST_OS_BSD) && defined(BSD4_4) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_3) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_2) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD) +# define BOOST_OS_BSD BOOST_PREDEF_MAKE_10_VVRR(BSD) +# endif +# if !defined(BOOST_OS_BSD) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD +# define BOOST_OS_BSD_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_NAME "BSD" + +#endif + +#include +#include +#include +#include +#include + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD,BOOST_OS_BSD_NAME) diff --git a/src/boost/predef/os/bsd/bsdi.h b/src/boost/predef/os/bsd/bsdi.h new file mode 100644 index 00000000..d0a5dcd9 --- /dev/null +++ b/src/boost/predef/os/bsd/bsdi.h @@ -0,0 +1,50 @@ +/* +Copyright Rene Rivera 2012-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_BSDI_H +#define BOOST_PREDEF_OS_BSD_BSDI_H + +#include + +/* tag::reference[] += `BOOST_OS_BSD_BSDI` + +http://en.wikipedia.org/wiki/BSD/OS[BSDi BSD/OS] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__bsdi__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__bsdi__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_BSDI_NAME "BSDi BSD/OS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_BSDI,BOOST_OS_BSD_BSDI_NAME) diff --git a/src/boost/predef/os/bsd/dragonfly.h b/src/boost/predef/os/bsd/dragonfly.h new file mode 100644 index 00000000..43207779 --- /dev/null +++ b/src/boost/predef/os/bsd/dragonfly.h @@ -0,0 +1,52 @@ +/* +Copyright Rene Rivera 2012-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_DRAGONFLY_H +#define BOOST_PREDEF_OS_BSD_DRAGONFLY_H + +#include + +/* tag::reference[] += `BOOST_OS_BSD_DRAGONFLY` + +http://en.wikipedia.org/wiki/DragonFly_BSD[DragonFly BSD] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__DragonFly__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_BSD_DRAGONFLY BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__DragonFly__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_DRAGONFLY +# if defined(__DragonFly__) +# define BOOST_OS_DRAGONFLY_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_DRAGONFLY +# define BOOST_OS_BSD_DRAGONFLY_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_DRAGONFLY_NAME "DragonFly BSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_DRAGONFLY,BOOST_OS_BSD_DRAGONFLY_NAME) diff --git a/src/boost/predef/os/bsd/free.h b/src/boost/predef/os/bsd/free.h new file mode 100644 index 00000000..4098b3a3 --- /dev/null +++ b/src/boost/predef/os/bsd/free.h @@ -0,0 +1,69 @@ +/* +Copyright Rene Rivera 2012-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_FREE_H +#define BOOST_PREDEF_OS_BSD_FREE_H + +#include + +/* tag::reference[] += `BOOST_OS_BSD_FREE` + +http://en.wikipedia.org/wiki/Freebsd[FreeBSD] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__FreeBSD__+` | {predef_detection} + +| `+__FreeBSD_version+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__FreeBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_FREE +# include +# if defined(__FreeBSD_version) +# if __FreeBSD_version == 491000 +# define BOOST_OS_BSD_FREE \ + BOOST_VERSION_NUMBER(4, 10, 0) +# elif __FreeBSD_version == 492000 +# define BOOST_OS_BSD_FREE \ + BOOST_VERSION_NUMBER(4, 11, 0) +# elif __FreeBSD_version < 500000 +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VRPPPP(__FreeBSD_version) +# else +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VVRRPPP(__FreeBSD_version) +# endif +# else +# define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_FREE +# define BOOST_OS_BSD_FREE_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_FREE_NAME "Free BSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_FREE,BOOST_OS_BSD_FREE_NAME) diff --git a/src/boost/predef/os/bsd/net.h b/src/boost/predef/os/bsd/net.h new file mode 100644 index 00000000..537f16a1 --- /dev/null +++ b/src/boost/predef/os/bsd/net.h @@ -0,0 +1,86 @@ +/* +Copyright Rene Rivera 2012-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_NET_H +#define BOOST_PREDEF_OS_BSD_NET_H + +#include + +/* tag::reference[] += `BOOST_OS_BSD_NET` + +http://en.wikipedia.org/wiki/Netbsd[NetBSD] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__NETBSD__+` | {predef_detection} +| `+__NetBSD__+` | {predef_detection} + +| `+__NETBSD_version+` | V.R.P +| `NetBSD0_8` | 0.8.0 +| `NetBSD0_9` | 0.9.0 +| `NetBSD1_0` | 1.0.0 +| `+__NetBSD_Version+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__NETBSD__) || defined(__NetBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_NET +# if defined(__NETBSD__) +# if defined(__NETBSD_version) +# if __NETBSD_version < 500000 +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRP000(__NETBSD_version) +# else +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRR000(__NETBSD_version) +# endif +# else +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# elif defined(__NetBSD__) +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_8) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,8,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_9) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,9,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD1_0) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(__NetBSD_Version) +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VVRR00PP00(__NetBSD_Version) +# endif +# if !defined(BOOST_OS_BSD_NET) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +#if BOOST_OS_BSD_NET +# define BOOST_OS_BSD_NET_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_NET_NAME "NetBSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_NET,BOOST_OS_BSD_NET_NAME) diff --git a/src/boost/predef/os/bsd/open.h b/src/boost/predef/os/bsd/open.h new file mode 100644 index 00000000..34f0a71a --- /dev/null +++ b/src/boost/predef/os/bsd/open.h @@ -0,0 +1,253 @@ +/* +Copyright Rene Rivera 2012-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_OPEN_H +#define BOOST_PREDEF_OS_BSD_OPEN_H + +#include + +/* tag::reference[] += `BOOST_OS_BSD_OPEN` + +http://en.wikipedia.org/wiki/Openbsd[OpenBSD] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__OpenBSD__+` | {predef_detection} + +| `OpenBSD2_0` | 2.0.0 +| `OpenBSD2_1` | 2.1.0 +| `OpenBSD2_2` | 2.2.0 +| `OpenBSD2_3` | 2.3.0 +| `OpenBSD2_4` | 2.4.0 +| `OpenBSD2_5` | 2.5.0 +| `OpenBSD2_6` | 2.6.0 +| `OpenBSD2_7` | 2.7.0 +| `OpenBSD2_8` | 2.8.0 +| `OpenBSD2_9` | 2.9.0 +| `OpenBSD3_0` | 3.0.0 +| `OpenBSD3_1` | 3.1.0 +| `OpenBSD3_2` | 3.2.0 +| `OpenBSD3_3` | 3.3.0 +| `OpenBSD3_4` | 3.4.0 +| `OpenBSD3_5` | 3.5.0 +| `OpenBSD3_6` | 3.6.0 +| `OpenBSD3_7` | 3.7.0 +| `OpenBSD3_8` | 3.8.0 +| `OpenBSD3_9` | 3.9.0 +| `OpenBSD4_0` | 4.0.0 +| `OpenBSD4_1` | 4.1.0 +| `OpenBSD4_2` | 4.2.0 +| `OpenBSD4_3` | 4.3.0 +| `OpenBSD4_4` | 4.4.0 +| `OpenBSD4_5` | 4.5.0 +| `OpenBSD4_6` | 4.6.0 +| `OpenBSD4_7` | 4.7.0 +| `OpenBSD4_8` | 4.8.0 +| `OpenBSD4_9` | 4.9.0 +| `OpenBSD5_0` | 5.0.0 +| `OpenBSD5_1` | 5.1.0 +| `OpenBSD5_2` | 5.2.0 +| `OpenBSD5_3` | 5.3.0 +| `OpenBSD5_4` | 5.4.0 +| `OpenBSD5_5` | 5.5.0 +| `OpenBSD5_6` | 5.6.0 +| `OpenBSD5_7` | 5.7.0 +| `OpenBSD5_8` | 5.8.0 +| `OpenBSD5_9` | 5.9.0 +| `OpenBSD6_0` | 6.0.0 +| `OpenBSD6_1` | 6.1.0 +| `OpenBSD6_2` | 6.2.0 +| `OpenBSD6_3` | 6.3.0 +| `OpenBSD6_4` | 6.4.0 +| `OpenBSD6_5` | 6.5.0 +| `OpenBSD6_6` | 6.6.0 +| `OpenBSD6_7` | 6.7.0 +| `OpenBSD6_8` | 6.8.0 +| `OpenBSD6_9` | 6.9.0 +|=== +*/ // end::reference[] + +#define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__OpenBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# undef BOOST_OS_BSD +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_OPEN +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD5_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(5,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD6_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(6,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_OPEN +# define BOOST_OS_BSD_OPEN_AVAILABLE +# include +#endif + +#define BOOST_OS_BSD_OPEN_NAME "OpenBSD" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_OPEN,BOOST_OS_BSD_OPEN_NAME) diff --git a/src/boost/predef/os/cygwin.h b/src/boost/predef/os/cygwin.h new file mode 100644 index 00000000..3ca73d26 --- /dev/null +++ b/src/boost/predef/os/cygwin.h @@ -0,0 +1,51 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_CYGWIN_H +#define BOOST_PREDEF_OS_CYGWIN_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_CYGWIN` + +http://en.wikipedia.org/wiki/Cygwin[Cygwin] evironment. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__CYGWIN__+` | {predef_detection} + +| `CYGWIN_VERSION_API_MAJOR`, `CYGWIN_VERSION_API_MINOR` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_OS_CYGWIN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__CYGWIN__) \ + ) +# include +# undef BOOST_OS_CYGWIN +# define BOOST_OS_CYGWIN \ + BOOST_VERSION_NUMBER(CYGWIN_VERSION_API_MAJOR,\ + CYGWIN_VERSION_API_MINOR, 0) +#endif + +#if BOOST_OS_CYGWIN +# define BOOST_OS_CYGWIN_AVAILABLE +# include +#endif + +#define BOOST_OS_CYGWIN_NAME "Cygwin" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_CYGWIN,BOOST_OS_CYGWIN_NAME) diff --git a/src/boost/predef/os/haiku.h b/src/boost/predef/os/haiku.h new file mode 100644 index 00000000..4ae31583 --- /dev/null +++ b/src/boost/predef/os/haiku.h @@ -0,0 +1,47 @@ +/* +Copyright Jessica Hamilton 2014 +Copyright Rene Rivera 2014-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_HAIKU_H +#define BOOST_PREDEF_OS_HAIKU_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_HAIKU` + +http://en.wikipedia.org/wiki/Haiku_(operating_system)[Haiku] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__HAIKU__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__HAIKU__) \ + ) +# undef BOOST_OS_HAIKU +# define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_HAIKU +# define BOOST_OS_HAIKU_AVAILABLE +# include +#endif + +#define BOOST_OS_HAIKU_NAME "Haiku" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HAIKU,BOOST_OS_HAIKU_NAME) diff --git a/src/boost/predef/os/hpux.h b/src/boost/predef/os/hpux.h new file mode 100644 index 00000000..79019148 --- /dev/null +++ b/src/boost/predef/os/hpux.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_HPUX_H +#define BOOST_PREDEF_OS_HPUX_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_HPUX` + +http://en.wikipedia.org/wiki/HP-UX[HP-UX] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `hpux` | {predef_detection} +| `+_hpux+` | {predef_detection} +| `+__hpux+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_HPUX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(hpux) || defined(_hpux) || defined(__hpux) \ + ) +# undef BOOST_OS_HPUX +# define BOOST_OS_HPUX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_HPUX +# define BOOST_OS_HPUX_AVAILABLE +# include +#endif + +#define BOOST_OS_HPUX_NAME "HP-UX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HPUX,BOOST_OS_HPUX_NAME) diff --git a/src/boost/predef/os/ios.h b/src/boost/predef/os/ios.h new file mode 100644 index 00000000..138963af --- /dev/null +++ b/src/boost/predef/os/ios.h @@ -0,0 +1,52 @@ +/* +Copyright Franz Detro 2014 +Copyright Rene Rivera 2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_IOS_H +#define BOOST_PREDEF_OS_IOS_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_IOS` + +http://en.wikipedia.org/wiki/iOS[iOS] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__APPLE__+` | {predef_detection} +| `+__MACH__+` | {predef_detection} +| `+__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__+` | {predef_detection} + +| `+__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__+` | +__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__+*1000 +|=== +*/ // end::reference[] + +#define BOOST_OS_IOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__APPLE__) && defined(__MACH__) && \ + defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) \ + ) +# undef BOOST_OS_IOS +# define BOOST_OS_IOS (__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__*1000) +#endif + +#if BOOST_OS_IOS +# define BOOST_OS_IOS_AVAILABLE +# include +#endif + +#define BOOST_OS_IOS_NAME "iOS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IOS,BOOST_OS_IOS_NAME) diff --git a/src/boost/predef/os/irix.h b/src/boost/predef/os/irix.h new file mode 100644 index 00000000..7c0bab04 --- /dev/null +++ b/src/boost/predef/os/irix.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_IRIX_H +#define BOOST_PREDEF_OS_IRIX_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_IRIX` + +http://en.wikipedia.org/wiki/Irix[IRIX] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `sgi` | {predef_detection} +| `+__sgi+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_IRIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(sgi) || defined(__sgi) \ + ) +# undef BOOST_OS_IRIX +# define BOOST_OS_IRIX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_IRIX +# define BOOST_OS_IRIX_AVAILABLE +# include +#endif + +#define BOOST_OS_IRIX_NAME "IRIX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IRIX,BOOST_OS_IRIX_NAME) diff --git a/src/boost/predef/os/linux.h b/src/boost/predef/os/linux.h new file mode 100644 index 00000000..bab64fc4 --- /dev/null +++ b/src/boost/predef/os/linux.h @@ -0,0 +1,50 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_LINUX_H +#define BOOST_PREDEF_OS_LINUX_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_LINUX` + +http://en.wikipedia.org/wiki/Linux[Linux] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `linux` | {predef_detection} +| `+__linux+` | {predef_detection} +| `+__linux__+` | {predef_detection} +| `+__gnu_linux__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_LINUX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(linux) || defined(__linux) || \ + defined(__linux__) || defined(__gnu_linux__) \ + ) +# undef BOOST_OS_LINUX +# define BOOST_OS_LINUX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_LINUX +# define BOOST_OS_LINUX_AVAILABLE +# include +#endif + +#define BOOST_OS_LINUX_NAME "Linux" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_LINUX,BOOST_OS_LINUX_NAME) diff --git a/src/boost/predef/os/macos.h b/src/boost/predef/os/macos.h new file mode 100644 index 00000000..1a443184 --- /dev/null +++ b/src/boost/predef/os/macos.h @@ -0,0 +1,66 @@ +/* +Copyright Rene Rivera 2008-2015 +Copyright Franz Detro 2014 +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) +*/ + +#ifndef BOOST_PREDEF_OS_MACOS_H +#define BOOST_PREDEF_OS_MACOS_H + +/* Special case: iOS will define the same predefs as MacOS, and additionally + '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__'. We can guard against that, + but only if we detect iOS first. Hence we will force include iOS detection + * before doing any MacOS detection. + */ +#include + +#include +#include + +/* tag::reference[] += `BOOST_OS_MACOS` + +http://en.wikipedia.org/wiki/Mac_OS[Mac OS] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `macintosh` | {predef_detection} +| `Macintosh` | {predef_detection} +| `+__APPLE__+` | {predef_detection} +| `+__MACH__+` | {predef_detection} + +| `+__APPLE__+`, `+__MACH__+` | 10.0.0 +| `_otherwise_` | 9.0.0 +|=== +*/ // end::reference[] + +#define BOOST_OS_MACOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(macintosh) || defined(Macintosh) || \ + (defined(__APPLE__) && defined(__MACH__)) \ + ) +# undef BOOST_OS_MACOS +# if !defined(BOOST_OS_MACOS) && defined(__APPLE__) && defined(__MACH__) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(10,0,0) +# endif +# if !defined(BOOST_OS_MACOS) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(9,0,0) +# endif +#endif + +#if BOOST_OS_MACOS +# define BOOST_OS_MACOS_AVAILABLE +# include +#endif + +#define BOOST_OS_MACOS_NAME "Mac OS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_MACOS,BOOST_OS_MACOS_NAME) diff --git a/src/boost/predef/os/os400.h b/src/boost/predef/os/os400.h new file mode 100644 index 00000000..209638d1 --- /dev/null +++ b/src/boost/predef/os/os400.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_OS400_H +#define BOOST_PREDEF_OS_OS400_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_OS400` + +http://en.wikipedia.org/wiki/IBM_i[IBM OS/400] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__OS400__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_OS400 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__OS400__) \ + ) +# undef BOOST_OS_OS400 +# define BOOST_OS_OS400 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_OS400 +# define BOOST_OS_OS400_AVAILABLE +# include +#endif + +#define BOOST_OS_OS400_NAME "IBM OS/400" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_OS400,BOOST_OS_OS400_NAME) diff --git a/src/boost/predef/os/qnxnto.h b/src/boost/predef/os/qnxnto.h new file mode 100644 index 00000000..7507cd08 --- /dev/null +++ b/src/boost/predef/os/qnxnto.h @@ -0,0 +1,60 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_QNXNTO_H +#define BOOST_PREDEF_OS_QNXNTO_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_QNX` + +http://en.wikipedia.org/wiki/QNX[QNX] operating system. +Version number available as major, and minor if possible. And +version 4 is specifically detected. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__QNX__+` | {predef_detection} +| `+__QNXNTO__+` | {predef_detection} + +| `+_NTO_VERSION+` | V.R.0 +| `+__QNX__+` | 4.0.0 +|=== +*/ // end::reference[] + +#define BOOST_OS_QNX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__QNX__) || defined(__QNXNTO__) \ + ) +# undef BOOST_OS_QNX +# if !defined(BOOST_OS_QNX) && defined(_NTO_VERSION) +# define BOOST_OS_QNX BOOST_PREDEF_MAKE_10_VVRR(_NTO_VERSION) +# endif +# if !defined(BOOST_OS_QNX) && defined(__QNX__) +# define BOOST_OS_QNX BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_OS_QNX) +# define BOOST_OS_QNX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_QNX +# define BOOST_OS_QNX_AVAILABLE +# include +#endif + +#define BOOST_OS_QNX_NAME "QNX" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_QNX,BOOST_OS_QNX_NAME) diff --git a/src/boost/predef/os/solaris.h b/src/boost/predef/os/solaris.h new file mode 100644 index 00000000..529af2b3 --- /dev/null +++ b/src/boost/predef/os/solaris.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_SOLARIS_H +#define BOOST_PREDEF_OS_SOLARIS_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_SOLARIS` + +http://en.wikipedia.org/wiki/Solaris_Operating_Environment[Solaris] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `sun` | {predef_detection} +| `+__sun+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(sun) || defined(__sun) \ + ) +# undef BOOST_OS_SOLARIS +# define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_SOLARIS +# define BOOST_OS_SOLARIS_AVAILABLE +# include +#endif + +#define BOOST_OS_SOLARIS_NAME "Solaris" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SOLARIS,BOOST_OS_SOLARIS_NAME) diff --git a/src/boost/predef/os/unix.h b/src/boost/predef/os/unix.h new file mode 100644 index 00000000..b86051dd --- /dev/null +++ b/src/boost/predef/os/unix.h @@ -0,0 +1,78 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_UNIX_H +#define BOOST_PREDEF_OS_UNIX_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_UNIX` + +http://en.wikipedia.org/wiki/Unix[Unix Environment] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `unix` | {predef_detection} +| `+__unix+` | {predef_detection} +| `+_XOPEN_SOURCE+` | {predef_detection} +| `+_POSIX_SOURCE+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_UNIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(unix) || defined(__unix) || \ + defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) +# undef BOOST_OS_UNIX +# define BOOST_OS_UNIX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_UNIX +# define BOOST_OS_UNIX_AVAILABLE +#endif + +#define BOOST_OS_UNIX_NAME "Unix Environment" + +/* tag::reference[] += `BOOST_OS_SVR4` + +http://en.wikipedia.org/wiki/UNIX_System_V[SVR4 Environment] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__sysv__+` | {predef_detection} +| `+__SVR4+` | {predef_detection} +| `+__svr4__+` | {predef_detection} +| `+_SYSTYPE_SVR4+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sysv__) || defined(__SVR4) || \ + defined(__svr4__) || defined(_SYSTYPE_SVR4) +# undef BOOST_OS_SVR4 +# define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_SVR4 +# define BOOST_OS_SVR4_AVAILABLE +#endif + +#define BOOST_OS_SVR4_NAME "SVR4 Environment" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_UNIX,BOOST_OS_UNIX_NAME) +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SVR4,BOOST_OS_SVR4_NAME) diff --git a/src/boost/predef/os/vms.h b/src/boost/predef/os/vms.h new file mode 100644 index 00000000..452e21d5 --- /dev/null +++ b/src/boost/predef/os/vms.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2011-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_VMS_H +#define BOOST_PREDEF_OS_VMS_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_VMS` + +http://en.wikipedia.org/wiki/OpenVMS[VMS] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `VMS` | {predef_detection} +| `+__VMS+` | {predef_detection} + +| `+__VMS_VER+` | V.R.P +|=== +*/ // end::reference[] + +#define BOOST_OS_VMS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(VMS) || defined(__VMS) \ + ) +# undef BOOST_OS_VMS +# if defined(__VMS_VER) +# define BOOST_OS_VMS BOOST_PREDEF_MAKE_10_VVRR00PP00(__VMS_VER) +# else +# define BOOST_OS_VMS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_VMS +# define BOOST_OS_VMS_AVAILABLE +# include +#endif + +#define BOOST_OS_VMS_NAME "VMS" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_VMS,BOOST_OS_VMS_NAME) diff --git a/src/boost/predef/os/windows.h b/src/boost/predef/os/windows.h new file mode 100644 index 00000000..d8d2d2b2 --- /dev/null +++ b/src/boost/predef/os/windows.h @@ -0,0 +1,52 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_OS_WINDOWS_H +#define BOOST_PREDEF_OS_WINDOWS_H + +#include +#include + +/* tag::reference[] += `BOOST_OS_WINDOWS` + +http://en.wikipedia.org/wiki/Category:Microsoft_Windows[Microsoft Windows] operating system. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+_WIN32+` | {predef_detection} +| `+_WIN64+` | {predef_detection} +| `+__WIN32__+` | {predef_detection} +| `+__TOS_WIN__+` | {predef_detection} +| `+__WINDOWS__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(_WIN32) || defined(_WIN64) || \ + defined(__WIN32__) || defined(__TOS_WIN__) || \ + defined(__WINDOWS__) \ + ) +# undef BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS_AVAILABLE +# include +#endif + +#define BOOST_OS_WINDOWS_NAME "Microsoft Windows" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_WINDOWS,BOOST_OS_WINDOWS_NAME) diff --git a/src/boost/predef/other.h b/src/boost/predef/other.h new file mode 100644 index 00000000..dc7e341e --- /dev/null +++ b/src/boost/predef/other.h @@ -0,0 +1,17 @@ +/* +Copyright Rene Ferdinand Rivera Morell 2013-2020 +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) +*/ + +#if !defined(BOOST_PREDEF_OTHER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_OTHER_H +#define BOOST_PREDEF_OTHER_H +#endif + +#include +#include +#include + +#endif diff --git a/src/boost/predef/other/endian.h b/src/boost/predef/other/endian.h new file mode 100644 index 00000000..435492a0 --- /dev/null +++ b/src/boost/predef/other/endian.h @@ -0,0 +1,202 @@ +/* +Copyright Rene Rivera 2013-2015 +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) +*/ + +#ifndef BOOST_PREDEF_ENDIAN_H +#define BOOST_PREDEF_ENDIAN_H + +#include +#include +#include +#include +#include +#include + +/* tag::reference[] += `BOOST_ENDIAN_*` + +Detection of endian memory ordering. There are four defined macros +in this header that define the various generally possible endian +memory orderings: + +* `BOOST_ENDIAN_BIG_BYTE`, byte-swapped big-endian. +* `BOOST_ENDIAN_BIG_WORD`, word-swapped big-endian. +* `BOOST_ENDIAN_LITTLE_BYTE`, byte-swapped little-endian. +* `BOOST_ENDIAN_LITTLE_WORD`, word-swapped little-endian. + +The detection is conservative in that it only identifies endianness +that it knows for certain. In particular bi-endianness is not +indicated as is it not practically possible to determine the +endianness from anything but an operating system provided +header. And the currently known headers do not define that +programatic bi-endianness is available. + +This implementation is a compilation of various publicly available +information and acquired knowledge: + +. The indispensable documentation of "Pre-defined Compiler Macros" + http://sourceforge.net/p/predef/wiki/Endianness[Endianness]. +. The various endian specifications available in the + http://wikipedia.org/[Wikipedia] computer architecture pages. +. Generally available searches for headers that define endianness. +*/ // end::reference[] + +#define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_BIG_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE + +/* GNU libc provides a header defining __BYTE_ORDER, or _BYTE_ORDER. + * And some OSs provide some for of endian header also. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if BOOST_LIB_C_GNU || BOOST_PLAT_ANDROID || BOOST_OS_BSD_OPEN +# include +# else +# if BOOST_OS_MACOS +# include +# else +# if BOOST_OS_BSD +# include +# endif +# endif +# endif +# if defined(__BYTE_ORDER) +# if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +# if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER) +# if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if defined(_PDP_ENDIAN) && (_BYTE_ORDER == _PDP_ENDIAN) +# undef BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +/* Built-in byte-swapped big-endian macros. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \ + (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \ + defined(__ARMEB__) || \ + defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || \ + defined(_MIPSEB) || \ + defined(__MIPSEB) || \ + defined(__MIPSEB__) +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +/* Built-in byte-swapped little-endian macros. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ + (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \ + defined(__ARMEL__) || \ + defined(__THUMBEL__) || \ + defined(__AARCH64EL__) || \ + defined(__loongarch__) || \ + defined(_MIPSEL) || \ + defined(__MIPSEL) || \ + defined(__MIPSEL__) || \ + defined(__riscv) || \ + defined(__e2k__) +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +/* Some architectures are strictly one endianess (as opposed + * the current common bi-endianess). + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# include +# if BOOST_ARCH_M68K || \ + BOOST_ARCH_PARISC || \ + BOOST_ARCH_SPARC || \ + BOOST_ARCH_SYS370 || \ + BOOST_ARCH_SYS390 || \ + BOOST_ARCH_Z +# undef BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# if BOOST_ARCH_IA64 || \ + BOOST_ARCH_X86 || \ + BOOST_ARCH_BLACKFIN +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +/* Windows on ARM, if not otherwise detected/specified, is always + * byte-swapped little-endian. + */ +#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \ + !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD +# if BOOST_ARCH_ARM +# include +# if BOOST_OS_WINDOWS +# undef BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +#if BOOST_ENDIAN_BIG_BYTE +# define BOOST_ENDIAN_BIG_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_BIG_WORD +# define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_LITTLE_BYTE +# define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE +#endif +#if BOOST_ENDIAN_LITTLE_WORD +# define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE +#endif + +#define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian" +#define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian" +#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian" +#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME) diff --git a/src/boost/predef/other/wordsize.h b/src/boost/predef/other/wordsize.h new file mode 100644 index 00000000..ce3016fe --- /dev/null +++ b/src/boost/predef/other/wordsize.h @@ -0,0 +1,73 @@ +/* +Copyright Rene Ferdinand Rivera Morell 2020-2021 +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) +*/ + +#ifndef BOOST_PREDEF_OTHER_WORD_SIZE_H +#define BOOST_PREDEF_OTHER_WORD_SIZE_H + +#include +#include +#include + +/* tag::reference[] += `BOOST_ARCH_WORD_BITS` + +Detects the native word size, in bits, for the current architecture. There are +two types of macros for this detection: + +* `BOOST_ARCH_WORD_BITS`, gives the number of word size bits + (16, 32, 64). +* `BOOST_ARCH_WORD_BITS_16`, `BOOST_ARCH_WORD_BITS_32`, and + `BOOST_ARCH_WORD_BITS_64`, indicate when the given word size is + detected. + +They allow for both single checks and direct use of the size in code. + +NOTE: The word size is determined manually on each architecture. Hence use of +the `wordsize.h` header will also include all the architecture headers. + +*/ // end::reference[] + +#if !defined(BOOST_ARCH_WORD_BITS_64) +# define BOOST_ARCH_WORD_BITS_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#elif !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 64 +#endif + +#if !defined(BOOST_ARCH_WORD_BITS_32) +# define BOOST_ARCH_WORD_BITS_32 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#elif !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 32 +#endif + +#if !defined(BOOST_ARCH_WORD_BITS_16) +# define BOOST_ARCH_WORD_BITS_16 BOOST_VERSION_NUMBER_NOT_AVAILABLE +#elif !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 16 +#endif + +#if !defined(BOOST_ARCH_WORD_BITS) +# define BOOST_ARCH_WORD_BITS 0 +#endif + +#define BOOST_ARCH_WORD_BITS_NAME "Word Bits" +#define BOOST_ARCH_WORD_BITS_16_NAME "16-bit Word Size" +#define BOOST_ARCH_WORD_BITS_32_NAME "32-bit Word Size" +#define BOOST_ARCH_WORD_BITS_64_NAME "64-bit Word Size" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS,BOOST_ARCH_WORD_BITS_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS_16,BOOST_ARCH_WORD_BITS_16_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS_32,BOOST_ARCH_WORD_BITS_32_NAME) + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_WORD_BITS_64,BOOST_ARCH_WORD_BITS_64_NAME) diff --git a/src/boost/predef/other/workaround.h b/src/boost/predef/other/workaround.h new file mode 100644 index 00000000..21f04d3f --- /dev/null +++ b/src/boost/predef/other/workaround.h @@ -0,0 +1,95 @@ +/* +Copyright Rene Rivera 2017 +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) +*/ + +#ifndef BOOST_PREDEF_WORKAROUND_H +#define BOOST_PREDEF_WORKAROUND_H + +/* tag::reference[] + += `BOOST_PREDEF_WORKAROUND` + +[source] +---- +BOOST_PREDEF_WORKAROUND(symbol,comp,major,minor,patch) +---- + +Usage: + +[source] +---- +#if BOOST_PREDEF_WORKAROUND(BOOST_COMP_CLANG,<,3,0,0) + // Workaround for old clang compilers.. +#endif +---- + +Defines a comparison against two version numbers that depends on the definion +of `BOOST_STRICT_CONFIG`. When `BOOST_STRICT_CONFIG` is defined this will expand +to a value convertible to `false`. Which has the effect of disabling all code +conditionally guarded by `BOOST_PREDEF_WORKAROUND`. When `BOOST_STRICT_CONFIG` +is undefine this expand to test the given `symbol` version value with the +`comp` comparison against `BOOST_VERSION_NUMBER(major,minor,patch)`. + +*/ // end::reference[] +#ifdef BOOST_STRICT_CONFIG +# define BOOST_PREDEF_WORKAROUND(symbol, comp, major, minor, patch) (0) +#else +# include +# define BOOST_PREDEF_WORKAROUND(symbol, comp, major, minor, patch) \ + ( (symbol) != (0) ) && \ + ( (symbol) comp (BOOST_VERSION_NUMBER( (major) , (minor) , (patch) )) ) +#endif + +/* tag::reference[] + += `BOOST_PREDEF_TESTED_AT` + +[source] +---- +BOOST_PREDEF_TESTED_AT(symbol,major,minor,patch) +---- + +Usage: + +[source] +---- +#if BOOST_PREDEF_TESTED_AT(BOOST_COMP_CLANG,3,5,0) + // Needed for clang, and last checked for 3.5.0. +#endif +---- + +Defines a comparison against two version numbers that depends on the definion +of `BOOST_STRICT_CONFIG` and `BOOST_DETECT_OUTDATED_WORKAROUNDS`. +When `BOOST_STRICT_CONFIG` is defined this will expand to a value convertible +to `false`. Which has the effect of disabling all code +conditionally guarded by `BOOST_PREDEF_TESTED_AT`. When `BOOST_STRICT_CONFIG` +is undefined this expand to either: + +* A value convertible to `true` when `BOOST_DETECT_OUTDATED_WORKAROUNDS` is not + defined. +* A value convertible `true` when the expansion of + `BOOST_PREDEF_WORKAROUND(symbol, <=, major, minor, patch)` is `true` and + `BOOST_DETECT_OUTDATED_WORKAROUNDS` is defined. +* A compile error when the expansion of + `BOOST_PREDEF_WORKAROUND(symbol, >, major, minor, patch)` is true and + `BOOST_DETECT_OUTDATED_WORKAROUNDS` is defined. + +*/ // end::reference[] +#ifdef BOOST_STRICT_CONFIG +# define BOOST_PREDEF_TESTED_AT(symbol, major, minor, patch) (0) +#else +# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_PREDEF_TESTED_AT(symbol, major, minor, patch) ( \ + BOOST_PREDEF_WORKAROUND(symbol, <=, major, minor, patch) \ + ? 1 \ + : (1%0) ) +# else +# define BOOST_PREDEF_TESTED_AT(symbol, major, minor, patch) \ + ( (symbol) >= BOOST_VERSION_NUMBER_AVAILABLE ) +# endif +#endif + +#endif diff --git a/src/boost/predef/platform.h b/src/boost/predef/platform.h new file mode 100644 index 00000000..756d65fd --- /dev/null +++ b/src/boost/predef/platform.h @@ -0,0 +1,28 @@ +/* +Copyright Rene Rivera 2013-2015 +Copyright (c) Microsoft Corporation 2014 +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) +*/ + +#if !defined(BOOST_PREDEF_PLATFORM_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_PLATFORM_H +#define BOOST_PREDEF_PLATFORM_H +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // deprecated +#include + +#endif diff --git a/src/boost/predef/platform/android.h b/src/boost/predef/platform/android.h new file mode 100644 index 00000000..5acfcd38 --- /dev/null +++ b/src/boost/predef/platform/android.h @@ -0,0 +1,44 @@ +/* +Copyright Rene Rivera 2015-2019 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_ANDROID_H +#define BOOST_PREDEF_PLAT_ANDROID_H + +#include +#include + +/* tag::reference[] += `BOOST_PLAT_ANDROID` + +http://en.wikipedia.org/wiki/Android_%28operating_system%29[Android] platform. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__ANDROID__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_ANDROID BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__ANDROID__) +# undef BOOST_PLAT_ANDROID +# define BOOST_PLAT_ANDROID BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_ANDROID +# define BOOST_PLAT_ANDROID_AVAILABLE +# include +#endif + +#define BOOST_PLAT_ANDROID_NAME "Android" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_ANDROID,BOOST_PLAT_ANDROID_NAME) diff --git a/src/boost/predef/platform/cloudabi.h b/src/boost/predef/platform/cloudabi.h new file mode 100644 index 00000000..a951c0ef --- /dev/null +++ b/src/boost/predef/platform/cloudabi.h @@ -0,0 +1,44 @@ +/* + Copyright 2017 James E. King, III + 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) +*/ + +#ifndef BOOST_PREDEF_PLAT_CLOUDABI_H +#define BOOST_PREDEF_PLAT_CLOUDABI_H + +#include +#include + +/* tag::reference[] += `BOOST_PLAT_CLOUDABI` + +https://github.com/NuxiNL/cloudabi[CloudABI] platform. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__CloudABI__+` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_CLOUDABI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__CloudABI__) +# undef BOOST_PLAT_CLOUDABI +# define BOOST_PLAT_CLOUDABI BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_CLOUDABI +# define BOOST_PLAT_CLOUDABI_AVAILABLE +# include +#endif + +#define BOOST_PLAT_CLOUDABI_NAME "CloudABI" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_CLOUDABI,BOOST_PLAT_CLOUDABI_NAME) diff --git a/src/boost/predef/platform/ios.h b/src/boost/predef/platform/ios.h new file mode 100644 index 00000000..7d7c815f --- /dev/null +++ b/src/boost/predef/platform/ios.h @@ -0,0 +1,63 @@ +/* +Copyright Ruslan Baratov 2017 +Copyright Rene Rivera 2017 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_IOS_H +#define BOOST_PREDEF_PLAT_IOS_H + +#include // BOOST_OS_IOS +#include // BOOST_VERSION_NUMBER_NOT_AVAILABLE + +/* tag::reference[] += `BOOST_PLAT_IOS_DEVICE` += `BOOST_PLAT_IOS_SIMULATOR` + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `TARGET_IPHONE_SIMULATOR` | {predef_detection} +| `TARGET_OS_SIMULATOR` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_IOS_DEVICE BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_PLAT_IOS_SIMULATOR BOOST_VERSION_NUMBER_NOT_AVAILABLE + +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h +#if BOOST_OS_IOS +# include +# if defined(TARGET_OS_SIMULATOR) && (TARGET_OS_SIMULATOR == 1) +# undef BOOST_PLAT_IOS_SIMULATOR +# define BOOST_PLAT_IOS_SIMULATOR BOOST_VERSION_NUMBER_AVAILABLE +# elif defined(TARGET_IPHONE_SIMULATOR) && (TARGET_IPHONE_SIMULATOR == 1) +# undef BOOST_PLAT_IOS_SIMULATOR +# define BOOST_PLAT_IOS_SIMULATOR BOOST_VERSION_NUMBER_AVAILABLE +# else +# undef BOOST_PLAT_IOS_DEVICE +# define BOOST_PLAT_IOS_DEVICE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_PLAT_IOS_SIMULATOR +# define BOOST_PLAT_IOS_SIMULATOR_AVAILABLE +# include +#endif + +#if BOOST_PLAT_IOS_DEVICE +# define BOOST_PLAT_IOS_DEVICE_AVAILABLE +# include +#endif + +#define BOOST_PLAT_IOS_SIMULATOR_NAME "iOS Simulator" +#define BOOST_PLAT_IOS_DEVICE_NAME "iOS Device" + +#endif // BOOST_PREDEF_PLAT_IOS_H + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_IOS_SIMULATOR,BOOST_PLAT_IOS_SIMULATOR_NAME) +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_IOS_DEVICE,BOOST_PLAT_IOS_DEVICE_NAME) diff --git a/src/boost/predef/platform/mingw.h b/src/boost/predef/platform/mingw.h new file mode 100644 index 00000000..0be00c61 --- /dev/null +++ b/src/boost/predef/platform/mingw.h @@ -0,0 +1,70 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_MINGW_H +#define BOOST_PREDEF_PLAT_MINGW_H + +#include +#include + +/* tag::reference[] += `BOOST_PLAT_MINGW` + +http://en.wikipedia.org/wiki/MinGW[MinGW] platform, either variety. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__MINGW32__+` | {predef_detection} +| `+__MINGW64__+` | {predef_detection} + +| `+__MINGW64_VERSION_MAJOR+`, `+__MINGW64_VERSION_MINOR+` | V.R.0 +| `+__MINGW32_VERSION_MAJOR+`, `+__MINGW32_VERSION_MINOR+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_PLAT_MINGW BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MINGW32__) || defined(__MINGW64__) +# include <_mingw.h> +# if !defined(BOOST_PLAT_MINGW_DETECTION) && (defined(__MINGW64_VERSION_MAJOR) && defined(__MINGW64_VERSION_MINOR)) +# define BOOST_PLAT_MINGW_DETECTION \ + BOOST_VERSION_NUMBER(__MINGW64_VERSION_MAJOR,__MINGW64_VERSION_MINOR,0) +# endif +# if !defined(BOOST_PLAT_MINGW_DETECTION) && (defined(__MINGW32_VERSION_MAJOR) && defined(__MINGW32_VERSION_MINOR)) +# define BOOST_PLAT_MINGW_DETECTION \ + BOOST_VERSION_NUMBER(__MINGW32_MAJOR_VERSION,__MINGW32_MINOR_VERSION,0) +# endif +# if !defined(BOOST_PLAT_MINGW_DETECTION) +# define BOOST_PLAT_MINGW_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_PLAT_MINGW_DETECTION +# define BOOST_PLAT_MINGW_AVAILABLE +# if defined(BOOST_PREDEF_DETAIL_PLAT_DETECTED) +# define BOOST_PLAT_MINGW_EMULATED BOOST_PLAT_MINGW_DETECTION +# else +# undef BOOST_PLAT_MINGW +# define BOOST_PLAT_MINGW BOOST_PLAT_MINGW_DETECTION +# endif +# include +#endif + +#define BOOST_PLAT_MINGW_NAME "MinGW (any variety)" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW,BOOST_PLAT_MINGW_NAME) + +#ifdef BOOST_PLAT_MINGW_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW_EMULATED,BOOST_PLAT_MINGW_NAME) +#endif diff --git a/src/boost/predef/platform/mingw32.h b/src/boost/predef/platform/mingw32.h new file mode 100644 index 00000000..73e99e68 --- /dev/null +++ b/src/boost/predef/platform/mingw32.h @@ -0,0 +1,64 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_MINGW32_H +#define BOOST_PREDEF_PLAT_MINGW32_H + +#include +#include + +/* tag::reference[] += `BOOST_PLAT_MINGW32` + +http://www.mingw.org/[MinGW] platform. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__MINGW32__+` | {predef_detection} + +| `+__MINGW32_VERSION_MAJOR+`, `+__MINGW32_VERSION_MINOR+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_PLAT_MINGW32 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MINGW32__) +# include <_mingw.h> +# if !defined(BOOST_PLAT_MINGW32_DETECTION) && (defined(__MINGW32_VERSION_MAJOR) && defined(__MINGW32_VERSION_MINOR)) +# define BOOST_PLAT_MINGW32_DETECTION \ + BOOST_VERSION_NUMBER(__MINGW32_VERSION_MAJOR,__MINGW32_VERSION_MINOR,0) +# endif +# if !defined(BOOST_PLAT_MINGW32_DETECTION) +# define BOOST_PLAT_MINGW32_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_PLAT_MINGW32_DETECTION +# define BOOST_PLAT_MINGW32_AVAILABLE +# if defined(BOOST_PREDEF_DETAIL_PLAT_DETECTED) +# define BOOST_PLAT_MINGW32_EMULATED BOOST_PLAT_MINGW32_DETECTION +# else +# undef BOOST_PLAT_MINGW32 +# define BOOST_PLAT_MINGW32 BOOST_PLAT_MINGW32_DETECTION +# endif +# include +#endif + +#define BOOST_PLAT_MINGW32_NAME "MinGW" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW32,BOOST_PLAT_MINGW32_NAME) + +#ifdef BOOST_PLAT_MINGW32_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW32_EMULATED,BOOST_PLAT_MINGW32_NAME) +#endif diff --git a/src/boost/predef/platform/mingw64.h b/src/boost/predef/platform/mingw64.h new file mode 100644 index 00000000..a49b195f --- /dev/null +++ b/src/boost/predef/platform/mingw64.h @@ -0,0 +1,64 @@ +/* +Copyright Rene Rivera 2008-2015 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_MINGW64_H +#define BOOST_PREDEF_PLAT_MINGW64_H + +#include +#include + +/* tag::reference[] += `BOOST_PLAT_MINGW64` + +https://mingw-w64.org/[MinGW-w64] platform. +Version number available as major, minor, and patch. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__MINGW64__+` | {predef_detection} + +| `+__MINGW64_VERSION_MAJOR+`, `+__MINGW64_VERSION_MINOR+` | V.R.0 +|=== +*/ // end::reference[] + +#define BOOST_PLAT_MINGW64 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__MINGW64__) +# include <_mingw.h> +# if !defined(BOOST_PLAT_MINGW64_DETECTION) && (defined(__MINGW64_VERSION_MAJOR) && defined(__MINGW64_VERSION_MINOR)) +# define BOOST_PLAT_MINGW64_DETECTION \ + BOOST_VERSION_NUMBER(__MINGW64_VERSION_MAJOR,__MINGW64_VERSION_MINOR,0) +# endif +# if !defined(BOOST_PLAT_MINGW64_DETECTION) +# define BOOST_PLAT_MINGW64_DETECTION BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#ifdef BOOST_PLAT_MINGW64_DETECTION +# define BOOST_PLAT_MINGW64_AVAILABLE +# if defined(BOOST_PREDEF_DETAIL_PLAT_DETECTED) +# define BOOST_PLAT_MINGW64_EMULATED BOOST_PLAT_MINGW64_DETECTION +# else +# undef BOOST_PLAT_MINGW64 +# define BOOST_PLAT_MINGW64 BOOST_PLAT_MINGW64_DETECTION +# endif +# include +#endif + +#define BOOST_PLAT_MINGW64_NAME "MinGW-w64" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW64,BOOST_PLAT_MINGW64_NAME) + +#ifdef BOOST_PLAT_MINGW64_EMULATED +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW64_EMULATED,BOOST_PLAT_MINGW64_NAME) +#endif diff --git a/src/boost/predef/platform/windows_desktop.h b/src/boost/predef/platform/windows_desktop.h new file mode 100644 index 00000000..917c3395 --- /dev/null +++ b/src/boost/predef/platform/windows_desktop.h @@ -0,0 +1,52 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_DESKTOP_H +#define BOOST_PREDEF_PLAT_WINDOWS_DESKTOP_H + +#include +#include +#include +#include + +/* tag::reference[] += `BOOST_PLAT_WINDOWS_DESKTOP` + +https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide[UWP] +for Windows Desktop development. Also available if the Platform SDK is too +old to support UWP. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP` | {predef_detection} +| `!BOOST_PLAT_WINDOWS_UWP` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_WINDOWS_DESKTOP BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && \ + ((defined(WINAPI_FAMILY_DESKTOP_APP) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) || \ + !BOOST_PLAT_WINDOWS_UWP) +# undef BOOST_PLAT_WINDOWS_DESKTOP +# define BOOST_PLAT_WINDOWS_DESKTOP BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_DESKTOP +# define BOOST_PLAT_WINDOWS_DESKTOP_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_DESKTOP_NAME "Windows Desktop" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_DESKTOP,BOOST_PLAT_WINDOWS_DESKTOP_NAME) diff --git a/src/boost/predef/platform/windows_phone.h b/src/boost/predef/platform/windows_phone.h new file mode 100644 index 00000000..cfb1b65e --- /dev/null +++ b/src/boost/predef/platform/windows_phone.h @@ -0,0 +1,49 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_PHONE_H +#define BOOST_PREDEF_PLAT_WINDOWS_PHONE_H + +#include +#include +#include +#include + +/* tag::reference[] += `BOOST_PLAT_WINDOWS_PHONE` + +https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide[UWP] +for Windows Phone development. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_WINDOWS_PHONE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && \ + defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +# undef BOOST_PLAT_WINDOWS_PHONE +# define BOOST_PLAT_WINDOWS_PHONE BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_PHONE +# define BOOST_PLAT_WINDOWS_PHONE_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_PHONE_NAME "Windows Phone" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_PHONE,BOOST_PLAT_WINDOWS_PHONE_NAME) diff --git a/src/boost/predef/platform/windows_runtime.h b/src/boost/predef/platform/windows_runtime.h new file mode 100644 index 00000000..44542d61 --- /dev/null +++ b/src/boost/predef/platform/windows_runtime.h @@ -0,0 +1,54 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_RUNTIME_H +#define BOOST_PREDEF_PLAT_WINDOWS_RUNTIME_H + +#include +#include +#include +#include +#include + +/* tag::reference[] += `BOOST_PLAT_WINDOWS_RUNTIME` + +Deprecated. + +https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide[UWP] +for Windows Phone or Store development. This does not align to the existing development model for +UWP and is deprecated. Use one of the other `BOOST_PLAT_WINDOWS_*`definitions instead. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `BOOST_PLAT_WINDOWS_PHONE` | {predef_detection} +| `BOOST_PLAT_WINDOWS_STORE` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_WINDOWS_RUNTIME BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && \ + (BOOST_PLAT_WINDOWS_STORE || BOOST_PLAT_WINDOWS_PHONE) +# undef BOOST_PLAT_WINDOWS_RUNTIME +# define BOOST_PLAT_WINDOWS_RUNTIME BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_RUNTIME +# define BOOST_PLAT_WINDOWS_RUNTIME_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_RUNTIME_NAME "Windows Runtime" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_RUNTIME,BOOST_PLAT_WINDOWS_RUNTIME_NAME) diff --git a/src/boost/predef/platform/windows_server.h b/src/boost/predef/platform/windows_server.h new file mode 100644 index 00000000..f0e3dc0b --- /dev/null +++ b/src/boost/predef/platform/windows_server.h @@ -0,0 +1,48 @@ +/* +Copyright James E. King III, 2017 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_SERVER_H +#define BOOST_PREDEF_PLAT_WINDOWS_SERVER_H + +#include +#include +#include +#include + +/* tag::reference[] += `BOOST_PLAT_WINDOWS_SERVER` + +https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide[UWP] +for Windows Server development. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `WINAPI_FAMILY == WINAPI_FAMILY_SERVER` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_WINDOWS_SERVER BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && \ + defined(WINAPI_FAMILY_SERVER) && WINAPI_FAMILY == WINAPI_FAMILY_SERVER +# undef BOOST_PLAT_WINDOWS_SERVER +# define BOOST_PLAT_WINDOWS_SERVER BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_SERVER +# define BOOST_PLAT_WINDOWS_SERVER_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_SERVER_NAME "Windows Server" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_SERVER,BOOST_PLAT_WINDOWS_SERVER_NAME) diff --git a/src/boost/predef/platform/windows_store.h b/src/boost/predef/platform/windows_store.h new file mode 100644 index 00000000..ac5ff519 --- /dev/null +++ b/src/boost/predef/platform/windows_store.h @@ -0,0 +1,51 @@ +/* +Copyright (c) Microsoft Corporation 2014 +Copyright Rene Rivera 2015 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_STORE_H +#define BOOST_PREDEF_PLAT_WINDOWS_STORE_H + +#include +#include +#include +#include + +/* tag::reference[] += `BOOST_PLAT_WINDOWS_STORE` + +https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide[UWP] +for Windows Store development. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `WINAPI_FAMILY == WINAPI_FAMILY_PC_APP` | {predef_detection} +| `WINAPI_FAMILY == WINAPI_FAMILY_APP` (deprecated) | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && \ + ((defined(WINAPI_FAMILY_PC_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) || \ + (defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP)) +# undef BOOST_PLAT_WINDOWS_STORE +# define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_STORE +# define BOOST_PLAT_WINDOWS_STORE_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_STORE_NAME "Windows Store" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_STORE,BOOST_PLAT_WINDOWS_STORE_NAME) diff --git a/src/boost/predef/platform/windows_system.h b/src/boost/predef/platform/windows_system.h new file mode 100644 index 00000000..71a0c2c6 --- /dev/null +++ b/src/boost/predef/platform/windows_system.h @@ -0,0 +1,48 @@ +/* +Copyright James E. King III, 2017 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_SYSTEM_H +#define BOOST_PREDEF_PLAT_WINDOWS_SYSTEM_H + +#include +#include +#include +#include + +/* tag::reference[] += `BOOST_PLAT_WINDOWS_SYSTEM` + +https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide[UWP] +for Windows System development. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `WINAPI_FAMILY == WINAPI_FAMILY_SYSTEM` | {predef_detection} +|=== +*/ // end::reference[] + +#define BOOST_PLAT_WINDOWS_SYSTEM BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS && \ + defined(WINAPI_FAMILY_SYSTEM) && WINAPI_FAMILY == WINAPI_FAMILY_SYSTEM +# undef BOOST_PLAT_WINDOWS_SYSTEM +# define BOOST_PLAT_WINDOWS_SYSTEM BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_PLAT_WINDOWS_SYSTEM +# define BOOST_PLAT_WINDOWS_SYSTEM_AVAILABLE +# include +#endif + +#define BOOST_PLAT_WINDOWS_SYSTEM_NAME "Windows Drivers and Tools" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_SYSTEM,BOOST_PLAT_WINDOWS_SYSTEM_NAME) diff --git a/src/boost/predef/platform/windows_uwp.h b/src/boost/predef/platform/windows_uwp.h new file mode 100644 index 00000000..8dc1380b --- /dev/null +++ b/src/boost/predef/platform/windows_uwp.h @@ -0,0 +1,61 @@ +/* +Copyright James E. King III, 2017 +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) +*/ + +#ifndef BOOST_PREDEF_PLAT_WINDOWS_UWP_H +#define BOOST_PREDEF_PLAT_WINDOWS_UWP_H + +#include +#include +#include + +/* tag::reference[] += `BOOST_PLAT_WINDOWS_UWP` + +http://docs.microsoft.com/windows/uwp/[Universal Windows Platform] +is available if the current development environment is capable of targeting +UWP development. + +[options="header"] +|=== +| {predef_symbol} | {predef_version} + +| `+__MINGW64_VERSION_MAJOR+` from `+_mingw.h+` | `>= 3` +| `VER_PRODUCTBUILD` from `ntverp.h` | `>= 9200` +|=== +*/ // end::reference[] + +#define BOOST_PLAT_WINDOWS_UWP BOOST_VERSION_NUMBER_NOT_AVAILABLE +#define BOOST_PLAT_WINDOWS_SDK_VERSION BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if BOOST_OS_WINDOWS +// MinGW (32-bit), WinCE, and wineg++ don't have a ntverp.h header +#if !defined(__MINGW32__) && !defined(_WIN32_WCE) && !defined(__WINE__) +# include +# undef BOOST_PLAT_WINDOWS_SDK_VERSION +# define BOOST_PLAT_WINDOWS_SDK_VERSION BOOST_VERSION_NUMBER(0, 0, VER_PRODUCTBUILD) +#endif + +// 9200 is Windows SDK 8.0 from ntverp.h which introduced family support +#if ((BOOST_PLAT_WINDOWS_SDK_VERSION >= BOOST_VERSION_NUMBER(0, 0, 9200)) || \ + (defined(__MINGW64__) && __MINGW64_VERSION_MAJOR >= 3)) +# undef BOOST_PLAT_WINDOWS_UWP +# define BOOST_PLAT_WINDOWS_UWP BOOST_VERSION_NUMBER_AVAILABLE +#endif +#endif + +#if BOOST_PLAT_WINDOWS_UWP +# define BOOST_PLAT_WINDOWS_UWP_AVAILABLE +# include +# include // Windows SDK +#endif + +#define BOOST_PLAT_WINDOWS_UWP_NAME "Universal Windows Platform" + +#endif + +#include +BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_UWP, BOOST_PLAT_WINDOWS_UWP_NAME) diff --git a/src/boost/predef/version.h b/src/boost/predef/version.h new file mode 100644 index 00000000..ba8f62ce --- /dev/null +++ b/src/boost/predef/version.h @@ -0,0 +1,15 @@ +/* +Copyright Rene Rivera 2015-2016 +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) +*/ + +#ifndef BOOST_PREDEF_VERSION_H +#define BOOST_PREDEF_VERSION_H + +#include + +#define BOOST_PREDEF_VERSION BOOST_VERSION_NUMBER(1,15,1) + +#endif diff --git a/src/boost/predef/version_number.h b/src/boost/predef/version_number.h new file mode 100644 index 00000000..90357824 --- /dev/null +++ b/src/boost/predef/version_number.h @@ -0,0 +1,74 @@ +/* +Copyright Rene Rivera 2005-2016 +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) +*/ + +#ifndef BOOST_PREDEF_VERSION_NUMBER_H +#define BOOST_PREDEF_VERSION_NUMBER_H + +/* tag::reference[] += `BOOST_VERSION_NUMBER` + +[source] +---- +BOOST_VERSION_NUMBER(major,minor,patch) +---- + +Defines standard version numbers, with these properties: + +* Decimal base whole numbers in the range [0,1000000000). + The number range is designed to allow for a (2,2,5) triplet. + Which fits within a 32 bit value. +* The `major` number can be in the [0,99] range. +* The `minor` number can be in the [0,99] range. +* The `patch` number can be in the [0,99999] range. +* Values can be specified in any base. As the defined value + is an constant expression. +* Value can be directly used in both preprocessor and compiler + expressions for comparison to other similarly defined values. +* The implementation enforces the individual ranges for the + major, minor, and patch numbers. And values over the ranges + are truncated (modulo). + +*/ // end::reference[] +#define BOOST_VERSION_NUMBER(major,minor,patch) \ + ( (((major)%100)*10000000) + (((minor)%100)*100000) + ((patch)%100000) ) + +#define BOOST_VERSION_NUMBER_MAX \ + BOOST_VERSION_NUMBER(99,99,99999) + +#define BOOST_VERSION_NUMBER_ZERO \ + BOOST_VERSION_NUMBER(0,0,0) + +#define BOOST_VERSION_NUMBER_MIN \ + BOOST_VERSION_NUMBER(0,0,1) + +#define BOOST_VERSION_NUMBER_AVAILABLE \ + BOOST_VERSION_NUMBER_MIN + +#define BOOST_VERSION_NUMBER_NOT_AVAILABLE \ + BOOST_VERSION_NUMBER_ZERO + +/* tag::reference[] +[source] +---- +BOOST_VERSION_NUMBER_MAJOR(N), BOOST_VERSION_NUMBER_MINOR(N), BOOST_VERSION_NUMBER_PATCH(N) +---- + +The macros extract the major, minor, and patch portion from a well formed +version number resulting in a preprocessor expression in the range of +[0,99] or [0,99999] for the major and minor, or patch numbers +respectively. +*/ // end::reference[] +#define BOOST_VERSION_NUMBER_MAJOR(N) \ + ( ((N)/10000000)%100 ) + +#define BOOST_VERSION_NUMBER_MINOR(N) \ + ( ((N)/100000)%100 ) + +#define BOOST_VERSION_NUMBER_PATCH(N) \ + ( (N)%100000 ) + +#endif diff --git a/src/boost/static_assert.hpp b/src/boost/static_assert.hpp new file mode 100644 index 00000000..d94ca807 --- /dev/null +++ b/src/boost/static_assert.hpp @@ -0,0 +1,181 @@ +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are 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/libs/static_assert for documentation. + +/* + Revision history: + 02 August 2000 + Initial version. +*/ + +#ifndef BOOST_STATIC_ASSERT_HPP +#define BOOST_STATIC_ASSERT_HPP + +#include +#include +#include //for std::size_t + +#if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) +// +// This is horrible, but it seems to be the only we can shut up the +// "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]" +// warning that get spewed out otherwise in non-C++11 mode. +// +#pragma GCC system_header +#endif + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_MSG( ... ) static_assert(__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT_MSG( B, Msg ) static_assert( B, Msg ) +# endif +#else +# define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B ) +#endif + +#ifdef BOOST_BORLANDC +// +// workaround for buggy integral-constant expression support: +#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS +#endif + +#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) +// gcc 3.3 and 3.4 don't produce good error messages with the default version: +# define BOOST_SA_GCC_WORKAROUND +#endif + +// +// If the compiler issues warnings about old C style casts, +// then enable this: +// +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) ((__VA_ARGS__) != 0) +# else +# define BOOST_STATIC_ASSERT_BOOL_CAST( x ) ((x) != 0) +# endif +#else +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) (bool)(__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT_BOOL_CAST(x) (bool)(x) +# endif +#endif + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__) +# else +# define BOOST_STATIC_ASSERT( B ) static_assert(B, #B) +# endif +#else + +namespace boost{ + +// HP aCC cannot deal with missing names for template value parameters +template struct STATIC_ASSERTION_FAILURE; + +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; + +// HP aCC cannot deal with missing names for template value parameters +template struct static_assert_test{}; + +} + +// +// Implicit instantiation requires that all member declarations be +// instantiated, but that the definitions are *not* instantiated. +// +// It's not particularly clear how this applies to enum's or typedefs; +// both are described as declarations [7.1.3] and [7.2] in the standard, +// however some compilers use "delayed evaluation" of one or more of +// these when implicitly instantiating templates. We use typedef declarations +// by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum +// version gets better results from your compiler... +// +// Implementation: +// Both of these versions rely on sizeof(incomplete_type) generating an error +// message containing the name of the incomplete type. We use +// "STATIC_ASSERTION_FAILURE" as the type name here to generate +// an eye catching error message. The result of the sizeof expression is either +// used as an enum initialiser, or as a template argument depending which version +// is in use... +// Note that the argument to the assert is explicitly cast to bool using old- +// style casts: too many compilers currently have problems with static_cast +// when used inside integral constant expressions. +// +#if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) + +#if defined(BOOST_MSVC) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) +#define BOOST_STATIC_ASSERT( B ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) +#elif defined(BOOST_MSVC) +#define BOOST_STATIC_ASSERT(...) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST (__VA_ARGS__) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) +#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) +// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error +// instead of warning in case of failure +# define BOOST_STATIC_ASSERT( B ) \ + typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ + [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ] +#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && !defined(BOOST_NO_CXX11_VARIADIC_MACROS) +// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error +// instead of warning in case of failure +# define BOOST_STATIC_ASSERT(...) \ + typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ + [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >::value ] +#elif defined(__sgi) +// special version for SGI MIPSpro compiler +#define BOOST_STATIC_ASSERT( B ) \ + BOOST_STATIC_CONSTANT(bool, \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) +#elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003) +// special version for CodeWarrior <= 8.x +#define BOOST_STATIC_ASSERT( B ) \ + BOOST_STATIC_CONSTANT(int, \ + BOOST_JOIN(boost_static_assert_test_, __LINE__) = \ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) ) +#else +// generic version +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED +# else +# define BOOST_STATIC_ASSERT( B ) \ + typedef ::boost::static_assert_test<\ + sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\ + BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED +# endif +#endif + +#else +// alternative enum based implementation: +# ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_STATIC_ASSERT( ... ) \ + enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ + = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( __VA_ARGS__ ) >) } +# else +# define BOOST_STATIC_ASSERT(B) \ + enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ + = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } +# endif +#endif +#endif // defined(BOOST_NO_CXX11_STATIC_ASSERT) + +#endif // BOOST_STATIC_ASSERT_HPP + + diff --git a/src/boost/throw_exception.hpp b/src/boost/throw_exception.hpp new file mode 100644 index 00000000..7c7fcbdd --- /dev/null +++ b/src/boost/throw_exception.hpp @@ -0,0 +1,278 @@ +#ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED +#define BOOST_THROW_EXCEPTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/throw_exception.hpp +// +// Copyright (c) 2002, 2018-2022 Peter Dimov +// Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc. +// +// 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) +// +// http://www.boost.org/libs/throw_exception + +#include +#include +#include +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +#include +#endif + +#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x593) ) +# define BOOST_EXCEPTION_DISABLE +#endif + +namespace boost +{ + +#if defined( BOOST_NO_EXCEPTIONS ) + +BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined +BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_location const & loc ); // user defined + +#endif + +// boost::wrapexcept + +namespace detail +{ + +typedef char (&wrapexcept_s1)[ 1 ]; +typedef char (&wrapexcept_s2)[ 2 ]; + +template wrapexcept_s1 wrapexcept_is_convertible( T* ); +template wrapexcept_s2 wrapexcept_is_convertible( void* ); + +template( static_cast< E* >( BOOST_NULLPTR ) ) ) > struct wrapexcept_add_base; + +template struct wrapexcept_add_base +{ + struct type {}; +}; + +template struct wrapexcept_add_base +{ + typedef B type; +}; + +} // namespace detail + +template struct BOOST_SYMBOL_VISIBLE wrapexcept: + public detail::wrapexcept_add_base::type, + public E, + public detail::wrapexcept_add_base::type +{ +private: + + struct deleter + { + wrapexcept * p_; + ~deleter() { delete p_; } + }; + +private: + + void copy_from( void const* ) + { + } + + void copy_from( boost::exception const* p ) + { + static_cast( *this ) = *p; + } + +public: + + explicit wrapexcept( E const & e ): E( e ) + { + copy_from( &e ); + } + + explicit wrapexcept( E const & e, boost::source_location const & loc ): E( e ) + { + copy_from( &e ); + + set_info( *this, throw_file( loc.file_name() ) ); + set_info( *this, throw_line( static_cast( loc.line() ) ) ); + set_info( *this, throw_function( loc.function_name() ) ); + set_info( *this, throw_column( static_cast( loc.column() ) ) ); + } + + virtual boost::exception_detail::clone_base const * clone() const BOOST_OVERRIDE + { + wrapexcept * p = new wrapexcept( *this ); + deleter del = { p }; + + boost::exception_detail::copy_boost_exception( p, this ); + + del.p_ = BOOST_NULLPTR; + return p; + } + + virtual void rethrow() const BOOST_OVERRIDE + { +#if defined( BOOST_NO_EXCEPTIONS ) + + boost::throw_exception( *this ); + +#else + + throw *this; + +#endif + } +}; + +// All boost exceptions are required to derive from std::exception, +// to ensure compatibility with BOOST_NO_EXCEPTIONS. + +inline void throw_exception_assert_compatibility( std::exception const & ) {} + +// boost::throw_exception + +#if !defined( BOOST_NO_EXCEPTIONS ) + +#if defined( BOOST_EXCEPTION_DISABLE ) + +template BOOST_NORETURN void throw_exception( E const & e ) +{ + throw_exception_assert_compatibility( e ); + throw e; +} + +template BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & ) +{ + throw_exception_assert_compatibility( e ); + throw e; +} + +#else // defined( BOOST_EXCEPTION_DISABLE ) + +template BOOST_NORETURN void throw_exception( E const & e ) +{ + throw_exception_assert_compatibility( e ); + throw wrapexcept( e ); +} + +template BOOST_NORETURN void throw_exception( E const & e, boost::source_location const & loc ) +{ + throw_exception_assert_compatibility( e ); + throw wrapexcept( e, loc ); +} + +#endif // defined( BOOST_EXCEPTION_DISABLE ) + +#endif // !defined( BOOST_NO_EXCEPTIONS ) + +} // namespace boost + +// BOOST_THROW_EXCEPTION + +#define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x, BOOST_CURRENT_LOCATION) + +namespace boost +{ + +// throw_with_location + +namespace detail +{ + +struct BOOST_SYMBOL_VISIBLE throw_location +{ + boost::source_location location_; + + explicit throw_location( boost::source_location const & loc ): location_( loc ) + { + } +}; + +template class BOOST_SYMBOL_VISIBLE with_throw_location: public E, public throw_location +{ +public: + + with_throw_location( E const & e, boost::source_location const & loc ): E( e ), throw_location( loc ) + { + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + with_throw_location( E && e, boost::source_location const & loc ): E( std::move( e ) ), throw_location( loc ) + { + } + +#endif +}; + +} // namespace detail + +#if !defined(BOOST_NO_EXCEPTIONS) + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + +template BOOST_NORETURN void throw_with_location( E && e, boost::source_location const & loc = BOOST_CURRENT_LOCATION ) +{ + throw_exception_assert_compatibility( e ); + throw detail::with_throw_location::type>( std::forward( e ), loc ); +} + +#else + +template BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION ) +{ + throw_exception_assert_compatibility( e ); + throw detail::with_throw_location( e, loc ); +} + +#endif + +#else + +template BOOST_NORETURN void throw_with_location( E const & e, boost::source_location const & loc = BOOST_CURRENT_LOCATION ) +{ + boost::throw_exception( e, loc ); +} + +#endif + +// get_throw_location + +template boost::source_location get_throw_location( E const & e ) +{ +#if defined(BOOST_NO_RTTI) + + (void)e; + return boost::source_location(); + +#else + + if( detail::throw_location const* pl = dynamic_cast< detail::throw_location const* >( &e ) ) + { + return pl->location_; + } + else if( boost::exception const* px = dynamic_cast< boost::exception const* >( &e ) ) + { + return exception_detail::get_exception_throw_location( *px ); + } + else + { + return boost::source_location(); + } + +#endif +} + +} // namespace boost + +#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED diff --git a/src/boost/unordered/concurrent_flat_map.hpp b/src/boost/unordered/concurrent_flat_map.hpp new file mode 100644 index 00000000..77445d18 --- /dev/null +++ b/src/boost/unordered/concurrent_flat_map.hpp @@ -0,0 +1,1055 @@ +/* Fast open-addressing concurrent hashmap. + * + * Copyright 2023 Christian Mazakas. + * Copyright 2023-2024 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_CONCURRENT_FLAT_MAP_HPP +#define BOOST_UNORDERED_CONCURRENT_FLAT_MAP_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace boost { + namespace unordered { + template + class concurrent_flat_map + { + private: + template + friend class concurrent_flat_map; + template + friend class unordered_flat_map; + + using type_policy = detail::foa::flat_map_types; + + using table_type = + detail::foa::concurrent_table; + + table_type table_; + + template + bool friend operator==(concurrent_flat_map const& lhs, + concurrent_flat_map const& rhs); + + template + friend typename concurrent_flat_map::size_type erase_if( + concurrent_flat_map& set, Predicate pred); + + template + friend void serialize( + Archive& ar, concurrent_flat_map& c, + unsigned int version); + + public: + using key_type = Key; + using mapped_type = T; + using value_type = typename type_policy::value_type; + using init_type = typename type_policy::init_type; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using hasher = typename boost::unordered::detail::type_identity::type; + using key_equal = typename boost::unordered::detail::type_identity::type; + using allocator_type = typename boost::unordered::detail::type_identity::type; + using reference = value_type&; + using const_reference = value_type const&; + using pointer = typename boost::allocator_pointer::type; + using const_pointer = + typename boost::allocator_const_pointer::type; + static constexpr size_type bulk_visit_size = table_type::bulk_visit_size; + +#if defined(BOOST_UNORDERED_ENABLE_STATS) + using stats = typename table_type::stats; +#endif + + concurrent_flat_map() + : concurrent_flat_map(detail::foa::default_bucket_count) + { + } + + explicit concurrent_flat_map(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()) + : table_(n, hf, eql, a) + { + } + + template + concurrent_flat_map(InputIterator f, InputIterator l, + size_type n = detail::foa::default_bucket_count, + const hasher& hf = hasher(), const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()) + : table_(n, hf, eql, a) + { + this->insert(f, l); + } + + concurrent_flat_map(concurrent_flat_map const& rhs) + : table_(rhs.table_, + boost::allocator_select_on_container_copy_construction( + rhs.get_allocator())) + { + } + + concurrent_flat_map(concurrent_flat_map&& rhs) + : table_(std::move(rhs.table_)) + { + } + + template + concurrent_flat_map( + InputIterator f, InputIterator l, allocator_type const& a) + : concurrent_flat_map(f, l, 0, hasher(), key_equal(), a) + { + } + + explicit concurrent_flat_map(allocator_type const& a) + : table_(detail::foa::default_bucket_count, hasher(), key_equal(), a) + { + } + + concurrent_flat_map( + concurrent_flat_map const& rhs, allocator_type const& a) + : table_(rhs.table_, a) + { + } + + concurrent_flat_map(concurrent_flat_map&& rhs, allocator_type const& a) + : table_(std::move(rhs.table_), a) + { + } + + concurrent_flat_map(std::initializer_list il, + size_type n = detail::foa::default_bucket_count, + const hasher& hf = hasher(), const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()) + : concurrent_flat_map(n, hf, eql, a) + { + this->insert(il.begin(), il.end()); + } + + concurrent_flat_map(size_type n, const allocator_type& a) + : concurrent_flat_map(n, hasher(), key_equal(), a) + { + } + + concurrent_flat_map( + size_type n, const hasher& hf, const allocator_type& a) + : concurrent_flat_map(n, hf, key_equal(), a) + { + } + + template + concurrent_flat_map( + InputIterator f, InputIterator l, size_type n, const allocator_type& a) + : concurrent_flat_map(f, l, n, hasher(), key_equal(), a) + { + } + + template + concurrent_flat_map(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const allocator_type& a) + : concurrent_flat_map(f, l, n, hf, key_equal(), a) + { + } + + concurrent_flat_map( + std::initializer_list il, const allocator_type& a) + : concurrent_flat_map( + il, detail::foa::default_bucket_count, hasher(), key_equal(), a) + { + } + + concurrent_flat_map(std::initializer_list il, size_type n, + const allocator_type& a) + : concurrent_flat_map(il, n, hasher(), key_equal(), a) + { + } + + concurrent_flat_map(std::initializer_list il, size_type n, + const hasher& hf, const allocator_type& a) + : concurrent_flat_map(il, n, hf, key_equal(), a) + { + } + + + template + concurrent_flat_map( + unordered_flat_map&& other) + : table_(std::move(other.table_)) + { + } + + ~concurrent_flat_map() = default; + + concurrent_flat_map& operator=(concurrent_flat_map const& rhs) + { + table_ = rhs.table_; + return *this; + } + + concurrent_flat_map& operator=(concurrent_flat_map&& rhs) noexcept( + noexcept(std::declval() = std::declval())) + { + table_ = std::move(rhs.table_); + return *this; + } + + concurrent_flat_map& operator=(std::initializer_list ilist) + { + table_ = ilist; + return *this; + } + + /// Capacity + /// + + size_type size() const noexcept { return table_.size(); } + size_type max_size() const noexcept { return table_.max_size(); } + + BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept + { + return size() == 0; + } + + template + BOOST_FORCEINLINE size_type visit(key_type const& k, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.visit(k, f); + } + + template + BOOST_FORCEINLINE size_type visit(key_type const& k, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit(k, f); + } + + template + BOOST_FORCEINLINE size_type cvisit(key_type const& k, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit(k, f); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, size_type>::type + visit(K&& k, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.visit(std::forward(k), f); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, size_type>::type + visit(K&& k, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit(std::forward(k), f); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, size_type>::type + cvisit(K&& k, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit(std::forward(k), f); + } + + template + BOOST_FORCEINLINE + size_t visit(FwdIterator first, FwdIterator last, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_BULK_VISIT_ITERATOR(FwdIterator) + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.visit(first, last, f); + } + + template + BOOST_FORCEINLINE + size_t visit(FwdIterator first, FwdIterator last, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_BULK_VISIT_ITERATOR(FwdIterator) + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit(first, last, f); + } + + template + BOOST_FORCEINLINE + size_t cvisit(FwdIterator first, FwdIterator last, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_BULK_VISIT_ITERATOR(FwdIterator) + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit(first, last, f); + } + + template size_type visit_all(F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.visit_all(f); + } + + template size_type visit_all(F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit_all(f); + } + + template size_type cvisit_all(F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.cvisit_all(f); + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + typename std::enable_if::value, + void>::type + visit_all(ExecPolicy&& p, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) + table_.visit_all(p, f); + } + + template + typename std::enable_if::value, + void>::type + visit_all(ExecPolicy&& p, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) + table_.visit_all(p, f); + } + + template + typename std::enable_if::value, + void>::type + cvisit_all(ExecPolicy&& p, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) + table_.cvisit_all(p, f); + } +#endif + + template bool visit_while(F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.visit_while(f); + } + + template bool visit_while(F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.visit_while(f); + } + + template bool cvisit_while(F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.cvisit_while(f); + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + typename std::enable_if::value, + bool>::type + visit_while(ExecPolicy&& p, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) + return table_.visit_while(p, f); + } + + template + typename std::enable_if::value, + bool>::type + visit_while(ExecPolicy&& p, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) + return table_.visit_while(p, f); + } + + template + typename std::enable_if::value, + bool>::type + cvisit_while(ExecPolicy&& p, F f) const + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) + return table_.cvisit_while(p, f); + } +#endif + + /// Modifiers + /// + + template + BOOST_FORCEINLINE auto insert(Ty&& value) + -> decltype(table_.insert(std::forward(value))) + { + return table_.insert(std::forward(value)); + } + + BOOST_FORCEINLINE bool insert(init_type&& obj) + { + return table_.insert(std::move(obj)); + } + + template + size_type insert(InputIterator begin, InputIterator end) + { + size_type count_elements = 0; + for (auto pos = begin; pos != end; ++pos, ++count_elements) { + table_.emplace(*pos); + } + return count_elements; + } + + size_type insert(std::initializer_list ilist) + { + return this->insert(ilist.begin(), ilist.end()); + } + + template + BOOST_FORCEINLINE bool insert_or_assign(key_type const& k, M&& obj) + { + return table_.try_emplace_or_visit(k, std::forward(obj), + [&](value_type& m) { m.second = std::forward(obj); }); + } + + template + BOOST_FORCEINLINE bool insert_or_assign(key_type&& k, M&& obj) + { + return table_.try_emplace_or_visit(std::move(k), std::forward(obj), + [&](value_type& m) { m.second = std::forward(obj); }); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, bool>::type + insert_or_assign(K&& k, M&& obj) + { + return table_.try_emplace_or_visit(std::forward(k), + std::forward(obj), + [&](value_type& m) { m.second = std::forward(obj); }); + } + + template + BOOST_FORCEINLINE auto insert_or_visit(Ty&& value, F f) + -> decltype(table_.insert_or_visit(std::forward(value), f)) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.insert_or_visit(std::forward(value), f); + } + + template + BOOST_FORCEINLINE bool insert_or_visit(init_type&& obj, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return table_.insert_or_visit(std::move(obj), f); + } + + template + size_type insert_or_visit(InputIterator first, InputIterator last, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + size_type count_elements = 0; + for (; first != last; ++first, ++count_elements) { + table_.emplace_or_visit(*first, f); + } + return count_elements; + } + + template + size_type insert_or_visit(std::initializer_list ilist, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) + return this->insert_or_visit(ilist.begin(), ilist.end(), std::ref(f)); + } + + template + BOOST_FORCEINLINE auto insert_or_cvisit(Ty&& value, F f) + -> decltype(table_.insert_or_cvisit(std::forward(value), f)) + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.insert_or_cvisit(std::forward(value), f); + } + + template + BOOST_FORCEINLINE bool insert_or_cvisit(init_type&& obj, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return table_.insert_or_cvisit(std::move(obj), f); + } + + template + size_type insert_or_cvisit(InputIterator first, InputIterator last, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + size_type count_elements = 0; + for (; first != last; ++first, ++count_elements) { + table_.emplace_or_cvisit(*first, f); + } + return count_elements; + } + + template + size_type insert_or_cvisit(std::initializer_list ilist, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) + return this->insert_or_cvisit(ilist.begin(), ilist.end(), std::ref(f)); + } + + template + BOOST_FORCEINLINE auto insert_and_visit(Ty&& value, F1 f1, F2 f2) + -> decltype(table_.insert_and_visit(std::forward(value), f1, f2)) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F2) + return table_.insert_and_visit(std::forward(value), f1, f2); + } + + template + BOOST_FORCEINLINE bool insert_and_visit(init_type&& obj, F1 f1, F2 f2) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F2) + return table_.insert_and_visit(std::move(obj), f1, f2); + } + + template + size_type insert_and_visit( + InputIterator first, InputIterator last, F1 f1, F2 f2) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F2) + size_type count_elements = 0; + for (; first != last; ++first, ++count_elements) { + table_.emplace_and_visit(*first, f1, f2); + } + return count_elements; + } + + template + size_type insert_and_visit( + std::initializer_list ilist, F1 f1, F2 f2) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F2) + return this->insert_and_visit( + ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2)); + } + + template + BOOST_FORCEINLINE auto insert_and_cvisit(Ty&& value, F1 f1, F2 f2) + -> decltype(table_.insert_and_cvisit(std::forward(value), f1, f2)) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2) + return table_.insert_and_cvisit(std::forward(value), f1, f2); + } + + template + BOOST_FORCEINLINE bool insert_and_cvisit(init_type&& obj, F1 f1, F2 f2) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2) + return table_.insert_and_cvisit(std::move(obj), f1, f2); + } + + template + size_type insert_and_cvisit( + InputIterator first, InputIterator last, F1 f1, F2 f2) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2) + size_type count_elements = 0; + for (; first != last; ++first, ++count_elements) { + table_.emplace_and_cvisit(*first, f1, f2); + } + return count_elements; + } + + template + size_type insert_and_cvisit( + std::initializer_list ilist, F1 f1, F2 f2) + { + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F1) + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F2) + return this->insert_and_cvisit( + ilist.begin(), ilist.end(), std::ref(f1), std::ref(f2)); + } + + template BOOST_FORCEINLINE bool emplace(Args&&... args) + { + return table_.emplace(std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_or_visit(Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg, Args...) + return table_.emplace_or_visit( + std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_or_cvisit(Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg, Args...) + return table_.emplace_or_cvisit( + std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_and_visit( + Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg2, Args...) + return table_.emplace_and_visit( + std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_and_cvisit( + Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg2, Args...) + return table_.emplace_and_cvisit( + std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace(key_type const& k, Args&&... args) + { + return table_.try_emplace(k, std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace(key_type&& k, Args&&... args) + { + return table_.try_emplace(std::move(k), std::forward(args)...); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, bool>::type + try_emplace(K&& k, Args&&... args) + { + return table_.try_emplace( + std::forward(k), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_visit( + key_type const& k, Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg, Args...) + return table_.try_emplace_or_visit( + k, std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_cvisit( + key_type const& k, Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg, Args...) + return table_.try_emplace_or_cvisit( + k, std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_visit( + key_type&& k, Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg, Args...) + return table_.try_emplace_or_visit( + std::move(k), std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_cvisit( + key_type&& k, Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg, Args...) + return table_.try_emplace_or_cvisit( + std::move(k), std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_visit( + K&& k, Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg, Args...) + return table_.try_emplace_or_visit(std::forward(k), + std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_cvisit( + K&& k, Arg&& arg, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg, Args...) + return table_.try_emplace_or_cvisit(std::forward(k), + std::forward(arg), std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_visit( + key_type const& k, Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg2, Args...) + return table_.try_emplace_and_visit( + k, std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_cvisit( + key_type const& k, Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg2, Args...) + return table_.try_emplace_and_cvisit( + k, std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_visit( + key_type&& k, Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg2, Args...) + return table_.try_emplace_and_visit( + std::move(k), std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_cvisit( + key_type&& k, Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg2, Args...) + return table_.try_emplace_and_cvisit( + std::move(k), std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_visit( + K&& k, Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg2, Args...) + return table_.try_emplace_and_visit(std::forward(k), + std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_cvisit( + K&& k, Arg1&& arg1, Arg2&& arg2, Args&&... args) + { + BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( + Arg1, Arg2, Args...) + BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg2, Args...) + return table_.try_emplace_and_cvisit(std::forward(k), + std::forward(arg1), std::forward(arg2), + std::forward(args)...); + } + + BOOST_FORCEINLINE size_type erase(key_type const& k) + { + return table_.erase(k); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, size_type>::type + erase(K&& k) + { + return table_.erase(std::forward(k)); + } + + template + BOOST_FORCEINLINE size_type erase_if(key_type const& k, F f) + { + return table_.erase_if(k, f); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value && + !detail::is_execution_policy::value, + size_type>::type + erase_if(K&& k, F f) + { + return table_.erase_if(std::forward(k), f); + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + typename std::enable_if::value, + void>::type + erase_if(ExecPolicy&& p, F f) + { + BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) + table_.erase_if(p, f); + } +#endif + + template size_type erase_if(F f) { return table_.erase_if(f); } + + void swap(concurrent_flat_map& other) noexcept( + boost::allocator_is_always_equal::type::value || + boost::allocator_propagate_on_container_swap::type::value) + { + return table_.swap(other.table_); + } + + void clear() noexcept { table_.clear(); } + + template + size_type merge(concurrent_flat_map& x) + { + BOOST_ASSERT(get_allocator() == x.get_allocator()); + return table_.merge(x.table_); + } + + template + size_type merge(concurrent_flat_map&& x) + { + return merge(x); + } + + BOOST_FORCEINLINE size_type count(key_type const& k) const + { + return table_.count(k); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, size_type>::type + count(K const& k) + { + return table_.count(k); + } + + BOOST_FORCEINLINE bool contains(key_type const& k) const + { + return table_.contains(k); + } + + template + BOOST_FORCEINLINE typename std::enable_if< + detail::are_transparent::value, bool>::type + contains(K const& k) const + { + return table_.contains(k); + } + + /// Hash Policy + /// + size_type bucket_count() const noexcept { return table_.capacity(); } + + float load_factor() const noexcept { return table_.load_factor(); } + float max_load_factor() const noexcept + { + return table_.max_load_factor(); + } + void max_load_factor(float) {} + size_type max_load() const noexcept { return table_.max_load(); } + + void rehash(size_type n) { table_.rehash(n); } + void reserve(size_type n) { table_.reserve(n); } + +#if defined(BOOST_UNORDERED_ENABLE_STATS) + /// Stats + /// + stats get_stats() const { return table_.get_stats(); } + + void reset_stats() noexcept { table_.reset_stats(); } +#endif + + /// Observers + /// + allocator_type get_allocator() const noexcept + { + return table_.get_allocator(); + } + + hasher hash_function() const { return table_.hash_function(); } + key_equal key_eq() const { return table_.key_eq(); } + }; + + template + bool operator==( + concurrent_flat_map const& lhs, + concurrent_flat_map const& rhs) + { + return lhs.table_ == rhs.table_; + } + + template + bool operator!=( + concurrent_flat_map const& lhs, + concurrent_flat_map const& rhs) + { + return !(lhs == rhs); + } + + template + void swap(concurrent_flat_map& x, + concurrent_flat_map& y) + noexcept(noexcept(x.swap(y))) + { + x.swap(y); + } + + template + typename concurrent_flat_map::size_type erase_if( + concurrent_flat_map& c, Predicate pred) + { + return c.table_.erase_if(pred); + } + + template + void serialize( + Archive& ar, concurrent_flat_map& c, unsigned int) + { + ar & core::make_nvp("table",c.table_); + } + +#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES + + template >, + class Pred = + std::equal_to >, + class Allocator = std::allocator< + boost::unordered::detail::iter_to_alloc_t >, + class = std::enable_if_t >, + class = std::enable_if_t >, + class = std::enable_if_t >, + class = std::enable_if_t > > + concurrent_flat_map(InputIterator, InputIterator, + std::size_t = boost::unordered::detail::foa::default_bucket_count, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_flat_map< + boost::unordered::detail::iter_key_t, + boost::unordered::detail::iter_val_t, Hash, Pred, + Allocator>; + + template >, + class Pred = std::equal_to >, + class Allocator = std::allocator >, + class = std::enable_if_t >, + class = std::enable_if_t >, + class = std::enable_if_t > > + concurrent_flat_map(std::initializer_list >, + std::size_t = boost::unordered::detail::foa::default_bucket_count, + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_flat_map, T, Hash, Pred, + Allocator>; + + template >, + class = std::enable_if_t > > + concurrent_flat_map(InputIterator, InputIterator, std::size_t, Allocator) + -> concurrent_flat_map< + boost::unordered::detail::iter_key_t, + boost::unordered::detail::iter_val_t, + boost::hash >, + std::equal_to >, + Allocator>; + + template >, + class = std::enable_if_t > > + concurrent_flat_map(InputIterator, InputIterator, Allocator) + -> concurrent_flat_map< + boost::unordered::detail::iter_key_t, + boost::unordered::detail::iter_val_t, + boost::hash >, + std::equal_to >, + Allocator>; + + template >, + class = std::enable_if_t >, + class = std::enable_if_t > > + concurrent_flat_map( + InputIterator, InputIterator, std::size_t, Hash, Allocator) + -> concurrent_flat_map< + boost::unordered::detail::iter_key_t, + boost::unordered::detail::iter_val_t, Hash, + std::equal_to >, + Allocator>; + + template > > + concurrent_flat_map(std::initializer_list >, std::size_t, + Allocator) -> concurrent_flat_map, T, + boost::hash >, + std::equal_to >, Allocator>; + + template > > + concurrent_flat_map(std::initializer_list >, Allocator) + -> concurrent_flat_map, T, + boost::hash >, + std::equal_to >, Allocator>; + + template >, + class = std::enable_if_t > > + concurrent_flat_map(std::initializer_list >, std::size_t, + Hash, Allocator) -> concurrent_flat_map, T, + Hash, std::equal_to >, Allocator>; + +#endif + + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_CONCURRENT_FLAT_MAP_HPP diff --git a/src/boost/unordered/concurrent_flat_map_fwd.hpp b/src/boost/unordered/concurrent_flat_map_fwd.hpp new file mode 100644 index 00000000..e66f3674 --- /dev/null +++ b/src/boost/unordered/concurrent_flat_map_fwd.hpp @@ -0,0 +1,66 @@ +/* Fast open-addressing concurrent hashmap. + * + * Copyright 2023 Christian Mazakas. + * Copyright 2024 Braden Ganetsky. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_CONCURRENT_FLAT_MAP_FWD_HPP +#define BOOST_UNORDERED_CONCURRENT_FLAT_MAP_FWD_HPP + +#include +#include + +#include +#include + +#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +#include +#endif + +namespace boost { + namespace unordered { + + template , + class Pred = std::equal_to, + class Allocator = std::allocator > > + class concurrent_flat_map; + + template + bool operator==( + concurrent_flat_map const& lhs, + concurrent_flat_map const& rhs); + + template + bool operator!=( + concurrent_flat_map const& lhs, + concurrent_flat_map const& rhs); + + template + void swap(concurrent_flat_map& x, + concurrent_flat_map& y) + noexcept(noexcept(x.swap(y))); + + template + typename concurrent_flat_map::size_type erase_if( + concurrent_flat_map& c, Predicate pred); + +#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE + namespace pmr { + template , + class Pred = std::equal_to > + using concurrent_flat_map = boost::unordered::concurrent_flat_map > >; + } // namespace pmr +#endif + + } // namespace unordered + + using boost::unordered::concurrent_flat_map; +} // namespace boost + +#endif // BOOST_UNORDERED_CONCURRENT_FLAT_MAP_HPP diff --git a/src/boost/unordered/detail/allocator_constructed.hpp b/src/boost/unordered/detail/allocator_constructed.hpp new file mode 100644 index 00000000..29fb1566 --- /dev/null +++ b/src/boost/unordered/detail/allocator_constructed.hpp @@ -0,0 +1,59 @@ +/* Copyright 2024 Braden Ganetsky. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_CONSTRUCTED_HPP +#define BOOST_UNORDERED_DETAIL_ALLOCATOR_CONSTRUCTED_HPP + +#include +#include + +namespace boost { + namespace unordered { + namespace detail { + + struct allocator_policy + { + template + static void construct(Allocator& a, T* p, Args&&... args) + { + boost::allocator_construct(a, p, std::forward(args)...); + } + + template + static void destroy(Allocator& a, T* p) + { + boost::allocator_destroy(a, p); + } + }; + + /* constructs a stack-based object with the given policy and allocator */ + template + class allocator_constructed + { + opt_storage storage; + Allocator alloc; + + public: + template + allocator_constructed(Allocator const& alloc_, Args&&... args) + : alloc(alloc_) + { + Policy::construct( + alloc, storage.address(), std::forward(args)...); + } + + ~allocator_constructed() { Policy::destroy(alloc, storage.address()); } + + T& value() { return *storage.address(); } + }; + + } /* namespace detail */ + } /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/archive_constructed.hpp b/src/boost/unordered/detail/archive_constructed.hpp new file mode 100644 index 00000000..341e2dbd --- /dev/null +++ b/src/boost/unordered/detail/archive_constructed.hpp @@ -0,0 +1,71 @@ +/* Copyright 2023 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP +#define BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP + +#include + +#include +#include +#include +#include + +namespace boost{ +namespace unordered{ +namespace detail{ + +/* constructs a stack-based object from a serialization archive */ + +template +struct archive_constructed:private noncopyable +{ + template + archive_constructed(const char* name,Archive& ar,unsigned int version) + { + core::load_construct_data_adl(ar,std::addressof(get()),version); + BOOST_TRY{ + ar>>core::make_nvp(name,get()); + } + BOOST_CATCH(...){ + get().~T(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + ~archive_constructed() + { + get().~T(); + } + +#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100) +#define BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING +#endif + +#if defined(BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + + T& get(){return *space.address();} + +#if defined(BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING) +#pragma GCC diagnostic pop +#undef BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING +#endif + +private: + opt_storage space; +}; + +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/bad_archive_exception.hpp b/src/boost/unordered/detail/bad_archive_exception.hpp new file mode 100644 index 00000000..5c7f4462 --- /dev/null +++ b/src/boost/unordered/detail/bad_archive_exception.hpp @@ -0,0 +1,27 @@ +/* Copyright 2023 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP +#define BOOST_UNORDERED_DETAIL_BAD_ARCHIVE_EXCEPTION_HPP + +#include + +namespace boost{ +namespace unordered{ +namespace detail{ + +struct bad_archive_exception:std::runtime_error +{ + bad_archive_exception():std::runtime_error("Invalid or corrupted archive"){} +}; + +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/concurrent_static_asserts.hpp b/src/boost/unordered/detail/concurrent_static_asserts.hpp new file mode 100644 index 00000000..09b050bf --- /dev/null +++ b/src/boost/unordered/detail/concurrent_static_asserts.hpp @@ -0,0 +1,127 @@ +/* Copyright 2023 Christian Mazakas. + * Copyright 2023-2024 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_CONCURRENT_STATIC_ASSERTS_HPP +#define BOOST_UNORDERED_DETAIL_CONCURRENT_STATIC_ASSERTS_HPP + +#include +#include +#include +#include + +#define BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) \ + static_assert(boost::unordered::detail::is_invocable::value, \ + "The provided Callable must be invocable with value_type&"); + +#define BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) \ + static_assert( \ + boost::unordered::detail::is_invocable::value, \ + "The provided Callable must be invocable with value_type const&"); + +#if BOOST_CXX_VERSION >= 202002L + +#define BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(P) \ + static_assert(!std::is_base_of::value, \ + "ExecPolicy must be sequenced."); \ + static_assert( \ + !std::is_base_of::value, \ + "ExecPolicy must be sequenced."); + +#else + +#define BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(P) \ + static_assert(!std::is_base_of::value, \ + "ExecPolicy must be sequenced."); +#endif + +#define BOOST_UNORDERED_DETAIL_COMMA , + +#define BOOST_UNORDERED_DETAIL_LAST_ARG(Arg, Args) \ + mp11::mp_back > + +#define BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_INVOCABLE(Arg, Args) \ + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE( \ + BOOST_UNORDERED_DETAIL_LAST_ARG(Arg, Args)) + +#define BOOST_UNORDERED_STATIC_ASSERT_LAST_ARG_CONST_INVOCABLE(Arg, Args) \ + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE( \ + BOOST_UNORDERED_DETAIL_LAST_ARG(Arg, Args)) + +#define BOOST_UNORDERED_DETAIL_PENULTIMATE_ARG(Arg1, Arg2, Args) \ + mp11::mp_at_c, \ + mp11::mp_size>::value - 2> + +#define BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_INVOCABLE( \ + Arg1, Arg2, Args) \ + BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE( \ + BOOST_UNORDERED_DETAIL_PENULTIMATE_ARG(Arg1, Arg2, Args)) + +#define BOOST_UNORDERED_STATIC_ASSERT_PENULTIMATE_ARG_CONST_INVOCABLE( \ + Arg1, Arg2, Args) \ + BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE( \ + BOOST_UNORDERED_DETAIL_PENULTIMATE_ARG(Arg1, Arg2, Args)) + +namespace boost { + namespace unordered { + namespace detail { + template struct is_invocable_helper : std::false_type + { + }; + + template + struct is_invocable_helper< + void_t()(std::declval()...))>, F, + Args...> : std::true_type + { + }; + + template + using is_invocable = is_invocable_helper; + + } // namespace detail + + } // namespace unordered + +} // namespace boost + +#if defined(BOOST_NO_CXX20_HDR_CONCEPTS) +#define BOOST_UNORDERED_STATIC_ASSERT_FWD_ITERATOR(Iterator) \ + static_assert( \ + std::is_base_of< \ + std::forward_iterator_tag, \ + typename std::iterator_traits::iterator_category>::value, \ + "The provided iterator must be at least forward"); +#else +#define BOOST_UNORDERED_STATIC_ASSERT_FWD_ITERATOR(Iterator) \ + static_assert(std::forward_iterator, \ + "The provided iterator must be at least forward"); + +#endif + +#define BOOST_UNORDERED_STATIC_ASSERT_KEY_COMPATIBLE_ITERATOR(Iterator) \ + static_assert( \ + std::is_same< \ + typename std::iterator_traits::value_type, \ + key_type>::value || \ + detail::are_transparent< \ + typename std::iterator_traits::value_type, \ + hasher, key_equal>::value, \ + "The provided iterator must dereference to a compatible key value"); + +#define BOOST_UNORDERED_STATIC_ASSERT_BULK_VISIT_ITERATOR(Iterator) \ + BOOST_UNORDERED_STATIC_ASSERT_FWD_ITERATOR(Iterator) \ + BOOST_UNORDERED_STATIC_ASSERT_KEY_COMPATIBLE_ITERATOR(Iterator) + +#endif // BOOST_UNORDERED_DETAIL_CONCURRENT_STATIC_ASSERTS_HPP diff --git a/src/boost/unordered/detail/foa/concurrent_table.hpp b/src/boost/unordered/detail/foa/concurrent_table.hpp new file mode 100644 index 00000000..d2f0991c --- /dev/null +++ b/src/boost/unordered/detail/foa/concurrent_table.hpp @@ -0,0 +1,1993 @@ +/* Fast open-addressing concurrent hash table. + * + * Copyright 2023-2024 Joaquin M Lopez Munoz. + * Copyright 2024 Braden Ganetsky. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_FOA_CONCURRENT_TABLE_HPP +#define BOOST_UNORDERED_DETAIL_FOA_CONCURRENT_TABLE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_UNORDERED_DISABLE_PARALLEL_ALGORITHMS) +#if defined(BOOST_UNORDERED_ENABLE_PARALLEL_ALGORITHMS)|| \ + !defined(BOOST_NO_CXX17_HDR_EXECUTION) +#define BOOST_UNORDERED_PARALLEL_ALGORITHMS +#endif +#endif + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) +#include +#include +#endif + +namespace boost{ +namespace unordered{ +namespace detail{ + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + +template +using is_execution_policy=std::is_execution_policy< + typename std::remove_cv< + typename std::remove_reference::type + >::type +>; + +#else + +template +using is_execution_policy=std::false_type; + +#endif + +namespace foa{ + +static constexpr std::size_t cacheline_size=64; + +template +class cache_aligned_array +{ +public: + cache_aligned_array(){for(std::size_t n=0;n0;)data(n--)->~T();} + cache_aligned_array(const cache_aligned_array&)=delete; + cache_aligned_array& operator=(const cache_aligned_array&)=delete; + + T& operator[](std::size_t pos)noexcept{return *data(pos);} + +private: + static constexpr std::size_t element_offset= + (sizeof(T)+cacheline_size-1)/cacheline_size*cacheline_size; + + BOOST_UNORDERED_STATIC_ASSERT(alignof(T)<=cacheline_size); + + T* data(std::size_t pos)noexcept + { + return reinterpret_cast( + (reinterpret_cast(&buf)+cacheline_size-1)/ + cacheline_size*cacheline_size + +pos*element_offset); + } + + unsigned char buf[element_offset*N+cacheline_size-1]; +}; + +template +class multimutex +{ +public: + constexpr std::size_t size()const noexcept{return N;} + + Mutex& operator[](std::size_t pos)noexcept + { + BOOST_ASSERT(pos0;)mutexes[--n].unlock();} + +private: + cache_aligned_array mutexes; +}; + +/* std::shared_lock is C++14 */ + +template +class shared_lock +{ +public: + shared_lock(Mutex& m_)noexcept:m(m_){m.lock_shared();} + ~shared_lock()noexcept{if(owns)m.unlock_shared();} + + /* not used but VS in pre-C++17 mode needs to see it for RVO */ + shared_lock(const shared_lock&); + + void lock(){BOOST_ASSERT(!owns);m.lock_shared();owns=true;} + void unlock(){BOOST_ASSERT(owns);m.unlock_shared();owns=false;} + +private: + Mutex &m; + bool owns=true; +}; + +/* VS in pre-C++17 mode can't implement RVO for std::lock_guard due to + * its copy constructor being deleted. + */ + +template +class lock_guard +{ +public: + lock_guard(Mutex& m_)noexcept:m(m_){m.lock();} + ~lock_guard()noexcept{m.unlock();} + + /* not used but VS in pre-C++17 mode needs to see it for RVO */ + lock_guard(const lock_guard&); + +private: + Mutex &m; +}; + +/* inspired by boost/multi_index/detail/scoped_bilock.hpp */ + +template +class scoped_bilock +{ +public: + scoped_bilock(Mutex& m1,Mutex& m2)noexcept + { + bool mutex_lt=std::less{}(&m1,&m2); + + pm1=mutex_lt?&m1:&m2; + pm1->lock(); + if(&m1==&m2){ + pm2=nullptr; + } + else{ + pm2=mutex_lt?&m2:&m1; + pm2->lock(); + } + } + + /* not used but VS in pre-C++17 mode needs to see it for RVO */ + scoped_bilock(const scoped_bilock&); + + ~scoped_bilock()noexcept + { + if(pm2)pm2->unlock(); + pm1->unlock(); + } + +private: + Mutex *pm1,*pm2; +}; + +/* use atomics for group metadata storage */ + +template +struct atomic_integral +{ + operator Integral()const{return n.load(std::memory_order_relaxed);} + void operator=(Integral m){n.store(m,std::memory_order_relaxed);} + void operator|=(Integral m){n.fetch_or(m,std::memory_order_relaxed);} + void operator&=(Integral m){n.fetch_and(m,std::memory_order_relaxed);} + + atomic_integral& operator=(atomic_integral const& rhs) { + n.store(rhs.n.load(std::memory_order_relaxed),std::memory_order_relaxed); + return *this; + } + + std::atomic n; +}; + +/* Group-level concurrency protection. It provides a rw mutex plus an + * atomic insertion counter for optimistic insertion (see + * unprotected_norehash_emplace_and_visit). + */ + +struct group_access +{ + using mutex_type=rw_spinlock; + using shared_lock_guard=shared_lock; + using exclusive_lock_guard=lock_guard; + using insert_counter_type=std::atomic; + + shared_lock_guard shared_access(){return shared_lock_guard{m};} + exclusive_lock_guard exclusive_access(){return exclusive_lock_guard{m};} + insert_counter_type& insert_counter(){return cnt;} + +private: + mutex_type m; + insert_counter_type cnt{0}; +}; + +template +group_access* dummy_group_accesses() +{ + /* Default group_access array to provide to empty containers without + * incurring dynamic allocation. Mutexes won't actually ever be used, + * (no successful reduced hash match) and insertion counters won't ever + * be incremented (insertions won't succeed as capacity()==0). + */ + + static group_access accesses[Size]; + + return accesses; +} + +/* subclasses table_arrays to add an additional group_access array */ + +template +struct concurrent_table_arrays:table_arrays +{ + using group_access_allocator_type= + typename boost::allocator_rebind::type; + using group_access_pointer= + typename boost::allocator_pointer::type; + + using super=table_arrays; + using allocator_type=typename super::allocator_type; + + concurrent_table_arrays(const super& arrays,group_access_pointer pga): + super{arrays},group_accesses_{pga}{} + + group_access* group_accesses()const noexcept{ + return boost::to_address(group_accesses_); + } + + static concurrent_table_arrays new_(allocator_type al,std::size_t n) + { + super x{super::new_(al,n)}; + BOOST_TRY{ + return new_group_access(group_access_allocator_type(al),x); + } + BOOST_CATCH(...){ + super::delete_(al,x); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + static void set_group_access( + group_access_allocator_type al,concurrent_table_arrays& arrays) + { + set_group_access( + al,arrays,std::is_same{}); + } + + static void set_group_access( + group_access_allocator_type al, + concurrent_table_arrays& arrays, + std::false_type /* fancy pointers */) + { + arrays.group_accesses_= + boost::allocator_allocate(al,arrays.groups_size_mask+1); + + for(std::size_t i=0;i(); + } else { + set_group_access(al,arrays,std::false_type{}); + } + } + + static concurrent_table_arrays new_group_access( + group_access_allocator_type al,const super& x) + { + concurrent_table_arrays arrays{x,nullptr}; + set_group_access(al,arrays); + return arrays; + } + + static void delete_(allocator_type al,concurrent_table_arrays& arrays)noexcept + { + delete_group_access(group_access_allocator_type(al),arrays); + super::delete_(al,arrays); + } + + static void delete_group_access( + group_access_allocator_type al,concurrent_table_arrays& arrays)noexcept + { + if(arrays.elements()){ + boost::allocator_deallocate( + al,arrays.group_accesses_,arrays.groups_size_mask+1); + } + } + + group_access_pointer group_accesses_; +}; + +struct atomic_size_control +{ + static constexpr auto atomic_size_t_size=sizeof(std::atomic); + BOOST_UNORDERED_STATIC_ASSERT(atomic_size_t_size ml; + unsigned char pad1_[cacheline_size-atomic_size_t_size]; + std::atomic size; +}; + +/* std::swap can't be used on non-assignable atomics */ + +inline void +swap_atomic_size_t(std::atomic& x,std::atomic& y) +{ + std::size_t tmp=x; + x=static_cast(y); + y=tmp; +} + +inline void swap(atomic_size_control& x,atomic_size_control& y) +{ + swap_atomic_size_t(x.ml,y.ml); + swap_atomic_size_t(x.size,y.size); +} + +/* foa::concurrent_table serves as the foundation for end-user concurrent + * hash containers. + * + * The exposed interface (completed by the wrapping containers) is not that + * of a regular container (in fact, it does not model Container as understood + * by the C++ standard): + * + * - Iterators are not provided as they are not suitable for concurrent + * scenarios. + * - As a consequence, composite operations with regular containers + * (like, for instance, looking up an element and modifying it), must + * be provided natively without any intervening iterator/accesor. + * Visitation is a core concept in this design, either on its own (eg. + * visit(k) locates the element with key k *and* accesses it) or as part + * of a native composite operation (eg. try_emplace_or_visit). Visitation + * is constant or mutating depending on whether the used table function is + * const or not. + * - The API provides member functions for all the meaningful composite + * operations of the form "X (and|or) Y", where X, Y are one of the + * primitives FIND, ACCESS, INSERT or ERASE. + * - Parallel versions of [c]visit_all(f) and erase_if(f) are provided based + * on C++17 stdlib parallel algorithms. + * + * Consult boost::concurrent_(flat|node)_(map|set) docs for the full API + * reference. Heterogeneous lookup is suported by default, that is, without + * checking for any ::is_transparent typedefs --this checking is done by the + * wrapping containers. + * + * Thread-safe concurrency is implemented using a two-level lock system: + * + * - A first container-level lock is implemented with an array of + * rw spinlocks acting as a single rw mutex with very little + * cache-coherence traffic on read (each thread is assigned a different + * spinlock in the array). Container-level write locking is only used for + * rehashing and other container-wide operations (assignment, swap, etc.) + * - Each group of slots has an associated rw spinlock. A thread holds + * at most one group lock at any given time. Lookup is implemented in + * a (groupwise) lock-free manner until a reduced hash match is found, in + * which case the relevant group is locked and the slot is double-checked + * for occupancy and compared with the key. + * - Each group has also an associated so-called insertion counter used for + * the following optimistic insertion algorithm: + * - The value of the insertion counter for the initial group in the probe + * sequence is locally recorded (let's call this value c0). + * - Lookup is as described above. If lookup finds no equivalent element, + * search for an available slot for insertion successively locks/unlocks + * each group in the probing sequence. + * - When an available slot is located, it is preemptively occupied (its + * reduced hash value is set) and the insertion counter is atomically + * incremented: if no other thread has incremented the counter during the + * whole operation (which is checked by comparing with c0), then we're + * good to go and complete the insertion, otherwise we roll back and + * start over. + */ + +template +class table; /* concurrent/non-concurrent interop */ + +template +using concurrent_table_core_impl=table_core< + TypePolicy,group15,concurrent_table_arrays, + atomic_size_control,Hash,Pred,Allocator>; + +#include + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4714) /* marked as __forceinline not inlined */ +#endif + +template +class concurrent_table: + concurrent_table_core_impl +{ + using super=concurrent_table_core_impl; + using type_policy=typename super::type_policy; + using group_type=typename super::group_type; + using super::N; + using prober=typename super::prober; + using arrays_type=typename super::arrays_type; + using size_ctrl_type=typename super::size_ctrl_type; + using compatible_nonconcurrent_table=table; + friend compatible_nonconcurrent_table; + +public: + using key_type=typename super::key_type; + using init_type=typename super::init_type; + using value_type=typename super::value_type; + using element_type=typename super::element_type; + using hasher=typename super::hasher; + using key_equal=typename super::key_equal; + using allocator_type=typename super::allocator_type; + using size_type=typename super::size_type; + static constexpr std::size_t bulk_visit_size=16; + +#if defined(BOOST_UNORDERED_ENABLE_STATS) + using stats=typename super::stats; +#endif + +private: + template + using enable_if_is_value_type=typename std::enable_if< + !std::is_same::value&& + std::is_same::value, + T + >::type; + +public: + concurrent_table( + std::size_t n=default_bucket_count,const Hash& h_=Hash(), + const Pred& pred_=Pred(),const Allocator& al_=Allocator()): + super{n,h_,pred_,al_} + {} + + concurrent_table(const concurrent_table& x): + concurrent_table(x,x.exclusive_access()){} + concurrent_table(concurrent_table&& x): + concurrent_table(std::move(x),x.exclusive_access()){} + concurrent_table(const concurrent_table& x,const Allocator& al_): + concurrent_table(x,al_,x.exclusive_access()){} + concurrent_table(concurrent_table&& x,const Allocator& al_): + concurrent_table(std::move(x),al_,x.exclusive_access()){} + + template + concurrent_table( + compatible_nonconcurrent_table&& x, + arrays_holder&& ah): + super{ + std::move(x.h()),std::move(x.pred()),std::move(x.al()), + [&x]{return arrays_type::new_group_access( + x.al(),typename arrays_type::super{ + x.arrays.groups_size_index,x.arrays.groups_size_mask, + to_pointer( + reinterpret_cast(x.arrays.groups())), + x.arrays.elements_});}, + size_ctrl_type{x.size_ctrl.ml,x.size_ctrl.size}} + { + x.arrays=ah.release(); + x.size_ctrl.ml=x.initial_max_load(); + x.size_ctrl.size=0; + BOOST_UNORDERED_SWAP_STATS(this->cstats,x.cstats); + } + + concurrent_table(compatible_nonconcurrent_table&& x): + concurrent_table(std::move(x),x.make_empty_arrays()) + {} + + ~concurrent_table()=default; + + concurrent_table& operator=(const concurrent_table& x) + { + auto lck=exclusive_access(*this,x); + super::operator=(x); + return *this; + } + + concurrent_table& operator=(concurrent_table&& x)noexcept( + noexcept(std::declval() = std::declval())) + { + auto lck=exclusive_access(*this,x); + super::operator=(std::move(x)); + return *this; + } + + concurrent_table& operator=(std::initializer_list il) { + auto lck=exclusive_access(); + super::clear(); + super::noshrink_reserve(il.size()); + for (auto const& v : il) { + this->unprotected_emplace(v); + } + return *this; + } + + allocator_type get_allocator()const noexcept + { + auto lck=shared_access(); + return super::get_allocator(); + } + + template + BOOST_FORCEINLINE std::size_t visit(const Key& x,F&& f) + { + return visit_impl(group_exclusive{},x,std::forward(f)); + } + + template + BOOST_FORCEINLINE std::size_t visit(const Key& x,F&& f)const + { + return visit_impl(group_shared{},x,std::forward(f)); + } + + template + BOOST_FORCEINLINE std::size_t cvisit(const Key& x,F&& f)const + { + return visit(x,std::forward(f)); + } + + template + BOOST_FORCEINLINE + std::size_t visit(FwdIterator first,FwdIterator last,F&& f) + { + return bulk_visit_impl(group_exclusive{},first,last,std::forward(f)); + } + + template + BOOST_FORCEINLINE + std::size_t visit(FwdIterator first,FwdIterator last,F&& f)const + { + return bulk_visit_impl(group_shared{},first,last,std::forward(f)); + } + + template + BOOST_FORCEINLINE + std::size_t cvisit(FwdIterator first,FwdIterator last,F&& f)const + { + return visit(first,last,std::forward(f)); + } + + template std::size_t visit_all(F&& f) + { + return visit_all_impl(group_exclusive{},std::forward(f)); + } + + template std::size_t visit_all(F&& f)const + { + return visit_all_impl(group_shared{},std::forward(f)); + } + + template std::size_t cvisit_all(F&& f)const + { + return visit_all(std::forward(f)); + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + void visit_all(ExecutionPolicy&& policy,F&& f) + { + visit_all_impl( + group_exclusive{}, + std::forward(policy),std::forward(f)); + } + + template + void visit_all(ExecutionPolicy&& policy,F&& f)const + { + visit_all_impl( + group_shared{}, + std::forward(policy),std::forward(f)); + } + + template + void cvisit_all(ExecutionPolicy&& policy,F&& f)const + { + visit_all(std::forward(policy),std::forward(f)); + } +#endif + + template bool visit_while(F&& f) + { + return visit_while_impl(group_exclusive{},std::forward(f)); + } + + template bool visit_while(F&& f)const + { + return visit_while_impl(group_shared{},std::forward(f)); + } + + template bool cvisit_while(F&& f)const + { + return visit_while(std::forward(f)); + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + bool visit_while(ExecutionPolicy&& policy,F&& f) + { + return visit_while_impl( + group_exclusive{}, + std::forward(policy),std::forward(f)); + } + + template + bool visit_while(ExecutionPolicy&& policy,F&& f)const + { + return visit_while_impl( + group_shared{}, + std::forward(policy),std::forward(f)); + } + + template + bool cvisit_while(ExecutionPolicy&& policy,F&& f)const + { + return visit_while( + std::forward(policy),std::forward(f)); + } +#endif + + bool empty()const noexcept{return size()==0;} + + std::size_t size()const noexcept + { + auto lck=shared_access(); + return unprotected_size(); + } + + using super::max_size; + + template + BOOST_FORCEINLINE bool emplace(Args&&... args) + { + return construct_and_emplace(std::forward(args)...); + } + + /* Optimization for value_type and init_type, to avoid constructing twice */ + template + BOOST_FORCEINLINE auto emplace(Value&& x)->typename std::enable_if< + detail::is_similar_to_any::value,bool>::type + { + return emplace_impl(std::forward(x)); + } + + /* Optimizations for maps for (k,v) to avoid eagerly constructing value */ + template + BOOST_FORCEINLINE auto emplace(K&& k, V&& v) -> + typename std::enable_if::value, + bool>::type + { + alloc_cted_or_fwded_key_type x( + this->al(), std::forward(k)); + return emplace_impl( + try_emplace_args_t{}, x.move_or_fwd(), std::forward(v)); + } + + BOOST_FORCEINLINE bool + insert(const init_type& x){return emplace_impl(x);} + + BOOST_FORCEINLINE bool + insert(init_type&& x){return emplace_impl(std::move(x));} + + /* template tilts call ambiguities in favor of init_type */ + + template + BOOST_FORCEINLINE bool + insert(const value_type& x){return emplace_impl(x);} + + template + BOOST_FORCEINLINE bool + insert(value_type&& x){return emplace_impl(std::move(x));} + + template + BOOST_FORCEINLINE + typename std::enable_if< + !std::is_same::value, + bool + >::type + insert(element_type&& x){return emplace_impl(std::move(x));} + + template + BOOST_FORCEINLINE bool try_emplace(Key&& x,Args&&... args) + { + return emplace_impl( + try_emplace_args_t{},std::forward(x),std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_visit(Key&& x,Args&&... args) + { + return emplace_or_visit_flast( + group_exclusive{}, + try_emplace_args_t{},std::forward(x),std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_or_cvisit(Key&& x,Args&&... args) + { + return emplace_or_visit_flast( + group_shared{}, + try_emplace_args_t{},std::forward(x),std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_visit(Key&& x,Args&&... args) + { + return emplace_and_visit_flast( + group_exclusive{}, + try_emplace_args_t{},std::forward(x),std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool try_emplace_and_cvisit(Key&& x,Args&&... args) + { + return emplace_and_visit_flast( + group_shared{}, + try_emplace_args_t{},std::forward(x),std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_or_visit(Args&&... args) + { + return construct_and_emplace_or_visit_flast( + group_exclusive{},std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_or_cvisit(Args&&... args) + { + return construct_and_emplace_or_visit_flast( + group_shared{},std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_and_visit(Args&&... args) + { + return construct_and_emplace_and_visit_flast( + group_exclusive{},std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_and_cvisit(Args&&... args) + { + return construct_and_emplace_and_visit_flast( + group_shared{},std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool insert_or_visit(Value&& x,F&& f) + { + return insert_and_visit( + std::forward(x),[](const value_type&){},std::forward(f)); + } + + template + BOOST_FORCEINLINE bool insert_or_cvisit(Value&& x,F&& f) + { + return insert_and_cvisit( + std::forward(x),[](const value_type&){},std::forward(f)); + } + + template + BOOST_FORCEINLINE bool insert_and_visit(const init_type& x,F1&& f1,F2&& f2) + { + return emplace_and_visit_impl( + group_exclusive{},std::forward(f1),std::forward(f2),x); + } + + template + BOOST_FORCEINLINE bool insert_and_cvisit(const init_type& x,F1&& f1,F2&& f2) + { + return emplace_and_visit_impl( + group_shared{},std::forward(f1),std::forward(f2),x); + } + + template + BOOST_FORCEINLINE bool insert_and_visit(init_type&& x,F1&& f1,F2&& f2) + { + return emplace_and_visit_impl( + group_exclusive{},std::forward(f1),std::forward(f2), + std::move(x)); + } + + template + BOOST_FORCEINLINE bool insert_and_cvisit(init_type&& x,F1&& f1,F2&& f2) + { + return emplace_and_visit_impl( + group_shared{},std::forward(f1),std::forward(f2),std::move(x)); + } + + /* SFINAE tilts call ambiguities in favor of init_type */ + + template + BOOST_FORCEINLINE auto insert_and_visit(const Value& x,F1&& f1,F2&& f2) + ->enable_if_is_value_type + { + return emplace_and_visit_impl( + group_exclusive{},std::forward(f1),std::forward(f2),x); + } + + template + BOOST_FORCEINLINE auto insert_and_cvisit(const Value& x,F1&& f1,F2&& f2) + ->enable_if_is_value_type + { + return emplace_and_visit_impl( + group_shared{},std::forward(f1),std::forward(f2),x); + } + + template + BOOST_FORCEINLINE auto insert_and_visit(Value&& x,F1&& f1,F2&& f2) + ->enable_if_is_value_type + { + return emplace_and_visit_impl( + group_exclusive{},std::forward(f1),std::forward(f2), + std::move(x)); + } + + template + BOOST_FORCEINLINE auto insert_and_cvisit(Value&& x,F1&& f1,F2&& f2) + ->enable_if_is_value_type + { + return emplace_and_visit_impl( + group_shared{},std::forward(f1),std::forward(f2),std::move(x)); + } + + template + BOOST_FORCEINLINE + typename std::enable_if< + !std::is_same::value, + bool + >::type + insert_and_visit(element_type&& x,F1&& f1,F2&& f2) + { + return emplace_and_visit_impl( + group_exclusive{},std::forward(f1),std::forward(f2), + std::move(x)); + } + + template + BOOST_FORCEINLINE + typename std::enable_if< + !std::is_same::value, + bool + >::type + insert_and_cvisit(element_type&& x,F1&& f1,F2&& f2) + { + return emplace_and_visit_impl( + group_shared{},std::forward(f1),std::forward(f2),std::move(x)); + } + + template + BOOST_FORCEINLINE std::size_t erase(const Key& x) + { + return erase_if(x,[](const value_type&){return true;}); + } + + template + BOOST_FORCEINLINE auto erase_if(const Key& x,F&& f)->typename std::enable_if< + !is_execution_policy::value,std::size_t>::type + { + auto lck=shared_access(); + auto hash=this->hash_for(x); + std::size_t res=0; + unprotected_internal_visit( + group_exclusive{},x,this->position_for(hash),hash, + [&,this](group_type* pg,unsigned int n,element_type* p) + { + if(f(cast_for(group_exclusive{},type_policy::value_from(*p)))){ + super::erase(pg,n,p); + res=1; + } + }); + return res; + } + + template + std::size_t erase_if(F&& f) + { + auto lck=shared_access(); + std::size_t res=0; + for_all_elements( + group_exclusive{}, + [&,this](group_type* pg,unsigned int n,element_type* p){ + if(f(cast_for(group_exclusive{},type_policy::value_from(*p)))){ + super::erase(pg,n,p); + ++res; + } + }); + return res; + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + auto erase_if(ExecutionPolicy&& policy,F&& f)->typename std::enable_if< + is_execution_policy::value,void>::type + { + auto lck=shared_access(); + for_all_elements( + group_exclusive{},std::forward(policy), + [&,this](group_type* pg,unsigned int n,element_type* p){ + if(f(cast_for(group_exclusive{},type_policy::value_from(*p)))){ + super::erase(pg,n,p); + } + }); + } +#endif + + void swap(concurrent_table& x) + noexcept(noexcept(std::declval().swap(std::declval()))) + { + auto lck=exclusive_access(*this,x); + super::swap(x); + } + + void clear()noexcept + { + auto lck=exclusive_access(); + super::clear(); + } + + template + BOOST_FORCEINLINE void extract(const Key& x,Extractor&& ext) + { + extract_if( + x,[](const value_type&){return true;},std::forward(ext)); + } + + template + BOOST_FORCEINLINE void extract_if(const Key& x,F&& f,Extractor&& ext) + { + auto lck=shared_access(); + auto hash=this->hash_for(x); + unprotected_internal_visit( + group_exclusive{},x,this->position_for(hash),hash, + [&,this](group_type* pg,unsigned int n,element_type* p) + { + if(f(cast_for(group_exclusive{},type_policy::value_from(*p)))){ + ext(std::move(*p),this->al()); + super::erase(pg,n,p); + } + }); + } + + // TODO: should we accept different allocator too? + template + size_type merge(concurrent_table& x) + { + using merge_table_type=concurrent_table; + using super2=typename merge_table_type::super; + + // for clang + boost::ignore_unused(); + + auto lck=exclusive_access(*this,x); + size_type s=super::size(); + x.super2::for_all_elements( /* super2::for_all_elements -> unprotected */ + [&,this](group_type* pg,unsigned int n,element_type* p){ + typename merge_table_type::erase_on_exit e{x,pg,n,p}; + if(!unprotected_emplace(type_policy::move(*p)))e.rollback(); + }); + return size_type{super::size()-s}; + } + + template + void merge(concurrent_table&& x){merge(x);} + + hasher hash_function()const + { + auto lck=shared_access(); + return super::hash_function(); + } + + key_equal key_eq()const + { + auto lck=shared_access(); + return super::key_eq(); + } + + template + BOOST_FORCEINLINE std::size_t count(Key&& x)const + { + return (std::size_t)contains(std::forward(x)); + } + + template + BOOST_FORCEINLINE bool contains(Key&& x)const + { + return visit(std::forward(x),[](const value_type&){})!=0; + } + + std::size_t capacity()const noexcept + { + auto lck=shared_access(); + return super::capacity(); + } + + float load_factor()const noexcept + { + auto lck=shared_access(); + if(super::capacity()==0)return 0; + else return float(unprotected_size())/ + float(super::capacity()); + } + + using super::max_load_factor; + + std::size_t max_load()const noexcept + { + auto lck=shared_access(); + return super::max_load(); + } + + void rehash(std::size_t n) + { + auto lck=exclusive_access(); + super::rehash(n); + } + + void reserve(std::size_t n) + { + auto lck=exclusive_access(); + super::reserve(n); + } + +#if defined(BOOST_UNORDERED_ENABLE_STATS) + /* already thread safe */ + + using super::get_stats; + using super::reset_stats; +#endif + + template + friend std::size_t erase_if(concurrent_table& x,Predicate&& pr) + { + return x.erase_if(std::forward(pr)); + } + + friend bool operator==(const concurrent_table& x,const concurrent_table& y) + { + auto lck=exclusive_access(x,y); + return static_cast(x)==static_cast(y); + } + + friend bool operator!=(const concurrent_table& x,const concurrent_table& y) + { + return !(x==y); + } + +private: + template friend class concurrent_table; + + using mutex_type=rw_spinlock; + using multimutex_type=multimutex; // TODO: adapt 128 to the machine + using shared_lock_guard=reentrancy_checked>; + using exclusive_lock_guard=reentrancy_checked>; + using exclusive_bilock_guard= + reentrancy_bichecked>; + using group_shared_lock_guard=typename group_access::shared_lock_guard; + using group_exclusive_lock_guard=typename group_access::exclusive_lock_guard; + using group_insert_counter_type=typename group_access::insert_counter_type; + + concurrent_table(const concurrent_table& x,exclusive_lock_guard): + super{x}{} + concurrent_table(concurrent_table&& x,exclusive_lock_guard): + super{std::move(x)}{} + concurrent_table( + const concurrent_table& x,const Allocator& al_,exclusive_lock_guard): + super{x,al_}{} + concurrent_table( + concurrent_table&& x,const Allocator& al_,exclusive_lock_guard): + super{std::move(x),al_}{} + + inline shared_lock_guard shared_access()const + { + thread_local auto id=(++thread_counter)%mutexes.size(); + + return shared_lock_guard{this,mutexes[id]}; + } + + inline exclusive_lock_guard exclusive_access()const + { + return exclusive_lock_guard{this,mutexes}; + } + + static inline exclusive_bilock_guard exclusive_access( + const concurrent_table& x,const concurrent_table& y) + { + return {&x,&y,x.mutexes,y.mutexes}; + } + + template + static inline exclusive_bilock_guard exclusive_access( + const concurrent_table& x, + const concurrent_table& y) + { + return {&x,&y,x.mutexes,y.mutexes}; + } + + /* Tag-dispatched shared/exclusive group access */ + + using group_shared=std::false_type; + using group_exclusive=std::true_type; + + inline group_shared_lock_guard access(group_shared,std::size_t pos)const + { + return this->arrays.group_accesses()[pos].shared_access(); + } + + inline group_exclusive_lock_guard access( + group_exclusive,std::size_t pos)const + { + return this->arrays.group_accesses()[pos].exclusive_access(); + } + + inline group_insert_counter_type& insert_counter(std::size_t pos)const + { + return this->arrays.group_accesses()[pos].insert_counter(); + } + + /* Const casts value_type& according to the level of group access for + * safe passing to visitation functions. When type_policy is set-like, + * access is always const regardless of group access. + */ + + static inline const value_type& + cast_for(group_shared,value_type& x){return x;} + + static inline typename std::conditional< + std::is_same::value, + const value_type&, + value_type& + >::type + cast_for(group_exclusive,value_type& x){return x;} + + struct erase_on_exit + { + erase_on_exit( + concurrent_table& x_, + group_type* pg_,unsigned int pos_,element_type* p_): + x(x_),pg(pg_),pos(pos_),p(p_){} + ~erase_on_exit(){if(!rollback_)x.super::erase(pg,pos,p);} + + void rollback(){rollback_=true;} + + concurrent_table &x; + group_type *pg; + unsigned int pos; + element_type *p; + bool rollback_=false; + }; + + template + BOOST_FORCEINLINE std::size_t visit_impl( + GroupAccessMode access_mode,const Key& x,F&& f)const + { + auto lck=shared_access(); + auto hash=this->hash_for(x); + return unprotected_visit( + access_mode,x,this->position_for(hash),hash,std::forward(f)); + } + + template + BOOST_FORCEINLINE + std::size_t bulk_visit_impl( + GroupAccessMode access_mode,FwdIterator first,FwdIterator last,F&& f)const + { + auto lck=shared_access(); + std::size_t res=0; + auto n=static_cast(std::distance(first,last)); + while(n){ + auto m=n<2*bulk_visit_size?n:bulk_visit_size; + res+=unprotected_bulk_visit(access_mode,first,m,std::forward(f)); + n-=m; + std::advance( + first, + static_cast< + typename std::iterator_traits::difference_type>(m)); + } + return res; + } + + template + std::size_t visit_all_impl(GroupAccessMode access_mode,F&& f)const + { + auto lck=shared_access(); + std::size_t res=0; + for_all_elements(access_mode,[&](element_type* p){ + f(cast_for(access_mode,type_policy::value_from(*p))); + ++res; + }); + return res; + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + void visit_all_impl( + GroupAccessMode access_mode,ExecutionPolicy&& policy,F&& f)const + { + auto lck=shared_access(); + for_all_elements( + access_mode,std::forward(policy), + [&](element_type* p){ + f(cast_for(access_mode,type_policy::value_from(*p))); + }); + } +#endif + + template + bool visit_while_impl(GroupAccessMode access_mode,F&& f)const + { + auto lck=shared_access(); + return for_all_elements_while(access_mode,[&](element_type* p){ + return f(cast_for(access_mode,type_policy::value_from(*p))); + }); + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + bool visit_while_impl( + GroupAccessMode access_mode,ExecutionPolicy&& policy,F&& f)const + { + auto lck=shared_access(); + return for_all_elements_while( + access_mode,std::forward(policy), + [&](element_type* p){ + return f(cast_for(access_mode,type_policy::value_from(*p))); + }); + } +#endif + + template + BOOST_FORCEINLINE std::size_t unprotected_visit( + GroupAccessMode access_mode, + const Key& x,std::size_t pos0,std::size_t hash,F&& f)const + { + return unprotected_internal_visit( + access_mode,x,pos0,hash, + [&](group_type*,unsigned int,element_type* p) + {f(cast_for(access_mode,type_policy::value_from(*p)));}); + } + +#if defined(BOOST_MSVC) +/* warning: forcing value to bool 'true' or 'false' in bool(pred()...) */ +#pragma warning(push) +#pragma warning(disable:4800) +#endif + + template + BOOST_FORCEINLINE std::size_t unprotected_internal_visit( + GroupAccessMode access_mode, + const Key& x,std::size_t pos0,std::size_t hash,F&& f)const + { + BOOST_UNORDERED_STATS_COUNTER(num_cmps); + prober pb(pos0); + do{ + auto pos=pb.get(); + auto pg=this->arrays.groups()+pos; + auto mask=pg->match(hash); + if(mask){ + auto p=this->arrays.elements()+pos*N; + BOOST_UNORDERED_PREFETCH_ELEMENTS(p,N); + auto lck=access(access_mode,pos); + do{ + auto n=unchecked_countr_zero(mask); + if(BOOST_LIKELY(pg->is_occupied(n))){ + BOOST_UNORDERED_INCREMENT_STATS_COUNTER(num_cmps); + if(BOOST_LIKELY(bool(this->pred()(x,this->key_from(p[n]))))){ + f(pg,n,p+n); + BOOST_UNORDERED_ADD_STATS( + this->cstats.successful_lookup,(pb.length(),num_cmps)); + return 1; + } + } + mask&=mask-1; + }while(mask); + } + if(BOOST_LIKELY(pg->is_not_overflowed(hash))){ + BOOST_UNORDERED_ADD_STATS( + this->cstats.unsuccessful_lookup,(pb.length(),num_cmps)); + return 0; + } + } + while(BOOST_LIKELY(pb.next(this->arrays.groups_size_mask))); + BOOST_UNORDERED_ADD_STATS( + this->cstats.unsuccessful_lookup,(pb.length(),num_cmps)); + return 0; + } + + template + BOOST_FORCEINLINE std::size_t unprotected_bulk_visit( + GroupAccessMode access_mode,FwdIterator first,std::size_t m,F&& f)const + { + BOOST_ASSERT(m<2*bulk_visit_size); + + std::size_t res=0, + hashes[2*bulk_visit_size-1], + positions[2*bulk_visit_size-1]; + int masks[2*bulk_visit_size-1]; + auto it=first; + + for(auto i=m;i--;++it){ + auto hash=hashes[i]=this->hash_for(*it); + auto pos=positions[i]=this->position_for(hash); + BOOST_UNORDERED_PREFETCH(this->arrays.groups()+pos); + } + + for(auto i=m;i--;){ + auto hash=hashes[i]; + auto pos=positions[i]; + auto mask=masks[i]=(this->arrays.groups()+pos)->match(hash); + if(mask){ + BOOST_UNORDERED_PREFETCH(this->arrays.group_accesses()+pos); + BOOST_UNORDERED_PREFETCH( + this->arrays.elements()+pos*N+unchecked_countr_zero(mask)); + } + } + + it=first; + for(auto i=m;i--;++it){ + BOOST_UNORDERED_STATS_COUNTER(num_cmps); + auto pos=positions[i]; + prober pb(pos); + auto pg=this->arrays.groups()+pos; + auto mask=masks[i]; + element_type *p; + if(!mask)goto post_mask; + p=this->arrays.elements()+pos*N; + for(;;){ + { + auto lck=access(access_mode,pos); + do{ + auto n=unchecked_countr_zero(mask); + if(BOOST_LIKELY(pg->is_occupied(n))){ + BOOST_UNORDERED_INCREMENT_STATS_COUNTER(num_cmps); + if(bool(this->pred()(*it,this->key_from(p[n])))){ + f(cast_for(access_mode,type_policy::value_from(p[n]))); + ++res; + BOOST_UNORDERED_ADD_STATS( + this->cstats.successful_lookup,(pb.length(),num_cmps)); + goto next_key; + } + } + mask&=mask-1; + }while(mask); + } + post_mask: + do{ + if(BOOST_LIKELY(pg->is_not_overflowed(hashes[i]))|| + BOOST_UNLIKELY(!pb.next(this->arrays.groups_size_mask))){ + BOOST_UNORDERED_ADD_STATS( + this->cstats.unsuccessful_lookup,(pb.length(),num_cmps)); + goto next_key; + } + pos=pb.get(); + pg=this->arrays.groups()+pos; + mask=pg->match(hashes[i]); + }while(!mask); + p=this->arrays.elements()+pos*N; + BOOST_UNORDERED_PREFETCH_ELEMENTS(p,N); + } + next_key:; + } + return res; + } + +#if defined(BOOST_MSVC) +#pragma warning(pop) /* C4800 */ +#endif + + std::size_t unprotected_size()const + { + std::size_t m=this->size_ctrl.ml; + std::size_t s=this->size_ctrl.size; + return s<=m?s:m; + } + + template + BOOST_FORCEINLINE bool construct_and_emplace(Args&&... args) + { + return construct_and_emplace_or_visit( + group_shared{},[](const value_type&){},std::forward(args)...); + } + + struct call_construct_and_emplace_or_visit + { + template + BOOST_FORCEINLINE bool operator()( + concurrent_table* this_,Args&&... args)const + { + return this_->construct_and_emplace_or_visit( + std::forward(args)...); + } + }; + + template + BOOST_FORCEINLINE bool construct_and_emplace_or_visit_flast( + GroupAccessMode access_mode,Args&&... args) + { + return mp11::tuple_apply( + call_construct_and_emplace_or_visit{}, + std::tuple_cat( + std::make_tuple(this,access_mode), + tuple_rotate_right(std::forward_as_tuple(std::forward(args)...)) + ) + ); + } + + struct call_construct_and_emplace_and_visit + { + template + BOOST_FORCEINLINE bool operator()( + concurrent_table* this_,Args&&... args)const + { + return this_->construct_and_emplace_and_visit( + std::forward(args)...); + } + }; + + template + BOOST_FORCEINLINE bool construct_and_emplace_and_visit_flast( + GroupAccessMode access_mode,Args&&... args) + { + return mp11::tuple_apply( + call_construct_and_emplace_and_visit{}, + std::tuple_cat( + std::make_tuple(this,access_mode), + tuple_rotate_right<2>( + std::forward_as_tuple(std::forward(args)...)) + ) + ); + } + + template + BOOST_FORCEINLINE bool construct_and_emplace_or_visit( + GroupAccessMode access_mode,F&& f,Args&&... args) + { + return construct_and_emplace_and_visit( + access_mode,[](const value_type&){},std::forward(f), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool construct_and_emplace_and_visit( + GroupAccessMode access_mode,F1&& f1,F2&& f2,Args&&... args) + { + auto lck=shared_access(); + + alloc_cted_insert_type x( + this->al(),std::forward(args)...); + int res=unprotected_norehash_emplace_and_visit( + access_mode,std::forward(f1),std::forward(f2), + type_policy::move(x.value())); + if(BOOST_LIKELY(res>=0))return res!=0; + + lck.unlock(); + + rehash_if_full(); + return noinline_emplace_and_visit( + access_mode,std::forward(f1),std::forward(f2), + type_policy::move(x.value())); + } + + template + BOOST_FORCEINLINE bool emplace_impl(Args&&... args) + { + return emplace_or_visit_impl( + group_shared{},[](const value_type&){},std::forward(args)...); + } + + template + BOOST_NOINLINE bool noinline_emplace_or_visit( + GroupAccessMode access_mode,F&& f,Args&&... args) + { + return emplace_or_visit_impl( + access_mode,std::forward(f),std::forward(args)...); + } + + template + BOOST_NOINLINE bool noinline_emplace_and_visit( + GroupAccessMode access_mode,F1&& f1,F2&& f2,Args&&... args) + { + return emplace_and_visit_impl( + access_mode,std::forward(f1),std::forward(f2), + std::forward(args)...); + } + + struct call_emplace_or_visit_impl + { + template + BOOST_FORCEINLINE bool operator()( + concurrent_table* this_,Args&&... args)const + { + return this_->emplace_or_visit_impl(std::forward(args)...); + } + }; + + template + BOOST_FORCEINLINE bool emplace_or_visit_flast( + GroupAccessMode access_mode,Args&&... args) + { + return mp11::tuple_apply( + call_emplace_or_visit_impl{}, + std::tuple_cat( + std::make_tuple(this,access_mode), + tuple_rotate_right(std::forward_as_tuple(std::forward(args)...)) + ) + ); + } + + struct call_emplace_and_visit_impl + { + template + BOOST_FORCEINLINE bool operator()( + concurrent_table* this_,Args&&... args)const + { + return this_->emplace_and_visit_impl(std::forward(args)...); + } + }; + + template + BOOST_FORCEINLINE bool emplace_and_visit_flast( + GroupAccessMode access_mode,Args&&... args) + { + return mp11::tuple_apply( + call_emplace_and_visit_impl{}, + std::tuple_cat( + std::make_tuple(this,access_mode), + tuple_rotate_right<2>( + std::forward_as_tuple(std::forward(args)...)) + ) + ); + } + + template + BOOST_FORCEINLINE bool emplace_or_visit_impl( + GroupAccessMode access_mode,F&& f,Args&&... args) + { + return emplace_and_visit_impl( + access_mode,[](const value_type&){},std::forward(f), + std::forward(args)...); + } + + template + BOOST_FORCEINLINE bool emplace_and_visit_impl( + GroupAccessMode access_mode,F1&& f1,F2&& f2,Args&&... args) + { + for(;;){ + { + auto lck=shared_access(); + int res=unprotected_norehash_emplace_and_visit( + access_mode,std::forward(f1),std::forward(f2), + std::forward(args)...); + if(BOOST_LIKELY(res>=0))return res!=0; + } + rehash_if_full(); + } + } + + template + BOOST_FORCEINLINE bool unprotected_emplace(Args&&... args) + { + const auto &k=this->key_from(std::forward(args)...); + auto hash=this->hash_for(k); + auto pos0=this->position_for(hash); + + if(this->find(k,pos0,hash))return false; + + if(BOOST_LIKELY(this->size_ctrl.sizesize_ctrl.ml)){ + this->unchecked_emplace_at(pos0,hash,std::forward(args)...); + } + else{ + this->unchecked_emplace_with_rehash(hash,std::forward(args)...); + } + return true; + } + + template + BOOST_FORCEINLINE int + unprotected_norehash_emplace_or_visit( + GroupAccessMode access_mode,F&& f,Args&&... args) + { + return unprotected_norehash_emplace_and_visit( + access_mode,[&](const value_type&){}, + std::forward(f),std::forward(args)...); + } + + struct reserve_size + { + reserve_size(concurrent_table& x_):x(x_) + { + size_=++x.size_ctrl.size; + } + + ~reserve_size() + { + if(!commit_)--x.size_ctrl.size; + } + + bool succeeded()const{return size_<=x.size_ctrl.ml;} + + void commit(){commit_=true;} + + concurrent_table &x; + std::size_t size_; + bool commit_=false; + }; + + struct reserve_slot + { + reserve_slot(group_type* pg_,std::size_t pos_,std::size_t hash): + pg{pg_},pos{pos_} + { + pg->set(pos,hash); + } + + ~reserve_slot() + { + if(!commit_)pg->reset(pos); + } + + void commit(){commit_=true;} + + group_type *pg; + std::size_t pos; + bool commit_=false; + }; + + template + BOOST_FORCEINLINE int + unprotected_norehash_emplace_and_visit( + GroupAccessMode access_mode,F1&& f1,F2&& f2,Args&&... args) + { + const auto &k=this->key_from(std::forward(args)...); + auto hash=this->hash_for(k); + auto pos0=this->position_for(hash); + + for(;;){ + startover: + boost::uint32_t counter=insert_counter(pos0); + if(unprotected_visit( + access_mode,k,pos0,hash,std::forward(f2)))return 0; + + reserve_size rsize(*this); + if(BOOST_LIKELY(rsize.succeeded())){ + for(prober pb(pos0);;pb.next(this->arrays.groups_size_mask)){ + auto pos=pb.get(); + auto pg=this->arrays.groups()+pos; + auto lck=access(group_exclusive{},pos); + auto mask=pg->match_available(); + if(BOOST_LIKELY(mask!=0)){ + auto n=unchecked_countr_zero(mask); + reserve_slot rslot{pg,n,hash}; + if(BOOST_UNLIKELY(insert_counter(pos0)++!=counter)){ + /* other thread inserted from pos0, need to start over */ + goto startover; + } + auto p=this->arrays.elements()+pos*N+n; + this->construct_element(p,std::forward(args)...); + rslot.commit(); + rsize.commit(); + f1(cast_for(group_exclusive{},type_policy::value_from(*p))); + BOOST_UNORDERED_ADD_STATS(this->cstats.insertion,(pb.length())); + return 1; + } + pg->mark_overflow(hash); + } + } + else return -1; + } + } + + void rehash_if_full() + { + auto lck=exclusive_access(); + if(this->size_ctrl.size==this->size_ctrl.ml){ + this->unchecked_rehash_for_growth(); + } + } + + template + auto for_all_elements(GroupAccessMode access_mode,F f)const + ->decltype(f(nullptr),void()) + { + for_all_elements( + access_mode,[&](group_type*,unsigned int,element_type* p){f(p);}); + } + + template + auto for_all_elements(GroupAccessMode access_mode,F f)const + ->decltype(f(nullptr,0,nullptr),void()) + { + for_all_elements_while( + access_mode,[&](group_type* pg,unsigned int n,element_type* p) + {f(pg,n,p);return true;}); + } + + template + auto for_all_elements_while(GroupAccessMode access_mode,F f)const + ->decltype(f(nullptr),bool()) + { + return for_all_elements_while( + access_mode,[&](group_type*,unsigned int,element_type* p){return f(p);}); + } + + template + auto for_all_elements_while(GroupAccessMode access_mode,F f)const + ->decltype(f(nullptr,0,nullptr),bool()) + { + auto p=this->arrays.elements(); + if(p){ + for(auto pg=this->arrays.groups(),last=pg+this->arrays.groups_size_mask+1; + pg!=last;++pg,p+=N){ + auto lck=access(access_mode,(std::size_t)(pg-this->arrays.groups())); + auto mask=this->match_really_occupied(pg,last); + while(mask){ + auto n=unchecked_countr_zero(mask); + if(!f(pg,n,p+n))return false; + mask&=mask-1; + } + } + } + return true; + } + +#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) + template + auto for_all_elements( + GroupAccessMode access_mode,ExecutionPolicy&& policy,F f)const + ->decltype(f(nullptr),void()) + { + for_all_elements( + access_mode,std::forward(policy), + [&](group_type*,unsigned int,element_type* p){f(p);}); + } + + template + auto for_all_elements( + GroupAccessMode access_mode,ExecutionPolicy&& policy,F f)const + ->decltype(f(nullptr,0,nullptr),void()) + { + if(!this->arrays.elements())return; + auto first=this->arrays.groups(), + last=first+this->arrays.groups_size_mask+1; + std::for_each(std::forward(policy),first,last, + [&,this](group_type& g){ + auto pos=static_cast(&g-first); + auto p=this->arrays.elements()+pos*N; + auto lck=access(access_mode,pos); + auto mask=this->match_really_occupied(&g,last); + while(mask){ + auto n=unchecked_countr_zero(mask); + f(&g,n,p+n); + mask&=mask-1; + } + } + ); + } + + template + bool for_all_elements_while( + GroupAccessMode access_mode,ExecutionPolicy&& policy,F f)const + { + if(!this->arrays.elements())return true; + auto first=this->arrays.groups(), + last=first+this->arrays.groups_size_mask+1; + return std::all_of(std::forward(policy),first,last, + [&,this](group_type& g){ + auto pos=static_cast(&g-first); + auto p=this->arrays.elements()+pos*N; + auto lck=access(access_mode,pos); + auto mask=this->match_really_occupied(&g,last); + while(mask){ + auto n=unchecked_countr_zero(mask); + if(!f(p+n))return false; + mask&=mask-1; + } + return true; + } + ); + } +#endif + + friend class boost::serialization::access; + + template + void serialize(Archive& ar,unsigned int version) + { + core::split_member(ar,*this,version); + } + + template + void save(Archive& ar,unsigned int version)const + { + save( + ar,version, + std::integral_constant::value>{}); + } + + template + void save(Archive& ar,unsigned int,std::true_type /* set */)const + { + auto lck=exclusive_access(); + const std::size_t s=super::size(); + const serialization_version value_version; + + ar< + void save(Archive& ar,unsigned int,std::false_type /* map */)const + { + using raw_key_type=typename std::remove_const::type; + using raw_mapped_type=typename std::remove_const< + typename TypePolicy::mapped_type>::type; + + auto lck=exclusive_access(); + const std::size_t s=super::size(); + const serialization_version key_version; + const serialization_version mapped_version; + + ar< + void load(Archive& ar,unsigned int version) + { + load( + ar,version, + std::integral_constant::value>{}); + } + + template + void load(Archive& ar,unsigned int,std::true_type /* set */) + { + auto lck=exclusive_access(); + std::size_t s; + serialization_version value_version; + + ar>>core::make_nvp("count",s); + ar>>core::make_nvp("value_version",value_version); + + super::clear(); + super::reserve(s); + + for(std::size_t n=0;n value("item",ar,value_version); + auto& x=value.get(); + auto hash=this->hash_for(x); + auto pos0=this->position_for(hash); + + if(this->find(x,pos0,hash))throw_exception(bad_archive_exception()); + auto loc=this->unchecked_emplace_at(pos0,hash,std::move(x)); + ar.reset_object_address( + std::addressof(type_policy::value_from(*loc.p)),std::addressof(x)); + } + } + + template + void load(Archive& ar,unsigned int,std::false_type /* map */) + { + using raw_key_type=typename std::remove_const::type; + using raw_mapped_type=typename std::remove_const< + typename type_policy::mapped_type>::type; + + auto lck=exclusive_access(); + std::size_t s; + serialization_version key_version; + serialization_version mapped_version; + + ar>>core::make_nvp("count",s); + ar>>core::make_nvp("key_version",key_version); + ar>>core::make_nvp("mapped_version",mapped_version); + + super::clear(); + super::reserve(s); + + for(std::size_t n=0;n key("key",ar,key_version); + archive_constructed mapped("mapped",ar,mapped_version); + auto& k=key.get(); + auto& m=mapped.get(); + auto hash=this->hash_for(k); + auto pos0=this->position_for(hash); + + if(this->find(k,pos0,hash))throw_exception(bad_archive_exception()); + auto loc=this->unchecked_emplace_at(pos0,hash,std::move(k),std::move(m)); + ar.reset_object_address( + std::addressof(type_policy::value_from(*loc.p).first), + std::addressof(k)); + ar.reset_object_address( + std::addressof(type_policy::value_from(*loc.p).second), + std::addressof(m)); + } + } + + static std::atomic thread_counter; + mutable multimutex_type mutexes; +}; + +template +std::atomic concurrent_table::thread_counter={}; + +#if defined(BOOST_MSVC) +#pragma warning(pop) /* C4714 */ +#endif + +#include + +} /* namespace foa */ +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/foa/core.hpp b/src/boost/unordered/detail/foa/core.hpp new file mode 100644 index 00000000..062b7112 --- /dev/null +++ b/src/boost/unordered/detail/foa/core.hpp @@ -0,0 +1,2404 @@ +/* Common base for Boost.Unordered open-addressing tables. + * + * Copyright 2022-2024 Joaquin M Lopez Munoz. + * Copyright 2023 Christian Mazakas. + * Copyright 2024 Braden Ganetsky. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_FOA_CORE_HPP +#define BOOST_UNORDERED_DETAIL_FOA_CORE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_UNORDERED_ENABLE_STATS) +#include +#endif + +#if !defined(BOOST_UNORDERED_DISABLE_SSE2) +#if defined(BOOST_UNORDERED_ENABLE_SSE2)|| \ + defined(__SSE2__)|| \ + defined(_M_X64)||(defined(_M_IX86_FP)&&_M_IX86_FP>=2) +#define BOOST_UNORDERED_SSE2 +#endif +#endif + +#if !defined(BOOST_UNORDERED_DISABLE_NEON) +#if defined(BOOST_UNORDERED_ENABLE_NEON)||\ + (defined(__ARM_NEON)&&!defined(__ARM_BIG_ENDIAN)) +#define BOOST_UNORDERED_LITTLE_ENDIAN_NEON +#endif +#endif + +#if defined(BOOST_UNORDERED_SSE2) +#include +#elif defined(BOOST_UNORDERED_LITTLE_ENDIAN_NEON) +#include +#endif + +#ifdef __has_builtin +#define BOOST_UNORDERED_HAS_BUILTIN(x) __has_builtin(x) +#else +#define BOOST_UNORDERED_HAS_BUILTIN(x) 0 +#endif + +#if !defined(NDEBUG) +#define BOOST_UNORDERED_ASSUME(cond) BOOST_ASSERT(cond) +#elif BOOST_UNORDERED_HAS_BUILTIN(__builtin_assume) +#define BOOST_UNORDERED_ASSUME(cond) __builtin_assume(cond) +#elif defined(__GNUC__) || BOOST_UNORDERED_HAS_BUILTIN(__builtin_unreachable) +#define BOOST_UNORDERED_ASSUME(cond) \ + do{ \ + if(!(cond))__builtin_unreachable(); \ + }while(0) +#elif defined(_MSC_VER) +#define BOOST_UNORDERED_ASSUME(cond) __assume(cond) +#else +#define BOOST_UNORDERED_ASSUME(cond) \ + do{ \ + static_cast(false&&(cond)); \ + }while(0) +#endif + +/* We use BOOST_UNORDERED_PREFETCH[_ELEMENTS] macros rather than proper + * functions because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109985 + */ + +#if defined(BOOST_GCC)||defined(BOOST_CLANG) +#define BOOST_UNORDERED_PREFETCH(p) __builtin_prefetch((const char*)(p)) +#elif defined(BOOST_UNORDERED_SSE2) +#define BOOST_UNORDERED_PREFETCH(p) _mm_prefetch((const char*)(p),_MM_HINT_T0) +#else +#define BOOST_UNORDERED_PREFETCH(p) ((void)(p)) +#endif + +/* We have experimentally confirmed that ARM architectures get a higher + * speedup when around the first half of the element slots in a group are + * prefetched, whereas for Intel just the first cache line is best. + * Please report back if you find better tunings for some particular + * architectures. + */ + +#if BOOST_ARCH_ARM +/* Cache line size can't be known at compile time, so we settle on + * the very frequent value of 64B. + */ + +#define BOOST_UNORDERED_PREFETCH_ELEMENTS(p,N) \ + do{ \ + auto BOOST_UNORDERED_P=(p); \ + constexpr int cache_line=64; \ + const char *p0=reinterpret_cast(BOOST_UNORDERED_P), \ + *p1=p0+sizeof(*BOOST_UNORDERED_P)*(N)/2; \ + for(;p0::value, \ + "Template parameter Hash is required to be nothrow Swappable."); \ + static_assert(boost::unordered::detail::is_nothrow_swappable::value, \ + "Template parameter Pred is required to be nothrow Swappable"); + +namespace boost{ +namespace unordered{ +namespace detail{ +namespace foa{ + +static constexpr std::size_t default_bucket_count=0; + +/* foa::table_core is the common base of foa::table and foa::concurrent_table, + * which in their turn serve as the foundational core of + * boost::unordered_(flat|node)_(map|set) and boost::concurrent_flat_(map|set), + * respectively. Its main internal design aspects are: + * + * - Element slots are logically split into groups of size N=15. The number + * of groups is always a power of two, so the number of allocated slots + is of the form (N*2^n)-1 (final slot reserved for a sentinel mark). + * - Positioning is done at the group level rather than the slot level, that + * is, for any given element its hash value is used to locate a group and + * insertion is performed on the first available element of that group; + * if the group is full (overflow), further groups are tried using + * quadratic probing. + * - Each group has an associated 16B metadata word holding reduced hash + * values and overflow information. Reduced hash values are used to + * accelerate lookup within the group by using 128-bit SIMD or 64-bit word + * operations. + */ + +/* group15 controls metadata information of a group of N=15 element slots. + * The 16B metadata word is organized as follows (LSB depicted rightmost): + * + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * |ofw|h14|h13|h13|h11|h10|h09|h08|h07|h06|h05|h04|h03|h02|h01|h00| + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * + * hi is 0 if the i-th element slot is avalaible, 1 to mark a sentinel and, + * when the slot is occupied, a value in the range [2,255] obtained from the + * element's original hash value. + * ofw is the so-called overflow byte. If insertion of an element with hash + * value h is tried on a full group, then the (h%8)-th bit of the overflow + * byte is set to 1 and a further group is probed. Having an overflow byte + * brings two advantages: + * + * - There's no need to reserve a special value of hi to mark tombstone + * slots; each reduced hash value keeps then log2(254)=7.99 bits of the + * original hash (alternative approaches reserve one full bit to mark + * if the slot is available/deleted, so their reduced hash values are 7 bit + * strong only). + * - When doing an unsuccessful lookup (i.e. the element is not present in + * the table), probing stops at the first non-overflowed group. Having 8 + * bits for signalling overflow makes it very likely that we stop at the + * current group (this happens when no element with the same (h%8) value + * has overflowed in the group), saving us an additional group check even + * under high-load/high-erase conditions. It is critical that hash + * reduction is invariant under modulo 8 (see maybe_caused_overflow). + * + * When looking for an element with hash value h, match(h) returns a bitmask + * signalling which slots have the same reduced hash value. If available, + * match uses SSE2 or (little endian) Neon 128-bit SIMD operations. On non-SIMD + * scenarios, the logical layout described above is physically mapped to two + * 64-bit words with *bit interleaving*, i.e. the least significant 16 bits of + * the first 64-bit word contain the least significant bits of each byte in the + * "logical" 128-bit word, and so forth. With this layout, match can be + * implemented with 4 ANDs, 3 shifts, 2 XORs, 1 OR and 1 NOT. + * + * IntegralWrapper is used to implement group15's underlying + * metadata: it behaves as a plain integral for foa::table or introduces + * atomic ops for foa::concurrent_table. If IntegralWrapper<...> is trivially + * constructible, so is group15, in which case it can be initialized via memset + * etc. Where needed, group15::initialize resets the metadata to the all + * zeros (default state). + */ + +#if defined(BOOST_UNORDERED_SSE2) + +template class IntegralWrapper> +struct group15 +{ + static constexpr std::size_t N=15; + static constexpr bool regular_layout=true; + + struct dummy_group_type + { + alignas(16) unsigned char storage[N+1]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}; + }; + + inline void initialize() + { + _mm_store_si128( + reinterpret_cast<__m128i*>(m),_mm_setzero_si128()); + } + + inline void set(std::size_t pos,std::size_t hash) + { + BOOST_ASSERT(pos(pc)=available_; + } + + inline int match(std::size_t hash)const + { + return _mm_movemask_epi8( + _mm_cmpeq_epi8(load_metadata(),_mm_set1_epi32(match_word(hash))))&0x7FFF; + } + + inline bool is_not_overflowed(std::size_t hash)const + { + static constexpr unsigned char shift[]={1,2,4,8,16,32,64,128}; + + return !(overflow()&shift[hash%8]); + } + + inline void mark_overflow(std::size_t hash) + { + overflow()|=static_cast(1<<(hash%8)); + } + + static inline bool maybe_caused_overflow(unsigned char* pc) + { + std::size_t pos=reinterpret_cast(pc)%sizeof(group15); + group15 *pg=reinterpret_cast(pc-pos); + return !pg->is_not_overflowed(*pc); + } + + inline int match_available()const + { + return _mm_movemask_epi8( + _mm_cmpeq_epi8(load_metadata(),_mm_setzero_si128()))&0x7FFF; + } + + inline bool is_occupied(std::size_t pos)const + { + BOOST_ASSERT(pos(pc)!=available_; + } + + inline int match_occupied()const + { + return (~match_available())&0x7FFF; + } + +private: + using slot_type=IntegralWrapper; + BOOST_UNORDERED_STATIC_ASSERT(sizeof(slot_type)==1); + + static constexpr unsigned char available_=0, + sentinel_=1; + + inline __m128i load_metadata()const + { +#if defined(BOOST_UNORDERED_THREAD_SANITIZER) + /* ThreadSanitizer complains on 1-byte atomic writes combined with + * 16-byte atomic reads. + */ + + return _mm_set_epi8( + (char)m[15],(char)m[14],(char)m[13],(char)m[12], + (char)m[11],(char)m[10],(char)m[ 9],(char)m[ 8], + (char)m[ 7],(char)m[ 6],(char)m[ 5],(char)m[ 4], + (char)m[ 3],(char)m[ 2],(char)m[ 1],(char)m[ 0]); +#else + return _mm_load_si128(reinterpret_cast(m)); +#endif + } + + inline static int match_word(std::size_t hash) + { + static constexpr boost::uint32_t word[]= + { + 0x08080808u,0x09090909u,0x02020202u,0x03030303u,0x04040404u,0x05050505u, + 0x06060606u,0x07070707u,0x08080808u,0x09090909u,0x0A0A0A0Au,0x0B0B0B0Bu, + 0x0C0C0C0Cu,0x0D0D0D0Du,0x0E0E0E0Eu,0x0F0F0F0Fu,0x10101010u,0x11111111u, + 0x12121212u,0x13131313u,0x14141414u,0x15151515u,0x16161616u,0x17171717u, + 0x18181818u,0x19191919u,0x1A1A1A1Au,0x1B1B1B1Bu,0x1C1C1C1Cu,0x1D1D1D1Du, + 0x1E1E1E1Eu,0x1F1F1F1Fu,0x20202020u,0x21212121u,0x22222222u,0x23232323u, + 0x24242424u,0x25252525u,0x26262626u,0x27272727u,0x28282828u,0x29292929u, + 0x2A2A2A2Au,0x2B2B2B2Bu,0x2C2C2C2Cu,0x2D2D2D2Du,0x2E2E2E2Eu,0x2F2F2F2Fu, + 0x30303030u,0x31313131u,0x32323232u,0x33333333u,0x34343434u,0x35353535u, + 0x36363636u,0x37373737u,0x38383838u,0x39393939u,0x3A3A3A3Au,0x3B3B3B3Bu, + 0x3C3C3C3Cu,0x3D3D3D3Du,0x3E3E3E3Eu,0x3F3F3F3Fu,0x40404040u,0x41414141u, + 0x42424242u,0x43434343u,0x44444444u,0x45454545u,0x46464646u,0x47474747u, + 0x48484848u,0x49494949u,0x4A4A4A4Au,0x4B4B4B4Bu,0x4C4C4C4Cu,0x4D4D4D4Du, + 0x4E4E4E4Eu,0x4F4F4F4Fu,0x50505050u,0x51515151u,0x52525252u,0x53535353u, + 0x54545454u,0x55555555u,0x56565656u,0x57575757u,0x58585858u,0x59595959u, + 0x5A5A5A5Au,0x5B5B5B5Bu,0x5C5C5C5Cu,0x5D5D5D5Du,0x5E5E5E5Eu,0x5F5F5F5Fu, + 0x60606060u,0x61616161u,0x62626262u,0x63636363u,0x64646464u,0x65656565u, + 0x66666666u,0x67676767u,0x68686868u,0x69696969u,0x6A6A6A6Au,0x6B6B6B6Bu, + 0x6C6C6C6Cu,0x6D6D6D6Du,0x6E6E6E6Eu,0x6F6F6F6Fu,0x70707070u,0x71717171u, + 0x72727272u,0x73737373u,0x74747474u,0x75757575u,0x76767676u,0x77777777u, + 0x78787878u,0x79797979u,0x7A7A7A7Au,0x7B7B7B7Bu,0x7C7C7C7Cu,0x7D7D7D7Du, + 0x7E7E7E7Eu,0x7F7F7F7Fu,0x80808080u,0x81818181u,0x82828282u,0x83838383u, + 0x84848484u,0x85858585u,0x86868686u,0x87878787u,0x88888888u,0x89898989u, + 0x8A8A8A8Au,0x8B8B8B8Bu,0x8C8C8C8Cu,0x8D8D8D8Du,0x8E8E8E8Eu,0x8F8F8F8Fu, + 0x90909090u,0x91919191u,0x92929292u,0x93939393u,0x94949494u,0x95959595u, + 0x96969696u,0x97979797u,0x98989898u,0x99999999u,0x9A9A9A9Au,0x9B9B9B9Bu, + 0x9C9C9C9Cu,0x9D9D9D9Du,0x9E9E9E9Eu,0x9F9F9F9Fu,0xA0A0A0A0u,0xA1A1A1A1u, + 0xA2A2A2A2u,0xA3A3A3A3u,0xA4A4A4A4u,0xA5A5A5A5u,0xA6A6A6A6u,0xA7A7A7A7u, + 0xA8A8A8A8u,0xA9A9A9A9u,0xAAAAAAAAu,0xABABABABu,0xACACACACu,0xADADADADu, + 0xAEAEAEAEu,0xAFAFAFAFu,0xB0B0B0B0u,0xB1B1B1B1u,0xB2B2B2B2u,0xB3B3B3B3u, + 0xB4B4B4B4u,0xB5B5B5B5u,0xB6B6B6B6u,0xB7B7B7B7u,0xB8B8B8B8u,0xB9B9B9B9u, + 0xBABABABAu,0xBBBBBBBBu,0xBCBCBCBCu,0xBDBDBDBDu,0xBEBEBEBEu,0xBFBFBFBFu, + 0xC0C0C0C0u,0xC1C1C1C1u,0xC2C2C2C2u,0xC3C3C3C3u,0xC4C4C4C4u,0xC5C5C5C5u, + 0xC6C6C6C6u,0xC7C7C7C7u,0xC8C8C8C8u,0xC9C9C9C9u,0xCACACACAu,0xCBCBCBCBu, + 0xCCCCCCCCu,0xCDCDCDCDu,0xCECECECEu,0xCFCFCFCFu,0xD0D0D0D0u,0xD1D1D1D1u, + 0xD2D2D2D2u,0xD3D3D3D3u,0xD4D4D4D4u,0xD5D5D5D5u,0xD6D6D6D6u,0xD7D7D7D7u, + 0xD8D8D8D8u,0xD9D9D9D9u,0xDADADADAu,0xDBDBDBDBu,0xDCDCDCDCu,0xDDDDDDDDu, + 0xDEDEDEDEu,0xDFDFDFDFu,0xE0E0E0E0u,0xE1E1E1E1u,0xE2E2E2E2u,0xE3E3E3E3u, + 0xE4E4E4E4u,0xE5E5E5E5u,0xE6E6E6E6u,0xE7E7E7E7u,0xE8E8E8E8u,0xE9E9E9E9u, + 0xEAEAEAEAu,0xEBEBEBEBu,0xECECECECu,0xEDEDEDEDu,0xEEEEEEEEu,0xEFEFEFEFu, + 0xF0F0F0F0u,0xF1F1F1F1u,0xF2F2F2F2u,0xF3F3F3F3u,0xF4F4F4F4u,0xF5F5F5F5u, + 0xF6F6F6F6u,0xF7F7F7F7u,0xF8F8F8F8u,0xF9F9F9F9u,0xFAFAFAFAu,0xFBFBFBFBu, + 0xFCFCFCFCu,0xFDFDFDFDu,0xFEFEFEFEu,0xFFFFFFFFu, + }; + + return (int)word[narrow_cast(hash)]; + } + + inline static unsigned char reduced_hash(std::size_t hash) + { + return narrow_cast(match_word(hash)); + } + + inline slot_type& at(std::size_t pos) + { + return m[pos]; + } + + inline const slot_type& at(std::size_t pos)const + { + return m[pos]; + } + + inline slot_type& overflow() + { + return at(N); + } + + inline const slot_type& overflow()const + { + return at(N); + } + + alignas(16) slot_type m[16]; +}; + +#elif defined(BOOST_UNORDERED_LITTLE_ENDIAN_NEON) + +template class IntegralWrapper> +struct group15 +{ + static constexpr std::size_t N=15; + static constexpr bool regular_layout=true; + + struct dummy_group_type + { + alignas(16) unsigned char storage[N+1]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}; + }; + + inline void initialize() + { + vst1q_u8(reinterpret_cast(m),vdupq_n_u8(0)); + } + + inline void set(std::size_t pos,std::size_t hash) + { + BOOST_ASSERT(pos(pc)==sentinel_; + } + + inline void reset(std::size_t pos) + { + BOOST_ASSERT(pos(pc)=available_; + } + + inline int match(std::size_t hash)const + { + return simde_mm_movemask_epi8(vceqq_u8( + load_metadata(),vdupq_n_u8(reduced_hash(hash))))&0x7FFF; + } + + inline bool is_not_overflowed(std::size_t hash)const + { + static constexpr unsigned char shift[]={1,2,4,8,16,32,64,128}; + + return !(overflow()&shift[hash%8]); + } + + inline void mark_overflow(std::size_t hash) + { + overflow()|=static_cast(1<<(hash%8)); + } + + static inline bool maybe_caused_overflow(unsigned char* pc) + { + std::size_t pos=reinterpret_cast(pc)%sizeof(group15); + group15 *pg=reinterpret_cast(pc-pos); + return !pg->is_not_overflowed(*pc); + }; + + inline int match_available()const + { + return simde_mm_movemask_epi8(vceqq_u8( + load_metadata(),vdupq_n_u8(0)))&0x7FFF; + } + + inline bool is_occupied(std::size_t pos)const + { + BOOST_ASSERT(pos(pc)!=available_; + } + + inline int match_occupied()const + { + return simde_mm_movemask_epi8(vcgtq_u8( + load_metadata(),vdupq_n_u8(0)))&0x7FFF; + } + +private: + using slot_type=IntegralWrapper; + BOOST_UNORDERED_STATIC_ASSERT(sizeof(slot_type)==1); + + static constexpr unsigned char available_=0, + sentinel_=1; + + inline uint8x16_t load_metadata()const + { +#if defined(BOOST_UNORDERED_THREAD_SANITIZER) + /* ThreadSanitizer complains on 1-byte atomic writes combined with + * 16-byte atomic reads. + */ + + alignas(16) uint8_t data[16]={ + m[ 0],m[ 1],m[ 2],m[ 3],m[ 4],m[ 5],m[ 6],m[ 7], + m[ 8],m[ 9],m[10],m[11],m[12],m[13],m[14],m[15]}; + return vld1q_u8(data); +#else + return vld1q_u8(reinterpret_cast(m)); +#endif + } + + inline static unsigned char reduced_hash(std::size_t hash) + { + static constexpr unsigned char table[]={ + 8,9,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, + 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, + 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, + 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, + }; + + return table[(unsigned char)hash]; + } + + /* Copied from + * https://github.com/simd-everywhere/simde/blob/master/simde/x86/ + * sse2.h#L3763 + */ + + static inline int simde_mm_movemask_epi8(uint8x16_t a) + { + static constexpr uint8_t md[16]={ + 1 << 0, 1 << 1, 1 << 2, 1 << 3, + 1 << 4, 1 << 5, 1 << 6, 1 << 7, + 1 << 0, 1 << 1, 1 << 2, 1 << 3, + 1 << 4, 1 << 5, 1 << 6, 1 << 7, + }; + + uint8x16_t masked=vandq_u8(vld1q_u8(md),a); + uint8x8x2_t tmp=vzip_u8(vget_low_u8(masked),vget_high_u8(masked)); + uint16x8_t x=vreinterpretq_u16_u8(vcombine_u8(tmp.val[0],tmp.val[1])); + +#if defined(__ARM_ARCH_ISA_A64) + return vaddvq_u16(x); +#else + uint64x2_t t64=vpaddlq_u32(vpaddlq_u16(x)); + return int(vgetq_lane_u64(t64,0))+int(vgetq_lane_u64(t64,1)); +#endif + } + + inline slot_type& at(std::size_t pos) + { + return m[pos]; + } + + inline const slot_type& at(std::size_t pos)const + { + return m[pos]; + } + + inline slot_type& overflow() + { + return at(N); + } + + inline const slot_type& overflow()const + { + return at(N); + } + + alignas(16) slot_type m[16]; +}; + +#else /* non-SIMD */ + +template class IntegralWrapper> +struct group15 +{ + static constexpr std::size_t N=15; + static constexpr bool regular_layout=false; + + struct dummy_group_type + { + alignas(16) boost::uint64_t m[2]= + {0x0000000000004000ull,0x0000000000000000ull}; + }; + + inline void initialize(){m[0]=0;m[1]=0;} + + inline void set(std::size_t pos,std::size_t hash) + { + BOOST_ASSERT(pos(pc)%sizeof(group15); + pc-=pos; + reinterpret_cast(pc)->reset(pos); + } + + inline int match(std::size_t hash)const + { + return match_impl(reduced_hash(hash)); + } + + inline bool is_not_overflowed(std::size_t hash)const + { + return !(reinterpret_cast(m)[hash%8] & 0x8000u); + } + + inline void mark_overflow(std::size_t hash) + { + reinterpret_cast(m)[hash%8]|=0x8000u; + } + + static inline bool maybe_caused_overflow(unsigned char* pc) + { + std::size_t pos=reinterpret_cast(pc)%sizeof(group15); + group15 *pg=reinterpret_cast(pc-pos); + boost::uint64_t x=((pg->m[0])>>pos)&0x000100010001ull; + boost::uint32_t y=narrow_cast(x|(x>>15)|(x>>30)); + return !pg->is_not_overflowed(y); + }; + + inline int match_available()const + { + boost::uint64_t x=~(m[0]|m[1]); + boost::uint32_t y=static_cast(x&(x>>32)); + y&=y>>16; + return y&0x7FFF; + } + + inline bool is_occupied(std::size_t pos)const + { + BOOST_ASSERT(pos(x|(x>>32)); + y|=y>>16; + return y&0x7FFF; + } + +private: + using word_type=IntegralWrapper; + BOOST_UNORDERED_STATIC_ASSERT(sizeof(word_type)==8); + + static constexpr unsigned char available_=0, + sentinel_=1; + + inline static unsigned char reduced_hash(std::size_t hash) + { + static constexpr unsigned char table[]={ + 8,9,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, + 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, + 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, + 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, + 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, + 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, + }; + + return table[narrow_cast(hash)]; + } + + inline void set_impl(std::size_t pos,std::size_t n) + { + BOOST_ASSERT(n<256); + set_impl(m[0],pos,n&0xFu); + set_impl(m[1],pos,n>>4); + } + + static inline void set_impl(word_type& x,std::size_t pos,std::size_t n) + { + static constexpr boost::uint64_t mask[]= + { + 0x0000000000000000ull,0x0000000000000001ull,0x0000000000010000ull, + 0x0000000000010001ull,0x0000000100000000ull,0x0000000100000001ull, + 0x0000000100010000ull,0x0000000100010001ull,0x0001000000000000ull, + 0x0001000000000001ull,0x0001000000010000ull,0x0001000000010001ull, + 0x0001000100000000ull,0x0001000100000001ull,0x0001000100010000ull, + 0x0001000100010001ull, + }; + static constexpr boost::uint64_t imask[]= + { + 0x0001000100010001ull,0x0001000100010000ull,0x0001000100000001ull, + 0x0001000100000000ull,0x0001000000010001ull,0x0001000000010000ull, + 0x0001000000000001ull,0x0001000000000000ull,0x0000000100010001ull, + 0x0000000100010000ull,0x0000000100000001ull,0x0000000100000000ull, + 0x0000000000010001ull,0x0000000000010000ull,0x0000000000000001ull, + 0x0000000000000000ull, + }; + + BOOST_ASSERT(pos<16&&n<16); + x|= mask[n]<>4])|x); + boost::uint32_t y=static_cast(x&(x>>32)); + y&=y>>16; + return y&0x7FFF; + } + + alignas(16) word_type m[2]; +}; + +#endif + +/* foa::table_core uses a size policy to obtain the permissible sizes of the + * group array (and, by implication, the element array) and to do the + * hash->group mapping. + * + * - size_index(n) returns an unspecified "index" number used in other policy + * operations. + * - size(size_index_) returns the number of groups for the given index. It + * is guaranteed that size(size_index(n)) >= n. + * - min_size() is the minimum number of groups permissible, i.e. + * size(size_index(0)). + * - position(hash,size_index_) maps hash to a position in the range + * [0,size(size_index_)). + * + * The reason we're introducing the intermediate index value for calculating + * sizes and positions is that it allows us to optimize the implementation of + * position, which is in the hot path of lookup and insertion operations: + * pow2_size_policy, the actual size policy used by foa::table, returns 2^n + * (n>0) as permissible sizes and returns the n most significant bits + * of the hash value as the position in the group array; using a size index + * defined as i = (bits in std::size_t) - n, we have an unbeatable + * implementation of position(hash) as hash>>i. + * There's a twofold reason for choosing the high bits of hash for positioning: + * - Multiplication-based mixing tends to yield better entropy in the high + * part of its result. + * - group15 reduced-hash values take the *low* bits of hash, and we want + * these values and positioning to be as uncorrelated as possible. + */ + +struct pow2_size_policy +{ + static inline std::size_t size_index(std::size_t n) + { + // TODO: min size is 2, see if we can bring it down to 1 without loss + // of performance + + return sizeof(std::size_t)*CHAR_BIT- + (n<=2?1:((std::size_t)(boost::core::bit_width(n-1)))); + } + + static inline std::size_t size(std::size_t size_index_) + { + return std::size_t(1)<<(sizeof(std::size_t)*CHAR_BIT-size_index_); + } + + static constexpr std::size_t min_size(){return 2;} + + static inline std::size_t position(std::size_t hash,std::size_t size_index_) + { + return hash>>size_index_; + } +}; + +/* size index of a group array for a given *element* capacity */ + +template +static inline std::size_t size_index_for(std::size_t n) +{ + /* n/N+1 == ceil((n+1)/N) (extra +1 for the sentinel) */ + return SizePolicy::size_index(n/Group::N+1); +} + +/* Quadratic prober over a power-of-two range using triangular numbers. + * mask in next(mask) must be the range size minus one (and since size is 2^n, + * mask has exactly its n first bits set to 1). + */ + +struct pow2_quadratic_prober +{ + pow2_quadratic_prober(std::size_t pos_):pos{pos_}{} + + inline std::size_t get()const{return pos;} + inline std::size_t length()const{return step+1;} + + /* next returns false when the whole array has been traversed, which ends + * probing (in practice, full-table probing will only happen with very small + * arrays). + */ + + inline bool next(std::size_t mask) + { + step+=1; + pos=(pos+step)&mask; + return step<=mask; + } + +private: + std::size_t pos,step=0; +}; + +/* Mixing policies: no_mix is the identity function, and mulx_mix + * uses the mulx function from . + * + * foa::table_core mixes hash results with mulx_mix unless the hash is marked + * as avalanching, i.e. of good quality + * (see ). + */ + +struct no_mix +{ + template + static inline std::size_t mix(const Hash& h,const T& x) + { + return h(x); + } +}; + +struct mulx_mix +{ + template + static inline std::size_t mix(const Hash& h,const T& x) + { + return mulx(h(x)); + } +}; + +/* boost::core::countr_zero has a potentially costly check for + * the case x==0. + */ + +inline unsigned int unchecked_countr_zero(int x) +{ +#if defined(BOOST_MSVC) + unsigned long r; + _BitScanForward(&r,(unsigned long)x); + return (unsigned int)r; +#else + BOOST_UNORDERED_ASSUME(x!=0); + return (unsigned int)boost::core::countr_zero((unsigned int)x); +#endif +} + +/* table_arrays controls allocation, initialization and deallocation of + * paired arrays of groups and element slots. Only one chunk of memory is + * allocated to place both arrays: this is not done for efficiency reasons, + * but in order to be able to properly align the group array without storing + * additional offset information --the alignment required (16B) is usually + * greater than alignof(std::max_align_t) and thus not guaranteed by + * allocators. + */ + +template +Group* dummy_groups() +{ + /* Dummy storage initialized as if in an empty container (actually, each + * of its groups is initialized like a separate empty container). + * We make table_arrays::groups point to this when capacity()==0, so that + * we are not allocating any dynamic memory and yet lookup can be implemented + * without checking for groups==nullptr. This space won't ever be used for + * insertion as the container's capacity is precisely zero. + */ + + static constexpr typename Group::dummy_group_type + storage[Size]={typename Group::dummy_group_type(),}; + + return reinterpret_cast( + const_cast(storage)); +} + +template< + typename Ptr,typename Ptr2, + typename std::enable_if::value>::type* = nullptr +> +Ptr to_pointer(Ptr2 p) +{ + if(!p){return nullptr;} + return boost::pointer_traits::pointer_to(*p); +} + +template +Ptr to_pointer(Ptr p) +{ + return p; +} + +template +struct arrays_holder +{ + arrays_holder(const Arrays& arrays,const Allocator& al): + arrays_{arrays},al_{al} + {} + + /* not defined but VS in pre-C++17 mode needs to see it for RVO */ + arrays_holder(arrays_holder const&); + arrays_holder& operator=(arrays_holder const&)=delete; + + ~arrays_holder() + { + if(!released_){ + arrays_.delete_(typename Arrays::allocator_type(al_),arrays_); + } + } + + const Arrays& release() + { + released_=true; + return arrays_; + } + +private: + Arrays arrays_; + Allocator al_; + bool released_=false; +}; + +template +struct table_arrays +{ + using allocator_type=typename boost::allocator_rebind::type; + + using value_type=Value; + using group_type=Group; + static constexpr auto N=group_type::N; + using size_policy=SizePolicy; + using value_type_pointer= + typename boost::allocator_pointer::type; + using group_type_pointer= + typename boost::pointer_traits::template + rebind; + using group_type_pointer_traits=boost::pointer_traits; + + // For natvis purposes + using char_pointer= + typename boost::pointer_traits::template + rebind; + + table_arrays( + std::size_t gsi,std::size_t gsm, + group_type_pointer pg,value_type_pointer pe): + groups_size_index{gsi},groups_size_mask{gsm},groups_{pg},elements_{pe}{} + + value_type* elements()const noexcept{return boost::to_address(elements_);} + group_type* groups()const noexcept{return boost::to_address(groups_);} + + static void set_arrays(table_arrays& arrays,allocator_type al,std::size_t n) + { + return set_arrays( + arrays,al,n,std::is_same{}); + } + + static void set_arrays( + table_arrays& arrays,allocator_type al,std::size_t, + std::false_type /* always allocate */) + { + using storage_traits=boost::allocator_traits; + auto groups_size_index=arrays.groups_size_index; + auto groups_size=size_policy::size(groups_size_index); + + auto sal=allocator_type(al); + arrays.elements_=storage_traits::allocate(sal,buffer_size(groups_size)); + + /* Align arrays.groups to sizeof(group_type). table_iterator critically + * depends on such alignment for its increment operation. + */ + + auto p=reinterpret_cast(arrays.elements()+groups_size*N-1); + p+=(uintptr_t(sizeof(group_type))- + reinterpret_cast(p))%sizeof(group_type); + arrays.groups_= + group_type_pointer_traits::pointer_to(*reinterpret_cast(p)); + + initialize_groups( + arrays.groups(),groups_size, + is_trivially_default_constructible{}); + arrays.groups()[groups_size-1].set_sentinel(); + } + + static void set_arrays( + table_arrays& arrays,allocator_type al,std::size_t n, + std::true_type /* optimize for n==0*/) + { + if(!n){ + arrays.groups_=dummy_groups(); + } + else{ + set_arrays(arrays,al,n,std::false_type{}); + } + } + + static table_arrays new_(allocator_type al,std::size_t n) + { + auto groups_size_index=size_index_for(n); + auto groups_size=size_policy::size(groups_size_index); + table_arrays arrays{groups_size_index,groups_size-1,nullptr,nullptr}; + + set_arrays(arrays,al,n); + return arrays; + } + + static void delete_(allocator_type al,table_arrays& arrays)noexcept + { + using storage_traits=boost::allocator_traits; + + auto sal=allocator_type(al); + if(arrays.elements()){ + storage_traits::deallocate( + sal,arrays.elements_,buffer_size(arrays.groups_size_mask+1)); + } + } + + /* combined space for elements and groups measured in sizeof(value_type)s */ + + static std::size_t buffer_size(std::size_t groups_size) + { + auto buffer_bytes= + /* space for elements (we subtract 1 because of the sentinel) */ + sizeof(value_type)*(groups_size*N-1)+ + /* space for groups + padding for group alignment */ + sizeof(group_type)*(groups_size+1)-1; + + /* ceil(buffer_bytes/sizeof(value_type)) */ + return (buffer_bytes+sizeof(value_type)-1)/sizeof(value_type); + } + + static void initialize_groups( + group_type* pg,std::size_t size,std::true_type /* memset */) + { + /* memset faster/not slower than manual, assumes all zeros is group_type's + * default layout. + * reinterpret_cast: GCC may complain about group_type not being trivially + * copy-assignable when we're relying on trivial copy constructibility. + */ + + std::memset( + reinterpret_cast(pg),0,sizeof(group_type)*size); + } + + static void initialize_groups( + group_type* pg,std::size_t size,std::false_type /* manual */) + { + while(size--!=0)::new (pg++) group_type(); + } + + std::size_t groups_size_index; + std::size_t groups_size_mask; + group_type_pointer groups_; + value_type_pointer elements_; +}; + +#if defined(BOOST_UNORDERED_ENABLE_STATS) +/* stats support */ + +struct table_core_cumulative_stats +{ + concurrent_cumulative_stats<1> insertion; + concurrent_cumulative_stats<2> successful_lookup, + unsuccessful_lookup; +}; + +struct table_core_insertion_stats +{ + std::size_t count; + sequence_stats_summary probe_length; +}; + +struct table_core_lookup_stats +{ + std::size_t count; + sequence_stats_summary probe_length; + sequence_stats_summary num_comparisons; +}; + +struct table_core_stats +{ + table_core_insertion_stats insertion; + table_core_lookup_stats successful_lookup, + unsuccessful_lookup; +}; + +#define BOOST_UNORDERED_ADD_STATS(stats,args) stats.add args +#define BOOST_UNORDERED_SWAP_STATS(stats1,stats2) std::swap(stats1,stats2) +#define BOOST_UNORDERED_COPY_STATS(stats1,stats2) stats1=stats2 +#define BOOST_UNORDERED_RESET_STATS_OF(x) x.reset_stats() +#define BOOST_UNORDERED_STATS_COUNTER(name) std::size_t name=0 +#define BOOST_UNORDERED_INCREMENT_STATS_COUNTER(name) ++name + +#else + +#define BOOST_UNORDERED_ADD_STATS(stats,args) ((void)0) +#define BOOST_UNORDERED_SWAP_STATS(stats1,stats2) ((void)0) +#define BOOST_UNORDERED_COPY_STATS(stats1,stats2) ((void)0) +#define BOOST_UNORDERED_RESET_STATS_OF(x) ((void)0) +#define BOOST_UNORDERED_STATS_COUNTER(name) ((void)0) +#define BOOST_UNORDERED_INCREMENT_STATS_COUNTER(name) ((void)0) + +#endif + +struct if_constexpr_void_else{void operator()()const{}}; + +template +void if_constexpr(F f,G g={}) +{ + std::get(std::forward_as_tuple(f,g))(); +} + +template::type* =nullptr> +void copy_assign_if(T& x,const T& y){x=y;} + +template::type* =nullptr> +void copy_assign_if(T&,const T&){} + +template::type* =nullptr> +void move_assign_if(T& x,T& y){x=std::move(y);} + +template::type* =nullptr> +void move_assign_if(T&,T&){} + +template::type* =nullptr> +void swap_if(T& x,T& y){using std::swap; swap(x,y);} + +template::type* =nullptr> +void swap_if(T&,T&){} + +template +struct is_std_allocator:std::false_type{}; + +template +struct is_std_allocator>:std::true_type{}; + +/* std::allocator::construct marked as deprecated */ +#if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +#elif defined(_STL_DISABLE_DEPRECATED_WARNING) +_STL_DISABLE_DEPRECATED_WARNING +#elif defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4996) +#endif + +template +struct alloc_has_construct +{ +private: + template + static decltype( + std::declval().construct( + std::declval(),std::declval()...), + std::true_type{} + ) check(int); + + template static std::false_type check(...); + +public: + static constexpr bool value=decltype(check(0))::value; +}; + +#if defined(_LIBCPP_SUPPRESS_DEPRECATED_POP) +_LIBCPP_SUPPRESS_DEPRECATED_POP +#elif defined(_STL_RESTORE_DEPRECATED_WARNING) +_STL_RESTORE_DEPRECATED_WARNING +#elif defined(_MSC_VER) +#pragma warning(pop) +#endif + +/* We expose the hard-coded max load factor so that tests can use it without + * needing to pull it from an instantiated class template such as the table + * class. + */ +static constexpr float mlf=0.875f; + +template +struct table_locator +{ + table_locator()=default; + table_locator(Group* pg_,unsigned int n_,Element* p_):pg{pg_},n{n_},p{p_}{} + + explicit operator bool()const noexcept{return p!=nullptr;} + + Group *pg=nullptr; + unsigned int n=0; + Element *p=nullptr; +}; + +struct try_emplace_args_t{}; + +template +class alloc_cted_insert_type +{ + using emplace_type=typename std::conditional< + std::is_constructible::value, + typename TypePolicy::init_type, + typename TypePolicy::value_type + >::type; + + using insert_type=typename std::conditional< + std::is_constructible::value, + emplace_type,typename TypePolicy::element_type + >::type; + + using alloc_cted = allocator_constructed; + alloc_cted val; + +public: + alloc_cted_insert_type(const Allocator& al_,Args&&... args):val{al_,std::forward(args)...} + { + } + + insert_type& value(){return val.value();} +}; + +template +alloc_cted_insert_type +alloc_make_insert_type(const Allocator& al,Args&&... args) +{ + return {al,std::forward(args)...}; +} + +template +class alloc_cted_or_fwded_key_type +{ + using key_type = typename TypePolicy::key_type; + allocator_constructed val; + +public: + alloc_cted_or_fwded_key_type(const Allocator& al_, KFwdRef k) + : val(al_, std::forward(k)) + { + } + + key_type&& move_or_fwd() { return std::move(val.value()); } +}; + +template +class alloc_cted_or_fwded_key_type::value>::type> +{ + // This specialization acts as a forwarding-reference wrapper + BOOST_UNORDERED_STATIC_ASSERT(std::is_reference::value); + KFwdRef ref; + +public: + alloc_cted_or_fwded_key_type(const Allocator&, KFwdRef k) + : ref(std::forward(k)) + { + } + + KFwdRef move_or_fwd() { return std::forward(ref); } +}; + +template +using is_map = + std::integral_constant::value>; + +template +using is_emplace_kv_able = std::integral_constant::value && + (is_similar::value || + is_complete_and_move_constructible::value)>; + +/* table_core. The TypePolicy template parameter is used to generate + * instantiations suitable for either maps or sets, and introduces non-standard + * init_type and element_type: + * + * - TypePolicy::key_type and TypePolicy::value_type have the obvious + * meaning. TypePolicy::mapped_type is expected to be provided as well + * when key_type and value_type are not the same. + * + * - TypePolicy::init_type is the type implicitly converted to when + * writing x.insert({...}). For maps, this is std::pair rather + * than std::pair so that, for instance, x.insert({"hello",0}) + * produces a cheaply moveable std::string&& ("hello") rather than + * a copyable const std::string&&. foa::table::insert is extended to accept + * both init_type and value_type references. + * + * - TypePolicy::construct and TypePolicy::destroy are used for the + * construction and destruction of the internal types: value_type, + * init_type, element_type, and key_type. + * + * - TypePolicy::move is used to provide move semantics for the internal + * types used by the container during rehashing and emplace. These types + * are init_type, value_type and emplace_type. During insertion, a + * stack-local type will be created based on the constructibility of the + * value_type and the supplied arguments. TypePolicy::move is used here + * for transfer of ownership. Similarly, TypePolicy::move is also used + * during rehashing when elements are moved to the new table. + * + * - TypePolicy::extract returns a const reference to the key part of + * a value of type value_type, init_type, element_type or + * decltype(TypePolicy::move(...)). + * + * - TypePolicy::element_type is the type that table_arrays uses when + * allocating buckets, which allows us to have flat and node container. + * For flat containers, element_type is value_type. For node + * containers, it is a strong typedef to value_type*. + * + * - TypePolicy::value_from returns a mutable reference to value_type from + * a given element_type. This is used when elements of the table themselves + * need to be moved, such as during move construction/assignment when + * allocators are unequal and there is no propagation. For all other cases, + * the element_type itself is moved. + */ + +#include + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4714) /* marked as __forceinline not inlined */ +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC,<=1900) +/* VS2015 marks as unreachable generic catch clauses around non-throwing + * code. + */ +#pragma warning(push) +#pragma warning(disable:4702) +#endif + +template< + typename TypePolicy,typename Group,template class Arrays, + typename SizeControl,typename Hash,typename Pred,typename Allocator +> +class + +#if defined(_MSC_VER)&&_MSC_FULL_VER>=190023918 +__declspec(empty_bases) /* activate EBO with multiple inheritance */ +#endif + +table_core:empty_value,empty_value,empty_value +{ +public: + using type_policy=TypePolicy; + using group_type=Group; + static constexpr auto N=group_type::N; + using size_policy=pow2_size_policy; + using prober=pow2_quadratic_prober; + using mix_policy=typename std::conditional< + hash_is_avalanching::value, + no_mix, + mulx_mix + >::type; + using alloc_traits=boost::allocator_traits; + using element_type=typename type_policy::element_type; + using arrays_type=Arrays; + using size_ctrl_type=SizeControl; + static constexpr auto uses_fancy_pointers=!std::is_same< + typename alloc_traits::pointer, + typename alloc_traits::value_type* + >::value; + + using key_type=typename type_policy::key_type; + using init_type=typename type_policy::init_type; + using value_type=typename type_policy::value_type; + using hasher=Hash; + using key_equal=Pred; + using allocator_type=Allocator; + using pointer=value_type*; + using const_pointer=const value_type*; + using reference=value_type&; + using const_reference=const value_type&; + using size_type=std::size_t; + using difference_type=std::ptrdiff_t; + using locator=table_locator; + using arrays_holder_type=arrays_holder; + +#if defined(BOOST_UNORDERED_ENABLE_STATS) + using cumulative_stats=table_core_cumulative_stats; + using stats=table_core_stats; +#endif + +#if defined(BOOST_GCC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + + table_core( + std::size_t n=default_bucket_count,const Hash& h_=Hash(), + const Pred& pred_=Pred(),const Allocator& al_=Allocator()): + hash_base{empty_init,h_},pred_base{empty_init,pred_}, + allocator_base{empty_init,al_},arrays(new_arrays(n)), + size_ctrl{initial_max_load(),0} + {} + +#if defined(BOOST_GCC) +#pragma GCC diagnostic pop +#endif + + /* genericize on an ArraysFn so that we can do things like delay an + * allocation for the group_access data required by cfoa after the move + * constructors of Hash, Pred have been invoked + */ + template + table_core( + Hash&& h_,Pred&& pred_,Allocator&& al_, + ArraysFn arrays_fn,const size_ctrl_type& size_ctrl_): + hash_base{empty_init,std::move(h_)}, + pred_base{empty_init,std::move(pred_)}, + allocator_base{empty_init,std::move(al_)}, + arrays(arrays_fn()),size_ctrl(size_ctrl_) + {} + + table_core(const table_core& x): + table_core{x,alloc_traits::select_on_container_copy_construction(x.al())}{} + + template + table_core(table_core&& x,arrays_holder_type&& ah,ArraysFn arrays_fn): + table_core( + std::move(x.h()),std::move(x.pred()),std::move(x.al()), + arrays_fn,x.size_ctrl) + { + x.arrays=ah.release(); + x.size_ctrl.ml=x.initial_max_load(); + x.size_ctrl.size=0; + BOOST_UNORDERED_SWAP_STATS(cstats,x.cstats); + } + + table_core(table_core&& x) + noexcept( + std::is_nothrow_move_constructible::value&& + std::is_nothrow_move_constructible::value&& + std::is_nothrow_move_constructible::value&& + !uses_fancy_pointers): + table_core{ + std::move(x),x.make_empty_arrays(),[&x]{return x.arrays;}} + {} + + table_core(const table_core& x,const Allocator& al_): + table_core{std::size_t(std::ceil(float(x.size())/mlf)),x.h(),x.pred(),al_} + { + copy_elements_from(x); + } + + table_core(table_core&& x,const Allocator& al_): + table_core{std::move(x.h()),std::move(x.pred()),al_} + { + if(al()==x.al()){ + using std::swap; + swap(arrays,x.arrays); + swap(size_ctrl,x.size_ctrl); + BOOST_UNORDERED_SWAP_STATS(cstats,x.cstats); + } + else{ + reserve(x.size()); + clear_on_exit c{x}; + (void)c; /* unused var warning */ + BOOST_UNORDERED_RESET_STATS_OF(x); + + /* This works because subsequent x.clear() does not depend on the + * elements' values. + */ + x.for_all_elements([this](element_type* p){ + unchecked_insert(type_policy::move(type_policy::value_from(*p))); + }); + } + } + + ~table_core()noexcept + { + for_all_elements([this](element_type* p){ + destroy_element(p); + }); + delete_arrays(arrays); + } + + std::size_t initial_max_load()const + { + static constexpr std::size_t small_capacity=2*N-1; + + auto capacity_=capacity(); + if(capacity_<=small_capacity){ + return capacity_; /* we allow 100% usage */ + } + else{ + return (std::size_t)(mlf*(float)(capacity_)); + } + } + + arrays_holder_type make_empty_arrays()const + { + return make_arrays(0); + } + + table_core& operator=(const table_core& x) + { + BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) + + static constexpr auto pocca= + alloc_traits::propagate_on_container_copy_assignment::value; + + if(this!=std::addressof(x)){ + /* If copy construction here winds up throwing, the container is still + * left intact so we perform these operations first. + */ + hasher tmp_h=x.h(); + key_equal tmp_p=x.pred(); + + clear(); + + /* Because we've asserted at compile-time that Hash and Pred are nothrow + * swappable, we can safely mutate our source container and maintain + * consistency between the Hash, Pred compatibility. + */ + using std::swap; + swap(h(),tmp_h); + swap(pred(),tmp_p); + + if_constexpr([&,this]{ + if(al()!=x.al()){ + auto ah=x.make_arrays(std::size_t(std::ceil(float(x.size())/mlf))); + delete_arrays(arrays); + arrays=ah.release(); + size_ctrl.ml=initial_max_load(); + } + copy_assign_if(al(),x.al()); + }); + /* noshrink: favor memory reuse over tightness */ + noshrink_reserve(x.size()); + copy_elements_from(x); + } + return *this; + } + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4127) /* conditional expression is constant */ +#endif + + table_core& operator=(table_core&& x) + noexcept( + (alloc_traits::propagate_on_container_move_assignment::value|| + alloc_traits::is_always_equal::value)&&!uses_fancy_pointers) + { + BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) + + static constexpr auto pocma= + alloc_traits::propagate_on_container_move_assignment::value; + + if(this!=std::addressof(x)){ + /* Given ambiguity in implementation strategies briefly discussed here: + * https://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2227 + * + * we opt into requiring nothrow swappability and eschew the move + * operations associated with Hash, Pred. + * + * To this end, we ensure that the user never has to consider the + * moved-from state of their Hash, Pred objects + */ + + using std::swap; + + clear(); + + if(pocma||al()==x.al()){ + auto ah=x.make_empty_arrays(); + swap(h(),x.h()); + swap(pred(),x.pred()); + delete_arrays(arrays); + move_assign_if(al(),x.al()); + arrays=x.arrays; + size_ctrl.ml=std::size_t(x.size_ctrl.ml); + size_ctrl.size=std::size_t(x.size_ctrl.size); + BOOST_UNORDERED_COPY_STATS(cstats,x.cstats); + x.arrays=ah.release(); + x.size_ctrl.ml=x.initial_max_load(); + x.size_ctrl.size=0; + BOOST_UNORDERED_RESET_STATS_OF(x); + } + else{ + swap(h(),x.h()); + swap(pred(),x.pred()); + + /* noshrink: favor memory reuse over tightness */ + noshrink_reserve(x.size()); + clear_on_exit c{x}; + (void)c; /* unused var warning */ + BOOST_UNORDERED_RESET_STATS_OF(x); + + /* This works because subsequent x.clear() does not depend on the + * elements' values. + */ + x.for_all_elements([this](element_type* p){ + unchecked_insert(type_policy::move(type_policy::value_from(*p))); + }); + } + } + return *this; + } + +#if defined(BOOST_MSVC) +#pragma warning(pop) /* C4127 */ +#endif + + allocator_type get_allocator()const noexcept{return al();} + + bool empty()const noexcept{return size()==0;} + std::size_t size()const noexcept{return size_ctrl.size;} + std::size_t max_size()const noexcept{return SIZE_MAX;} + + BOOST_FORCEINLINE + void erase(group_type* pg,unsigned int pos,element_type* p)noexcept + { + destroy_element(p); + recover_slot(pg,pos); + } + + BOOST_FORCEINLINE + void erase(unsigned char* pc,element_type* p)noexcept + { + destroy_element(p); + recover_slot(pc); + } + + template + BOOST_FORCEINLINE locator find(const Key& x)const + { + auto hash=hash_for(x); + return find(x,position_for(hash),hash); + } + +#if defined(BOOST_MSVC) +/* warning: forcing value to bool 'true' or 'false' in bool(pred()...) */ +#pragma warning(push) +#pragma warning(disable:4800) +#endif + + template + BOOST_FORCEINLINE locator find( + const Key& x,std::size_t pos0,std::size_t hash)const + { + BOOST_UNORDERED_STATS_COUNTER(num_cmps); + prober pb(pos0); + do{ + auto pos=pb.get(); + auto pg=arrays.groups()+pos; + auto mask=pg->match(hash); + if(mask){ + auto elements=arrays.elements(); + BOOST_UNORDERED_ASSUME(elements!=nullptr); + auto p=elements+pos*N; + BOOST_UNORDERED_PREFETCH_ELEMENTS(p,N); + do{ + BOOST_UNORDERED_INCREMENT_STATS_COUNTER(num_cmps); + auto n=unchecked_countr_zero(mask); + if(BOOST_LIKELY(bool(pred()(x,key_from(p[n]))))){ + BOOST_UNORDERED_ADD_STATS( + cstats.successful_lookup,(pb.length(),num_cmps)); + return {pg,n,p+n}; + } + mask&=mask-1; + }while(mask); + } + if(BOOST_LIKELY(pg->is_not_overflowed(hash))){ + BOOST_UNORDERED_ADD_STATS( + cstats.unsuccessful_lookup,(pb.length(),num_cmps)); + return {}; + } + } + while(BOOST_LIKELY(pb.next(arrays.groups_size_mask))); + BOOST_UNORDERED_ADD_STATS( + cstats.unsuccessful_lookup,(pb.length(),num_cmps)); + return {}; + } + +#if defined(BOOST_MSVC) +#pragma warning(pop) /* C4800 */ +#endif + + void swap(table_core& x) + noexcept( + alloc_traits::propagate_on_container_swap::value|| + alloc_traits::is_always_equal::value) + { + BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) + + static constexpr auto pocs= + alloc_traits::propagate_on_container_swap::value; + + using std::swap; + if_constexpr([&,this]{ + swap_if(al(),x.al()); + }, + [&,this]{ /* else */ + BOOST_ASSERT(al()==x.al()); + (void)this; /* makes sure captured this is used */ + }); + + swap(h(),x.h()); + swap(pred(),x.pred()); + swap(arrays,x.arrays); + swap(size_ctrl,x.size_ctrl); + } + + void clear()noexcept + { + auto p=arrays.elements(); + if(p){ + for(auto pg=arrays.groups(),last=pg+arrays.groups_size_mask+1; + pg!=last;++pg,p+=N){ + auto mask=match_really_occupied(pg,last); + while(mask){ + destroy_element(p+unchecked_countr_zero(mask)); + mask&=mask-1; + } + /* we wipe the entire metadata to reset the overflow byte as well */ + pg->initialize(); + } + arrays.groups()[arrays.groups_size_mask].set_sentinel(); + size_ctrl.ml=initial_max_load(); + size_ctrl.size=0; + } + } + + hasher hash_function()const{return h();} + key_equal key_eq()const{return pred();} + + std::size_t capacity()const noexcept + { + return arrays.elements()?(arrays.groups_size_mask+1)*N-1:0; + } + + float load_factor()const noexcept + { + if(capacity()==0)return 0; + else return float(size())/float(capacity()); + } + + float max_load_factor()const noexcept{return mlf;} + + std::size_t max_load()const noexcept{return size_ctrl.ml;} + + void rehash(std::size_t n) + { + auto m=size_t(std::ceil(float(size())/mlf)); + if(m>n)n=m; + if(n)n=capacity_for(n); /* exact resulting capacity */ + + if(n!=capacity())unchecked_rehash(n); + } + + void reserve(std::size_t n) + { + rehash(std::size_t(std::ceil(float(n)/mlf))); + } + +#if defined(BOOST_UNORDERED_ENABLE_STATS) + stats get_stats()const + { + auto insertion=cstats.insertion.get_summary(); + auto successful_lookup=cstats.successful_lookup.get_summary(); + auto unsuccessful_lookup=cstats.unsuccessful_lookup.get_summary(); + return{ + { + insertion.count, + insertion.sequence_summary[0] + }, + { + successful_lookup.count, + successful_lookup.sequence_summary[0], + successful_lookup.sequence_summary[1] + }, + { + unsuccessful_lookup.count, + unsuccessful_lookup.sequence_summary[0], + unsuccessful_lookup.sequence_summary[1] + }, + }; + } + + void reset_stats()noexcept + { + cstats.insertion.reset(); + cstats.successful_lookup.reset(); + cstats.unsuccessful_lookup.reset(); + } +#endif + + friend bool operator==(const table_core& x,const table_core& y) + { + return + x.size()==y.size()&& + x.for_all_elements_while([&](element_type* p){ + auto loc=y.find(key_from(*p)); + return loc&& + const_cast(type_policy::value_from(*p))== + const_cast(type_policy::value_from(*loc.p)); + }); + } + + friend bool operator!=(const table_core& x,const table_core& y) + { + return !(x==y); + } + + struct clear_on_exit + { + ~clear_on_exit(){x.clear();} + table_core& x; + }; + + Hash& h(){return hash_base::get();} + const Hash& h()const{return hash_base::get();} + Pred& pred(){return pred_base::get();} + const Pred& pred()const{return pred_base::get();} + Allocator& al(){return allocator_base::get();} + const Allocator& al()const{return allocator_base::get();} + + template + void construct_element(element_type* p,Args&&... args) + { + type_policy::construct(al(),p,std::forward(args)...); + } + + template + void construct_element(element_type* p,try_emplace_args_t,Args&&... args) + { + construct_element_from_try_emplace_args( + p, + std::integral_constant::value>{}, + std::forward(args)...); + } + + void destroy_element(element_type* p)noexcept + { + type_policy::destroy(al(),p); + } + + struct destroy_element_on_exit + { + ~destroy_element_on_exit(){this_->destroy_element(p);} + table_core *this_; + element_type *p; + }; + + template + static inline auto key_from(const T& x) + ->decltype(type_policy::extract(x)) + { + return type_policy::extract(x); + } + + template + static inline const Key& key_from( + try_emplace_args_t,const Key& x,const Args&...) + { + return x; + } + + template + inline std::size_t hash_for(const Key& x)const + { + return mix_policy::mix(h(),x); + } + + inline std::size_t position_for(std::size_t hash)const + { + return position_for(hash,arrays); + } + + static inline std::size_t position_for( + std::size_t hash,const arrays_type& arrays_) + { + return size_policy::position(hash,arrays_.groups_size_index); + } + + static inline int match_really_occupied(group_type* pg,group_type* last) + { + /* excluding the sentinel */ + return pg->match_occupied()&~(int(pg==last-1)<<(N-1)); + } + + template + locator unchecked_emplace_at( + std::size_t pos0,std::size_t hash,Args&&... args) + { + auto res=nosize_unchecked_emplace_at( + arrays,pos0,hash,std::forward(args)...); + ++size_ctrl.size; + return res; + } + + BOOST_NOINLINE void unchecked_rehash_for_growth() + { + auto new_arrays_=new_arrays_for_growth(); + unchecked_rehash(new_arrays_); + } + + template + BOOST_NOINLINE locator + unchecked_emplace_with_rehash(std::size_t hash,Args&&... args) + { + auto new_arrays_=new_arrays_for_growth(); + locator it; + BOOST_TRY{ + /* strong exception guarantee -> try insertion before rehash */ + it=nosize_unchecked_emplace_at( + new_arrays_,position_for(hash,new_arrays_), + hash,std::forward(args)...); + } + BOOST_CATCH(...){ + delete_arrays(new_arrays_); + BOOST_RETHROW + } + BOOST_CATCH_END + + /* new_arrays_ lifetime taken care of by unchecked_rehash */ + unchecked_rehash(new_arrays_); + ++size_ctrl.size; + return it; + } + + void noshrink_reserve(std::size_t n) + { + /* used only on assignment after element clearance */ + BOOST_ASSERT(empty()); + + if(n){ + n=std::size_t(std::ceil(float(n)/mlf)); /* elements -> slots */ + n=capacity_for(n); /* exact resulting capacity */ + + if(n>capacity()){ + auto new_arrays_=new_arrays(n); + delete_arrays(arrays); + arrays=new_arrays_; + size_ctrl.ml=initial_max_load(); + } + } + } + + template + void for_all_elements(F f)const + { + for_all_elements(arrays,f); + } + + template + static auto for_all_elements(const arrays_type& arrays_,F f) + ->decltype(f(nullptr),void()) + { + for_all_elements_while(arrays_,[&](element_type* p){f(p);return true;}); + } + + template + static auto for_all_elements(const arrays_type& arrays_,F f) + ->decltype(f(nullptr,0,nullptr),void()) + { + for_all_elements_while( + arrays_,[&](group_type* pg,unsigned int n,element_type* p) + {f(pg,n,p);return true;}); + } + + template + bool for_all_elements_while(F f)const + { + return for_all_elements_while(arrays,f); + } + + template + static auto for_all_elements_while(const arrays_type& arrays_,F f) + ->decltype(f(nullptr),bool()) + { + return for_all_elements_while( + arrays_,[&](group_type*,unsigned int,element_type* p){return f(p);}); + } + + template + static auto for_all_elements_while(const arrays_type& arrays_,F f) + ->decltype(f(nullptr,0,nullptr),bool()) + { + auto p=arrays_.elements(); + if(p){ + for(auto pg=arrays_.groups(),last=pg+arrays_.groups_size_mask+1; + pg!=last;++pg,p+=N){ + auto mask=match_really_occupied(pg,last); + while(mask){ + auto n=unchecked_countr_zero(mask); + if(!f(pg,n,p+n))return false; + mask&=mask-1; + } + } + } + return true; + } + + arrays_type arrays; + size_ctrl_type size_ctrl; + +#if defined(BOOST_UNORDERED_ENABLE_STATS) + mutable cumulative_stats cstats; +#endif + +private: + template< + typename,typename,template class, + typename,typename,typename,typename + > + friend class table_core; + + using hash_base=empty_value; + using pred_base=empty_value; + using allocator_base=empty_value; + +#if defined(BOOST_GCC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + + /* used by allocator-extended move ctor */ + + table_core(Hash&& h_,Pred&& pred_,const Allocator& al_): + hash_base{empty_init,std::move(h_)}, + pred_base{empty_init,std::move(pred_)}, + allocator_base{empty_init,al_},arrays(new_arrays(0)), + size_ctrl{initial_max_load(),0} + { + } + +#if defined(BOOST_GCC) +#pragma GCC diagnostic pop +#endif + + arrays_type new_arrays(std::size_t n)const + { + return arrays_type::new_(typename arrays_type::allocator_type(al()),n); + } + + arrays_type new_arrays_for_growth()const + { + /* Due to the anti-drift mechanism (see recover_slot), the new arrays may + * be of the same size as the old arrays; in the limit, erasing one + * element at full load and then inserting could bring us back to the same + * capacity after a costly rehash. To avoid this, we jump to the next + * capacity level when the number of erased elements is <= 10% of total + * elements at full load, which is implemented by requesting additional + * F*size elements, with F = P * 10% / (1 - P * 10%), where P is the + * probability of an element having caused overflow; P has been measured as + * ~0.162 under ideal conditions, yielding F ~ 0.0165 ~ 1/61. + */ + return new_arrays(std::size_t( + std::ceil(static_cast(size()+size()/61+1)/mlf))); + } + + void delete_arrays(arrays_type& arrays_)noexcept + { + arrays_type::delete_(typename arrays_type::allocator_type(al()),arrays_); + } + + arrays_holder_type make_arrays(std::size_t n)const + { + return {new_arrays(n),al()}; + } + + template + void construct_element_from_try_emplace_args( + element_type* p,std::false_type,Key&& x,Args&&... args) + { + type_policy::construct( + this->al(),p, + std::piecewise_construct, + std::forward_as_tuple(std::forward(x)), + std::forward_as_tuple(std::forward(args)...)); + } + + /* This overload allows boost::unordered_flat_set to internally use + * try_emplace to implement heterogeneous insert (P2363). + */ + + template + void construct_element_from_try_emplace_args( + element_type* p,std::true_type,Key&& x) + { + type_policy::construct(this->al(),p,std::forward(x)); + } + + void copy_elements_from(const table_core& x) + { + BOOST_ASSERT(empty()); + BOOST_ASSERT(this!=std::addressof(x)); + if(arrays.groups_size_mask==x.arrays.groups_size_mask){ + fast_copy_elements_from(x); + } + else{ + x.for_all_elements([this](const element_type* p){ + unchecked_insert(*p); + }); + } + } + + void fast_copy_elements_from(const table_core& x) + { + if(arrays.elements()&&x.arrays.elements()){ + copy_elements_array_from(x); + copy_groups_array_from(x); + size_ctrl.ml=std::size_t(x.size_ctrl.ml); + size_ctrl.size=std::size_t(x.size_ctrl.size); + } + } + + void copy_elements_array_from(const table_core& x) + { + copy_elements_array_from( + x, + std::integral_constant< + bool, + is_trivially_copy_constructible::value&&( + is_std_allocator::value|| + !alloc_has_construct::value) + >{} + ); + } + + void copy_elements_array_from( + const table_core& x,std::true_type /* -> memcpy */) + { + /* reinterpret_cast: GCC may complain about value_type not being trivially + * copy-assignable when we're relying on trivial copy constructibility. + */ + std::memcpy( + reinterpret_cast(arrays.elements()), + reinterpret_cast(x.arrays.elements()), + x.capacity()*sizeof(value_type)); + } + + void copy_elements_array_from( + const table_core& x,std::false_type /* -> manual */) + { + std::size_t num_constructed=0; + BOOST_TRY{ + x.for_all_elements([&,this](const element_type* p){ + construct_element(arrays.elements()+(p-x.arrays.elements()),*p); + ++num_constructed; + }); + } + BOOST_CATCH(...){ + if(num_constructed){ + x.for_all_elements_while([&,this](const element_type* p){ + destroy_element(arrays.elements()+(p-x.arrays.elements())); + return --num_constructed!=0; + }); + } + BOOST_RETHROW + } + BOOST_CATCH_END + } + + void copy_groups_array_from(const table_core& x) { + copy_groups_array_from(x,is_trivially_copy_assignable{}); + } + + void copy_groups_array_from( + const table_core& x, std::true_type /* -> memcpy */) + { + std::memcpy( + arrays.groups(),x.arrays.groups(), + (arrays.groups_size_mask+1)*sizeof(group_type)); + } + + void copy_groups_array_from( + const table_core& x, std::false_type /* -> manual */) + { + auto pg=arrays.groups(); + auto xpg=x.arrays.groups(); + for(std::size_t i=0;i(pg)+pos); + } + + static std::size_t capacity_for(std::size_t n) + { + return size_policy::size(size_index_for(n))*N-1; + } + + BOOST_NOINLINE void unchecked_rehash(std::size_t n) + { + auto new_arrays_=new_arrays(n); + unchecked_rehash(new_arrays_); + } + + BOOST_NOINLINE void unchecked_rehash(arrays_type& new_arrays_) + { + std::size_t num_destroyed=0; + BOOST_TRY{ + for_all_elements([&,this](element_type* p){ + nosize_transfer_element(p,new_arrays_,num_destroyed); + }); + } + BOOST_CATCH(...){ + if(num_destroyed){ + for_all_elements_while( + [&,this](group_type* pg,unsigned int n,element_type*){ + recover_slot(pg,n); + return --num_destroyed!=0; + } + ); + } + for_all_elements(new_arrays_,[this](element_type* p){ + destroy_element(p); + }); + delete_arrays(new_arrays_); + BOOST_RETHROW + } + BOOST_CATCH_END + + /* either all moved and destroyed or all copied */ + BOOST_ASSERT(num_destroyed==size()||num_destroyed==0); + if(num_destroyed!=size()){ + for_all_elements([this](element_type* p){ + destroy_element(p); + }); + } + delete_arrays(arrays); + arrays=new_arrays_; + size_ctrl.ml=initial_max_load(); + } + + template + void unchecked_insert(Value&& x) + { + auto hash=hash_for(key_from(x)); + unchecked_emplace_at(position_for(hash),hash,std::forward(x)); + } + + void nosize_transfer_element( + element_type* p,const arrays_type& arrays_,std::size_t& num_destroyed) + { + nosize_transfer_element( + p,hash_for(key_from(*p)),arrays_,num_destroyed, + std::integral_constant< /* std::move_if_noexcept semantics */ + bool, + std::is_nothrow_move_constructible::value|| + !std::is_same::value|| + !std::is_copy_constructible::value>{}); + } + + void nosize_transfer_element( + element_type* p,std::size_t hash,const arrays_type& arrays_, + std::size_t& num_destroyed,std::true_type /* ->move */) + { + /* Destroy p even if an an exception is thrown in the middle of move + * construction, which could leave the source half-moved. + */ + ++num_destroyed; + destroy_element_on_exit d{this,p}; + (void)d; /* unused var warning */ + nosize_unchecked_emplace_at( + arrays_,position_for(hash,arrays_),hash,type_policy::move(*p)); + } + + void nosize_transfer_element( + element_type* p,std::size_t hash,const arrays_type& arrays_, + std::size_t& /*num_destroyed*/,std::false_type /* ->copy */) + { + nosize_unchecked_emplace_at( + arrays_,position_for(hash,arrays_),hash, + const_cast(*p)); + } + + template + locator nosize_unchecked_emplace_at( + const arrays_type& arrays_,std::size_t pos0,std::size_t hash, + Args&&... args) + { + for(prober pb(pos0);;pb.next(arrays_.groups_size_mask)){ + auto pos=pb.get(); + auto pg=arrays_.groups()+pos; + auto mask=pg->match_available(); + if(BOOST_LIKELY(mask!=0)){ + auto n=unchecked_countr_zero(mask); + auto p=arrays_.elements()+pos*N+n; + construct_element(p,std::forward(args)...); + pg->set(n,hash); + BOOST_UNORDERED_ADD_STATS(cstats.insertion,(pb.length())); + return {pg,n,p}; + } + else pg->mark_overflow(hash); + } + } +}; + +#if BOOST_WORKAROUND(BOOST_MSVC,<=1900) +#pragma warning(pop) /* C4702 */ +#endif + +#if defined(BOOST_MSVC) +#pragma warning(pop) /* C4714 */ +#endif + +#include + +} /* namespace foa */ +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#undef BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED +#undef BOOST_UNORDERED_HAS_FEATURE +#undef BOOST_UNORDERED_HAS_BUILTIN +#endif diff --git a/src/boost/unordered/detail/foa/cumulative_stats.hpp b/src/boost/unordered/detail/foa/cumulative_stats.hpp new file mode 100644 index 00000000..13a15747 --- /dev/null +++ b/src/boost/unordered/detail/foa/cumulative_stats.hpp @@ -0,0 +1,177 @@ +/* Copyright 2024 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_FOA_CUMULATIVE_STATS_HPP +#define BOOST_UNORDERED_DETAIL_FOA_CUMULATIVE_STATS_HPP + +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_THREADS) +#include +#include +#endif + +namespace boost{ +namespace unordered{ +namespace detail{ +namespace foa{ + +/* Cumulative one-pass calculation of the average, variance and deviation of + * running sequences. + */ + +struct sequence_stats_data +{ + double m=0.0; + double m_prior=0.0; + double s=0.0; +}; + +struct welfords_algorithm /* 0-based */ +{ + template + int operator()(T&& x,sequence_stats_data& d)const noexcept + { + static_assert( + noexcept(static_cast(x)), + "Argument conversion to double must not throw."); + + d.m_prior=d.m; + d.m+=(static_cast(x)-d.m)/static_cast(n); + d.s+=(n!=1)* + (static_cast(x)-d.m_prior)*(static_cast(x)-d.m); + + return 0; /* mp11::tuple_transform requires that return type not be void */ + } + + std::size_t n; +}; + +struct sequence_stats_summary +{ + double average; + double variance; + double deviation; +}; + +/* Stats calculated jointly for N same-sized sequences to save the space + * for count. + */ + +template +class cumulative_stats +{ +public: + struct summary + { + std::size_t count; + std::array sequence_summary; + }; + + void reset()noexcept{*this=cumulative_stats();} + + template + void add(Ts&&... xs)noexcept + { + static_assert( + sizeof...(Ts)==N,"A sample must be provided for each sequence."); + + if(BOOST_UNLIKELY(++n==0)){ /* wraparound */ + reset(); + n=1; + } + mp11::tuple_transform( + welfords_algorithm{n}, + std::forward_as_tuple(std::forward(xs)...), + data); + } + + summary get_summary()const noexcept + { + summary res; + res.count=n; + for(std::size_t i=0;i(n):0.0, /* biased */ + deviation=std::sqrt(variance); + res.sequence_summary[i]={average,variance,deviation}; + } + return res; + } + +private: + std::size_t n=0; + std::array data; +}; + +#if defined(BOOST_HAS_THREADS) + +template +class concurrent_cumulative_stats:cumulative_stats +{ + using super=cumulative_stats; + using lock_guard=std::lock_guard; + +public: + using summary=typename super::summary; + + concurrent_cumulative_stats()noexcept:super{}{} + concurrent_cumulative_stats(const concurrent_cumulative_stats& x)noexcept: + concurrent_cumulative_stats{x,lock_guard{x.mut}}{} + + concurrent_cumulative_stats& + operator=(const concurrent_cumulative_stats& x)noexcept + { + auto x1=x; + lock_guard lck{mut}; + static_cast(*this)=x1; + return *this; + } + + void reset()noexcept + { + lock_guard lck{mut}; + super::reset(); + } + + template + void add(Ts&&... xs)noexcept + { + lock_guard lck{mut}; + super::add(std::forward(xs)...); + } + + summary get_summary()const noexcept + { + lock_guard lck{mut}; + return super::get_summary(); + } + +private: + concurrent_cumulative_stats(const super& x,lock_guard&&):super{x}{} + + mutable rw_spinlock mut; +}; + +#else + +template +using concurrent_cumulative_stats=cumulative_stats; + +#endif + +} /* namespace foa */ +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/foa/flat_map_types.hpp b/src/boost/unordered/detail/foa/flat_map_types.hpp new file mode 100644 index 00000000..75069131 --- /dev/null +++ b/src/boost/unordered/detail/foa/flat_map_types.hpp @@ -0,0 +1,94 @@ +// Copyright (C) 2023 Christian Mazakas +// Copyright (C) 2024 Braden Ganetsky +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP +#define BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP + +#include + +#include + +namespace boost { + namespace unordered { + namespace detail { + namespace foa { + template struct flat_map_types + { + using key_type = Key; + using mapped_type = T; + using raw_key_type = typename std::remove_const::type; + using raw_mapped_type = typename std::remove_const::type; + + using init_type = std::pair; + using moved_type = std::pair; + using value_type = std::pair; + + using element_type = value_type; + + using types = flat_map_types; + using constructibility_checker = map_types_constructibility; + + static value_type& value_from(element_type& x) { return x; } + + template + static raw_key_type const& extract(std::pair const& kv) + { + return kv.first; + } + + static moved_type move(init_type& x) + { + return {std::move(x.first), std::move(x.second)}; + } + + static moved_type move(element_type& x) + { + // TODO: we probably need to launder here + return {std::move(const_cast(x.first)), + std::move(const_cast(x.second))}; + } + + template + static void construct(A& al, init_type* p, Args&&... args) + { + constructibility_checker::check(al, p, std::forward(args)...); + boost::allocator_construct(al, p, std::forward(args)...); + } + + template + static void construct(A& al, value_type* p, Args&&... args) + { + constructibility_checker::check(al, p, std::forward(args)...); + boost::allocator_construct(al, p, std::forward(args)...); + } + + template + static void construct(A& al, key_type* p, Args&&... args) + { + constructibility_checker::check(al, p, std::forward(args)...); + boost::allocator_construct(al, p, std::forward(args)...); + } + + template static void destroy(A& al, init_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + + template static void destroy(A& al, value_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + + template static void destroy(A& al, key_type* p) noexcept + { + boost::allocator_destroy(al, p); + } + }; + } // namespace foa + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP diff --git a/src/boost/unordered/detail/foa/ignore_wshadow.hpp b/src/boost/unordered/detail/foa/ignore_wshadow.hpp new file mode 100644 index 00000000..f84262bc --- /dev/null +++ b/src/boost/unordered/detail/foa/ignore_wshadow.hpp @@ -0,0 +1,35 @@ +/* Copyright 2023 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#include + +#if defined(BOOST_GCC) +#if !defined(BOOST_UNORDERED_DETAIL_RESTORE_WSHADOW) + /* GCC's -Wshadow triggers at scenarios like this: + * + * struct foo{}; + * template + * struct derived:Base + * { + * void f(){int foo;} + * }; + * + * derivedx; + * x.f(); // declaration of "foo" in derived::f shadows base type "foo" + * + * This makes shadowing warnings unavoidable in general when a class template + * derives from user-provided classes, as is the case with foa::table_core + * deriving from empty_value. + */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#else +#pragma GCC diagnostic pop +#endif +#endif diff --git a/src/boost/unordered/detail/foa/reentrancy_check.hpp b/src/boost/unordered/detail/foa/reentrancy_check.hpp new file mode 100644 index 00000000..2855056a --- /dev/null +++ b/src/boost/unordered/detail/foa/reentrancy_check.hpp @@ -0,0 +1,138 @@ +/* Copyright 2023 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_FOA_REENTRANCY_CHECK_HPP +#define BOOST_UNORDERED_DETAIL_FOA_REENTRANCY_CHECK_HPP + +#include +#include + +#if !defined(BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK)&& \ + !defined(BOOST_ASSERT_IS_VOID) +#define BOOST_UNORDERED_REENTRANCY_CHECK +#endif + +namespace boost{ +namespace unordered{ +namespace detail{ +namespace foa{ + +#if defined(BOOST_UNORDERED_REENTRANCY_CHECK) + +class entry_trace +{ +public: + entry_trace(const void* px_):px{px_} + { + if(px){ + BOOST_ASSERT_MSG(!find(px),"reentrancy not allowed"); + header()=this; + } + } + + /* not used but VS in pre-C++17 mode needs to see it for RVO */ + entry_trace(const entry_trace&); + + ~entry_trace(){clear();} + + void clear() + { + if(px){ + header()=next; + px=nullptr; + } + } + +private: + static entry_trace*& header() + { + thread_local entry_trace *pe=nullptr; + return pe; + } + + static bool find(const void* px) + { + for(auto pe=header();pe;pe=pe->next){ + if(pe->px==px)return true; + } + return false; + } + + const void *px; + entry_trace *next=header(); +}; + +template +struct reentrancy_checked +{ + template + reentrancy_checked(const void* px,Args&&... args): + tr{px},lck{std::forward(args)...}{} + + void unlock() + { + lck.unlock(); + tr.clear(); + } + + entry_trace tr; + LockGuard lck; +}; + +template +struct reentrancy_bichecked +{ + template + reentrancy_bichecked(const void* px,const void* py,Args&&... args): + tr1{px},tr2{py!=px?py:nullptr},lck{std::forward(args)...}{} + + void unlock() + { + lck.unlock(); + tr2.clear(); + tr1.clear(); + } + + entry_trace tr1,tr2; + LockGuard lck; +}; + +#else + +template +struct reentrancy_checked +{ + template + reentrancy_checked(const void*,Args&&... args): + lck{std::forward(args)...}{} + + void unlock(){lck.unlock();} + + LockGuard lck; +}; + +template +struct reentrancy_bichecked +{ + template + reentrancy_bichecked(const void*,const void*,Args&&... args): + lck{std::forward(args)...}{} + + void unlock(){lck.unlock();} + + LockGuard lck; +}; + +#endif + +} /* namespace foa */ +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/foa/restore_wshadow.hpp b/src/boost/unordered/detail/foa/restore_wshadow.hpp new file mode 100644 index 00000000..89c32c23 --- /dev/null +++ b/src/boost/unordered/detail/foa/restore_wshadow.hpp @@ -0,0 +1,11 @@ +/* Copyright 2023 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#define BOOST_UNORDERED_DETAIL_RESTORE_WSHADOW +#include +#undef BOOST_UNORDERED_DETAIL_RESTORE_WSHADOW diff --git a/src/boost/unordered/detail/foa/rw_spinlock.hpp b/src/boost/unordered/detail/foa/rw_spinlock.hpp new file mode 100644 index 00000000..8437fd3a --- /dev/null +++ b/src/boost/unordered/detail/foa/rw_spinlock.hpp @@ -0,0 +1,179 @@ +#ifndef BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED +#define BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +namespace boost{ +namespace unordered{ +namespace detail{ +namespace foa{ + +class rw_spinlock +{ +private: + + // bit 31: locked exclusive + // bit 30: writer pending + // bit 29..0: reader lock count + + static constexpr std::uint32_t locked_exclusive_mask = 1u << 31; // 0x8000'0000 + static constexpr std::uint32_t writer_pending_mask = 1u << 30; // 0x4000'0000 + static constexpr std::uint32_t reader_lock_count_mask = writer_pending_mask - 1; // 0x3FFF'FFFF + + std::atomic state_ = {}; + +private: + + // Effects: Provides a hint to the implementation that the current thread + // has been unable to make progress for k+1 iterations. + + static void yield( unsigned k ) noexcept + { + unsigned const sleep_every = 1024; // see below + + k %= sleep_every; + + if( k < 5 ) + { + // Intel recommendation from the Optimization Reference Manual + // Exponentially increase number of PAUSE instructions each + // iteration until reaching a maximum which is approximately + // one timeslice long (2^4 == 16 in our case) + + unsigned const pause_count = 1u << k; + + for( unsigned i = 0; i < pause_count; ++i ) + { + boost::core::sp_thread_pause(); + } + } + else if( k < sleep_every - 1 ) + { + // Once the maximum number of PAUSE instructions is reached, + // we switch to yielding the timeslice immediately + + boost::core::sp_thread_yield(); + } + else + { + // After `sleep_every` iterations of no progress, we sleep, + // to avoid a deadlock if a lower priority thread has the lock + + boost::core::sp_thread_sleep(); + } + } + +public: + + bool try_lock_shared() noexcept + { + std::uint32_t st = state_.load( std::memory_order_relaxed ); + + if( st >= reader_lock_count_mask ) + { + // either bit 31 set, bit 30 set, or reader count is max + return false; + } + + std::uint32_t newst = st + 1; + return state_.compare_exchange_strong( st, newst, std::memory_order_acquire, std::memory_order_relaxed ); + } + + void lock_shared() noexcept + { + for( unsigned k = 0; ; ++k ) + { + std::uint32_t st = state_.load( std::memory_order_relaxed ); + + if( st < reader_lock_count_mask ) + { + std::uint32_t newst = st + 1; + if( state_.compare_exchange_weak( st, newst, std::memory_order_acquire, std::memory_order_relaxed ) ) return; + } + + yield( k ); + } + } + + void unlock_shared() noexcept + { + // pre: locked shared, not locked exclusive + + state_.fetch_sub( 1, std::memory_order_release ); + + // if the writer pending bit is set, there's a writer waiting + // let it acquire the lock; it will clear the bit on unlock + } + + bool try_lock() noexcept + { + std::uint32_t st = state_.load( std::memory_order_relaxed ); + + if( st & locked_exclusive_mask ) + { + // locked exclusive + return false; + } + + if( st & reader_lock_count_mask ) + { + // locked shared + return false; + } + + std::uint32_t newst = locked_exclusive_mask; + return state_.compare_exchange_strong( st, newst, std::memory_order_acquire, std::memory_order_relaxed ); + } + + void lock() noexcept + { + for( unsigned k = 0; ; ++k ) + { + std::uint32_t st = state_.load( std::memory_order_relaxed ); + + if( st & locked_exclusive_mask ) + { + // locked exclusive, spin + } + else if( ( st & reader_lock_count_mask ) == 0 ) + { + // not locked exclusive, not locked shared, try to lock + + std::uint32_t newst = locked_exclusive_mask; + if( state_.compare_exchange_weak( st, newst, std::memory_order_acquire, std::memory_order_relaxed ) ) return; + } + else if( st & writer_pending_mask ) + { + // writer pending bit already set, nothing to do + } + else + { + // locked shared, set writer pending bit + + std::uint32_t newst = st | writer_pending_mask; + state_.compare_exchange_weak( st, newst, std::memory_order_relaxed, std::memory_order_relaxed ); + } + + yield( k ); + } + } + + void unlock() noexcept + { + // pre: locked exclusive, not locked shared + state_.store( 0, std::memory_order_release ); + } +}; + +} /* namespace foa */ +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif // BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED diff --git a/src/boost/unordered/detail/foa/tuple_rotate_right.hpp b/src/boost/unordered/detail/foa/tuple_rotate_right.hpp new file mode 100644 index 00000000..bd08842f --- /dev/null +++ b/src/boost/unordered/detail/foa/tuple_rotate_right.hpp @@ -0,0 +1,53 @@ +/* Copyright 2023-2024 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_FOA_TUPLE_ROTATE_RIGHT_HPP +#define BOOST_UNORDERED_DETAIL_FOA_TUPLE_ROTATE_RIGHT_HPP + +#include +#include +#include +#include + +namespace boost{ +namespace unordered{ +namespace detail{ +namespace foa{ + +template +using tuple_rotate_right_return_type=mp11::mp_rotate_right_c< + typename std::remove_cv::type>::type, + Offset +>; + +template +tuple_rotate_right_return_type +tuple_rotate_right_aux(mp11::index_sequence,Tuple&& x) +{ + return tuple_rotate_right_return_type{ + std::get<(Is+sizeof...(Is)-Offset)%sizeof...(Is)>( + std::forward(x))...}; +} + +template +tuple_rotate_right_return_type tuple_rotate_right(Tuple&& x) +{ + using RawTuple=typename std::remove_cv< + typename std::remove_reference::type>::type; + + return tuple_rotate_right_aux( + mp11::make_index_sequence::value>{}, + std::forward(x)); +} + +} /* namespace foa */ +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/foa/types_constructibility.hpp b/src/boost/unordered/detail/foa/types_constructibility.hpp new file mode 100644 index 00000000..10b9208b --- /dev/null +++ b/src/boost/unordered/detail/foa/types_constructibility.hpp @@ -0,0 +1,172 @@ +// Copyright (C) 2024 Braden Ganetsky +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_FOA_TYPES_CONSTRUCTIBILITY_HPP +#define BOOST_UNORDERED_DETAIL_FOA_TYPES_CONSTRUCTIBILITY_HPP + +#include +#include +#include +#include + +namespace boost { + namespace unordered { + namespace detail { + namespace foa { + template struct check_key_type_t + { + static_assert(std::is_constructible::value, + "key_type must be constructible from Args"); + }; + template struct check_key_type_t + { + static_assert(std::is_constructible::value, + "key_type must be default constructible"); + }; + template struct check_key_type_t + { + static_assert(std::is_constructible::value, + "key_type must be copy constructible"); + }; + template struct check_key_type_t + { + static_assert(std::is_constructible::value, + "key_type must be move constructible"); + }; + + template struct check_mapped_type_t + { + static_assert(std::is_constructible::value, + "mapped_type must be constructible from Args"); + }; + template struct check_mapped_type_t + { + static_assert(std::is_constructible::value, + "mapped_type must be default constructible"); + }; + template + struct check_mapped_type_t + { + static_assert(std::is_constructible::value, + "mapped_type must be copy constructible"); + }; + template struct check_mapped_type_t + { + static_assert(std::is_constructible::value, + "mapped_type must be move constructible"); + }; + + template struct map_types_constructibility + { + using key_type = typename TypePolicy::key_type; + using mapped_type = typename TypePolicy::mapped_type; + using init_type = typename TypePolicy::init_type; + using value_type = typename TypePolicy::value_type; + + template + static void check(A&, X*, Args&&...) + { + // Pass through, as we cannot say anything about a general allocator + } + + template static void check_key_type() + { + (void)check_key_type_t{}; + } + template static void check_mapped_type() + { + (void)check_mapped_type_t{}; + } + + template + static void check(std::allocator&, key_type*, Arg&&) + { + check_key_type(); + } + + template + static void check( + std::allocator&, value_type*, Arg1&&, Arg2&&) + { + check_key_type(); + check_mapped_type(); + } + template + static void check(std::allocator&, value_type*, + const std::pair&) + { + check_key_type(); + check_mapped_type(); + } + template + static void check( + std::allocator&, value_type*, std::pair&&) + { + check_key_type(); + check_mapped_type(); + } + template + static void check(std::allocator&, value_type*, + std::piecewise_construct_t, std::tuple&&, + std::tuple&&) + { + check_key_type(); + check_mapped_type(); + } + + template + static void check( + std::allocator&, init_type*, Arg1&&, Arg2&&) + { + check_key_type(); + check_mapped_type(); + } + template + static void check(std::allocator&, init_type*, + const std::pair&) + { + check_key_type(); + check_mapped_type(); + } + template + static void check( + std::allocator&, init_type*, std::pair&&) + { + check_key_type(); + check_mapped_type(); + } + template + static void check(std::allocator&, init_type*, + std::piecewise_construct_t, std::tuple&&, + std::tuple&&) + { + check_key_type(); + check_mapped_type(); + } + }; + + template struct set_types_constructibility + { + using key_type = typename TypePolicy::key_type; + using value_type = typename TypePolicy::value_type; + static_assert(std::is_same::value, ""); + + template + static void check(A&, X*, Args&&...) + { + // Pass through, as we cannot say anything about a general allocator + } + + template + static void check(std::allocator&, key_type*, Args&&...) + { + (void)check_key_type_t{}; + } + }; + } // namespace foa + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_FOA_TYPES_CONSTRUCTIBILITY_HPP diff --git a/src/boost/unordered/detail/mulx.hpp b/src/boost/unordered/detail/mulx.hpp new file mode 100644 index 00000000..c2ec2701 --- /dev/null +++ b/src/boost/unordered/detail/mulx.hpp @@ -0,0 +1,129 @@ +#ifndef BOOST_UNORDERED_DETAIL_MULX_HPP +#define BOOST_UNORDERED_DETAIL_MULX_HPP + +// Copyright 2022 Peter Dimov. +// Copyright 2022 Joaquin M Lopez Munoz. +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +#if defined(_MSC_VER) && !defined(__clang__) +# include +#endif + +namespace boost { +namespace unordered { +namespace detail { + +// Bit mixer based on the mulx primitive + +#if defined(_MSC_VER) && defined(_M_X64) && !defined(__clang__) + +__forceinline boost::uint64_t mulx64( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t r2; + boost::uint64_t r = _umul128( x, y, &r2 ); + return r ^ r2; +} + +#elif defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) + +__forceinline boost::uint64_t mulx64( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t r = x * y; + boost::uint64_t r2 = __umulh( x, y ); + return r ^ r2; +} + +#elif defined(__SIZEOF_INT128__) + +inline boost::uint64_t mulx64( boost::uint64_t x, boost::uint64_t y ) +{ + __uint128_t r = (__uint128_t)x * y; + return (boost::uint64_t)r ^ (boost::uint64_t)( r >> 64 ); +} + +#else + +inline boost::uint64_t mulx64( boost::uint64_t x, boost::uint64_t y ) +{ + boost::uint64_t x1 = (boost::uint32_t)x; + boost::uint64_t x2 = x >> 32; + + boost::uint64_t y1 = (boost::uint32_t)y; + boost::uint64_t y2 = y >> 32; + + boost::uint64_t r3 = x2 * y2; + + boost::uint64_t r2a = x1 * y2; + + r3 += r2a >> 32; + + boost::uint64_t r2b = x2 * y1; + + r3 += r2b >> 32; + + boost::uint64_t r1 = x1 * y1; + + boost::uint64_t r2 = (r1 >> 32) + (boost::uint32_t)r2a + (boost::uint32_t)r2b; + + r1 = (r2 << 32) + (boost::uint32_t)r1; + r3 += r2 >> 32; + + return r1 ^ r3; +} + +#endif + +inline boost::uint32_t mulx32( boost::uint32_t x, boost::uint32_t y ) +{ + boost::uint64_t r = (boost::uint64_t)x * y; + +#if defined(__MSVC_RUNTIME_CHECKS) + + return (boost::uint32_t)(r & UINT32_MAX) ^ (boost::uint32_t)(r >> 32); + +#else + + return (boost::uint32_t)r ^ (boost::uint32_t)(r >> 32); + +#endif +} + +#if defined(SIZE_MAX) +#if ((((SIZE_MAX >> 16) >> 16) >> 16) >> 15) != 0 +#define BOOST_UNORDERED_64B_ARCHITECTURE /* >64 bits assumed as 64 bits */ +#endif +#elif defined(UINTPTR_MAX) /* used as proxy for std::size_t */ +#if ((((UINTPTR_MAX >> 16) >> 16) >> 16) >> 15) != 0 +#define BOOST_UNORDERED_64B_ARCHITECTURE +#endif +#endif + +inline std::size_t mulx( std::size_t x ) noexcept +{ +#if defined(BOOST_UNORDERED_64B_ARCHITECTURE) + + // multiplier is phi + return (std::size_t)mulx64( (boost::uint64_t)x, 0x9E3779B97F4A7C15ull ); + +#else /* 32 bits assumed */ + + // multiplier from https://arxiv.org/abs/2001.05304 + return mulx32( x, 0xE817FB2Du ); + +#endif +} + +#ifdef BOOST_UNORDERED_64B_ARCHITECTURE +#undef BOOST_UNORDERED_64B_ARCHITECTURE +#endif + +} // namespace detail +} // namespace unordered +} // namespace boost + +#endif // #ifndef BOOST_UNORDERED_DETAIL_MULX_HPP diff --git a/src/boost/unordered/detail/narrow_cast.hpp b/src/boost/unordered/detail/narrow_cast.hpp new file mode 100644 index 00000000..3e59cdd0 --- /dev/null +++ b/src/boost/unordered/detail/narrow_cast.hpp @@ -0,0 +1,44 @@ +/* Copyright 2022 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP +#define BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP + +#include + +#include +#include + +namespace boost{ +namespace unordered{ +namespace detail{ + +template +constexpr To narrow_cast(From x) noexcept +{ + BOOST_UNORDERED_STATIC_ASSERT(std::is_integral::value); + BOOST_UNORDERED_STATIC_ASSERT(std::is_integral::value); + BOOST_UNORDERED_STATIC_ASSERT(sizeof(From)>=sizeof(To)); + + return static_cast( + x + +#if defined(__MSVC_RUNTIME_CHECKS) + /* Avoids VS's "Run-Time Check Failure #1 - A cast to a smaller data type + * has caused a loss of data." + */ + &static_cast::type>(~static_cast(0)) +#endif + ); +} + +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/opt_storage.hpp b/src/boost/unordered/detail/opt_storage.hpp new file mode 100644 index 00000000..c38b5879 --- /dev/null +++ b/src/boost/unordered/detail/opt_storage.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Christian Mazakas +// +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP +#define BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP + +#include + +#include + +namespace boost { + namespace unordered { + namespace detail { + template union opt_storage + { + BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS T t_; + + opt_storage() {} + ~opt_storage() {} + + T* address() noexcept { return std::addressof(t_); } + T const* address() const noexcept { return std::addressof(t_); } + }; + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP diff --git a/src/boost/unordered/detail/serialization_version.hpp b/src/boost/unordered/detail/serialization_version.hpp new file mode 100644 index 00000000..c63eb034 --- /dev/null +++ b/src/boost/unordered/detail/serialization_version.hpp @@ -0,0 +1,74 @@ +/* Copyright 2023 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_SERIALIZATION_VERSION_HPP +#define BOOST_UNORDERED_DETAIL_SERIALIZATION_VERSION_HPP + +#include +#include + +namespace boost{ +namespace unordered{ +namespace detail{ + +/* boost::serialization::load_construct_adl(ar,t,version) requires user code + * to pass the serialization version for t, when this information is really + * stored in the archive. serialization_version circumvents this design + * error by acting as a regular serializable type with the same serialization + * version as T; loading/saving serialization_version does nothing with + * the archive data itself but captures the stored serialization version + * at load() time. + */ + +template +struct serialization_version +{ + serialization_version(): + value(boost::serialization::version::value){} + + serialization_version& operator=(unsigned int x){value=x;return *this;}; + + operator unsigned int()const{return value;} + +private: + friend class boost::serialization::access; + + template + void serialize(Archive& ar,unsigned int version) + { + core::split_member(ar,*this,version); + } + + template + void save(Archive&,unsigned int)const{} + + template + void load(Archive&,unsigned int version) + { + this->value=version; + } + + unsigned int value; +}; + +} /* namespace detail */ +} /* namespace unordered */ + +namespace serialization{ + +template +struct version > +{ + BOOST_STATIC_CONSTANT(int,value=version::value); +}; + +} /* namespace serialization */ + +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/detail/static_assert.hpp b/src/boost/unordered/detail/static_assert.hpp new file mode 100644 index 00000000..4e877b12 --- /dev/null +++ b/src/boost/unordered/detail/static_assert.hpp @@ -0,0 +1,16 @@ +// Copyright 2023 Christian Mazakas +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP +#define BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#define BOOST_UNORDERED_STATIC_ASSERT(...) \ + static_assert(__VA_ARGS__, #__VA_ARGS__) + +#endif // BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP diff --git a/src/boost/unordered/detail/type_traits.hpp b/src/boost/unordered/detail/type_traits.hpp new file mode 100644 index 00000000..f99f7f42 --- /dev/null +++ b/src/boost/unordered/detail/type_traits.hpp @@ -0,0 +1,237 @@ +// Copyright (C) 2022-2023 Christian Mazakas +// Copyright (C) 2024 Braden Ganetsky +// +// 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) + +#ifndef BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP +#define BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include + +#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES) +#include +#endif + +#include +#include + +// BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES + +#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES) +#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES) +#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 1 +#endif +#endif + +#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES) +#define BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES 0 +#endif + +namespace boost { + namespace unordered { + namespace detail { + + template struct type_identity + { + using type = T; + }; + + template struct make_void + { + typedef void type; + }; + + template using void_t = typename make_void::type; + + template struct is_complete : std::false_type + { + }; + + template + struct is_complete > : std::true_type + { + }; + + template + using is_complete_and_move_constructible = + typename std::conditional::value, + std::is_move_constructible, std::false_type>::type; + +#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) + /* std::is_trivially_default_constructible not provided */ + template + struct is_trivially_default_constructible + : public std::integral_constant::value && + std::has_trivial_default_constructor::value> + { + }; +#else + using std::is_trivially_default_constructible; +#endif + +#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) + /* std::is_trivially_copy_constructible not provided */ + template + struct is_trivially_copy_constructible + : public std::integral_constant::value && + std::has_trivial_copy_constructor::value> + { + }; +#else + using std::is_trivially_copy_constructible; +#endif + +#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) + /* std::is_trivially_copy_assignable not provided */ + template + struct is_trivially_copy_assignable + : public std::integral_constant::value && + std::has_trivial_copy_assign::value> + { + }; +#else + using std::is_trivially_copy_assignable; +#endif + + namespace type_traits_detail { + using std::swap; + + template struct is_nothrow_swappable_helper + { + constexpr static bool const value = false; + }; + + template + struct is_nothrow_swappable_helper(), std::declval()))> > + { + constexpr static bool const value = + noexcept(swap(std::declval(), std::declval())); + }; + + } // namespace type_traits_detail + + template + struct is_nothrow_swappable + : public std::integral_constant::value> + { + }; + + //////////////////////////////////////////////////////////////////////////// + // Type checkers used for the transparent member functions added by C++20 + // and up + + template + struct is_transparent : public std::false_type + { + }; + + template + struct is_transparent > + : public std::true_type + { + }; + + template struct are_transparent + { + static bool const value = + is_transparent::value && is_transparent::value; + }; + + template struct transparent_non_iterable + { + typedef typename UnorderedMap::hasher hash; + typedef typename UnorderedMap::key_equal key_equal; + typedef typename UnorderedMap::iterator iterator; + typedef typename UnorderedMap::const_iterator const_iterator; + + static bool const value = + are_transparent::value && + !std::is_convertible::value && + !std::is_convertible::value; + }; + + template + using remove_cvref_t = + typename std::remove_cv::type>::type; + + template + using is_similar = std::is_same, remove_cvref_t >; + + template struct is_similar_to_any : std::false_type + { + }; + template + struct is_similar_to_any + : std::conditional::value, is_similar, + is_similar_to_any >::type + { + }; + +#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES + // https://eel.is/c++draft/container.requirements#container.alloc.reqmts-34 + // https://eel.is/c++draft/container.requirements#unord.req.general-243 + + template + constexpr bool const is_input_iterator_v = + !std::is_integral::value; + + template struct is_allocator + { + constexpr static bool const value = false; + }; + + template + struct is_allocator().allocate(std::size_t{}))> > + { + constexpr static bool const value = true; + }; + + template + constexpr bool const is_allocator_v = is_allocator::value; + + template + constexpr bool const is_hash_v = + !std::is_integral::value && !is_allocator_v; + + template constexpr bool const is_pred_v = !is_allocator_v

; + + template + using iter_key_t = + typename std::iterator_traits::value_type::first_type; + template + using iter_val_t = + typename std::iterator_traits::value_type::second_type; + template + using iter_to_alloc_t = + typename std::pair const, iter_val_t >; +#endif + +#if BOOST_CXX_VERSION < 201703L + template + constexpr typename std::add_const::type& as_const(T& t) noexcept + { + return t; + } + template void as_const(const T&&) = delete; +#else + using std::as_const; +#endif + } // namespace detail + } // namespace unordered +} // namespace boost + +#endif // BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP diff --git a/src/boost/unordered/hash_traits.hpp b/src/boost/unordered/hash_traits.hpp new file mode 100644 index 00000000..5e2b1af0 --- /dev/null +++ b/src/boost/unordered/hash_traits.hpp @@ -0,0 +1,70 @@ +/* Hash function characterization. + * + * Copyright 2022-2024 Joaquin M Lopez Munoz. + * 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) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_HASH_TRAITS_HPP +#define BOOST_UNORDERED_HASH_TRAITS_HPP + +#include + +namespace boost{ +namespace unordered{ + +namespace detail{ + +template +struct hash_is_avalanching_impl:std::false_type{}; + +template +struct avalanching_value +{ + static constexpr bool value=IsAvalanching::value; +}; + +/* may be explicitly marked as BOOST_DEPRECATED in the future */ +template<> struct avalanching_value +{ + static constexpr bool value=true; +}; + +template +struct hash_is_avalanching_impl< + Hash, + boost::unordered::detail::void_t +>:std::integral_constant< + bool, + avalanching_value::value +>{}; + +template +struct hash_is_avalanching_impl< + Hash, + typename std::enable_if<((void)Hash::is_avalanching,true)>::type +>{}; /* Hash::is_avalanching is not a type: compile error downstream */ + +} /* namespace detail */ + +/* Each trait can be partially specialized by users for concrete hash functions + * when actual characterization differs from default. + */ + +/* hash_is_avalanching::value is: + * - false if Hash::is_avalanching is not present. + * - Hash::is_avalanching::value if this is present and constexpr-convertible + * to a bool. + * - true if Hash::is_avalanching is void (deprecated). + * - ill-formed otherwise. + */ +template +struct hash_is_avalanching: detail::hash_is_avalanching_impl::type{}; + +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/src/boost/unordered/unordered_flat_map_fwd.hpp b/src/boost/unordered/unordered_flat_map_fwd.hpp new file mode 100644 index 00000000..f758f83a --- /dev/null +++ b/src/boost/unordered/unordered_flat_map_fwd.hpp @@ -0,0 +1,59 @@ + +// Copyright (C) 2022 Christian Mazakas +// Copyright (C) 2024 Braden Ganetsky +// 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) + +#ifndef BOOST_UNORDERED_FLAT_MAP_FWD_HPP_INCLUDED +#define BOOST_UNORDERED_FLAT_MAP_FWD_HPP_INCLUDED + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include +#include +#include + +#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE +#include +#endif + +namespace boost { + namespace unordered { + template , + class KeyEqual = std::equal_to, + class Allocator = std::allocator > > + class unordered_flat_map; + + template + bool operator==( + unordered_flat_map const& lhs, + unordered_flat_map const& rhs); + + template + bool operator!=( + unordered_flat_map const& lhs, + unordered_flat_map const& rhs); + + template + void swap(unordered_flat_map& lhs, + unordered_flat_map& rhs) + noexcept(noexcept(lhs.swap(rhs))); + +#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE + namespace pmr { + template , + class KeyEqual = std::equal_to > + using unordered_flat_map = + boost::unordered::unordered_flat_map > >; + } // namespace pmr +#endif + } // namespace unordered + + using boost::unordered::unordered_flat_map; +} // namespace boost + +#endif diff --git a/src/boost/unordered/unordered_printers.hpp b/src/boost/unordered/unordered_printers.hpp new file mode 100644 index 00000000..a7d0d137 --- /dev/null +++ b/src/boost/unordered/unordered_printers.hpp @@ -0,0 +1,414 @@ +// Copyright 2024 Braden Ganetsky +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +// Generated on 2024-08-25T17:48:54 + +#ifndef BOOST_UNORDERED_UNORDERED_PRINTERS_HPP +#define BOOST_UNORDERED_UNORDERED_PRINTERS_HPP + +#ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS +#if defined(__ELF__) +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverlength-strings" +#endif +__asm__(".pushsection \".debug_gdb_scripts\", \"MS\",%progbits,1\n" + ".ascii \"\\4gdb.inlined-script.BOOST_UNORDERED_UNORDERED_PRINTERS_HPP\\n\"\n" + ".ascii \"import gdb.printing\\n\"\n" + ".ascii \"import gdb.xmethod\\n\"\n" + ".ascii \"import re\\n\"\n" + ".ascii \"import math\\n\"\n" + + ".ascii \"class BoostUnorderedHelpers:\\n\"\n" + ".ascii \" def maybe_unwrap_atomic(n):\\n\"\n" + ".ascii \" if f\\\"{n.type.strip_typedefs()}\\\".startswith(\\\"std::atomic<\\\"):\\n\"\n" + ".ascii \" underlying_type = n.type.template_argument(0)\\n\"\n" + ".ascii \" return n.cast(underlying_type)\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" return n\\n\"\n" + + ".ascii \" def maybe_unwrap_foa_element(e):\\n\"\n" + ".ascii \" if f\\\"{e.type.strip_typedefs()}\\\".startswith(\\\"boost::unordered::detail::foa::element_type<\\\"):\\n\"\n" + ".ascii \" return e[\\\"p\\\"]\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" return e\\n\"\n" + + ".ascii \" def maybe_unwrap_reference(value):\\n\"\n" + ".ascii \" if value.type.code == gdb.TYPE_CODE_REF:\\n\"\n" + ".ascii \" return value.referenced_value()\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" return value\\n\"\n" + + ".ascii \" def countr_zero(n):\\n\"\n" + ".ascii \" for i in range(32):\\n\"\n" + ".ascii \" if (n & (1 << i)) != 0:\\n\"\n" + ".ascii \" return i\\n\"\n" + ".ascii \" return 32\\n\"\n" + + ".ascii \"class BoostUnorderedPointerCustomizationPoint:\\n\"\n" + ".ascii \" def __init__(self, any_ptr):\\n\"\n" + ".ascii \" vis = gdb.default_visualizer(any_ptr)\\n\"\n" + ".ascii \" if vis is None:\\n\"\n" + ".ascii \" self.to_address = lambda ptr: ptr\\n\"\n" + ".ascii \" self.next = lambda ptr, offset: ptr + offset\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" self.to_address = lambda ptr: ptr if (ptr.type.code == gdb.TYPE_CODE_PTR) else type(vis).boost_to_address(ptr)\\n\"\n" + ".ascii \" self.next = lambda ptr, offset: type(vis).boost_next(ptr, offset)\\n\"\n" + + ".ascii \"class BoostUnorderedFcaPrinter:\\n\"\n" + ".ascii \" def __init__(self, val):\\n\"\n" + ".ascii \" self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n" + ".ascii \" self.name = f\\\"{self.val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n" + ".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n" + ".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n" + ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"table_\\\"][\\\"buckets_\\\"][\\\"buckets\\\"])\\n\"\n" + + ".ascii \" def to_string(self):\\n\"\n" + ".ascii \" size = self.val[\\\"table_\\\"][\\\"size_\\\"]\\n\"\n" + ".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n" + + ".ascii \" def display_hint(self):\\n\"\n" + ".ascii \" return \\\"map\\\"\\n\"\n" + + ".ascii \" def children(self):\\n\"\n" + ".ascii \" def generator():\\n\"\n" + ".ascii \" grouped_buckets = self.val[\\\"table_\\\"][\\\"buckets_\\\"]\\n\"\n" + + ".ascii \" size = grouped_buckets[\\\"size_\\\"]\\n\"\n" + ".ascii \" buckets = grouped_buckets[\\\"buckets\\\"]\\n\"\n" + ".ascii \" bucket_index = 0\\n\"\n" + + ".ascii \" count = 0\\n\"\n" + ".ascii \" while bucket_index != size:\\n\"\n" + ".ascii \" current_bucket = self.cpo.next(self.cpo.to_address(buckets), bucket_index)\\n\"\n" + ".ascii \" node = self.cpo.to_address(current_bucket.dereference()[\\\"next\\\"])\\n\"\n" + ".ascii \" while node != 0:\\n\"\n" + ".ascii \" value = node.dereference()[\\\"buf\\\"][\\\"t_\\\"]\\n\"\n" + ".ascii \" if self.is_map:\\n\"\n" + ".ascii \" first = value[\\\"first\\\"]\\n\"\n" + ".ascii \" second = value[\\\"second\\\"]\\n\"\n" + ".ascii \" yield \\\"\\\", first\\n\"\n" + ".ascii \" yield \\\"\\\", second\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" yield \\\"\\\", count\\n\"\n" + ".ascii \" yield \\\"\\\", value\\n\"\n" + ".ascii \" count += 1\\n\"\n" + ".ascii \" node = self.cpo.to_address(node.dereference()[\\\"next\\\"])\\n\"\n" + ".ascii \" bucket_index += 1\\n\"\n" + + ".ascii \" return generator()\\n\"\n" + + ".ascii \"class BoostUnorderedFcaIteratorPrinter:\\n\"\n" + ".ascii \" def __init__(self, val):\\n\"\n" + ".ascii \" self.val = val\\n\"\n" + ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"p\\\"])\\n\"\n" + + ".ascii \" def to_string(self):\\n\"\n" + ".ascii \" if self.valid():\\n\"\n" + ".ascii \" value = self.cpo.to_address(self.val[\\\"p\\\"]).dereference()[\\\"buf\\\"][\\\"t_\\\"]\\n\"\n" + ".ascii \" return f\\\"iterator = {{ {value} }}\\\"\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" return \\\"iterator = { end iterator }\\\"\\n\"\n" + + ".ascii \" def valid(self):\\n\"\n" + ".ascii \" return (self.cpo.to_address(self.val[\\\"p\\\"]) != 0) and (self.cpo.to_address(self.val[\\\"itb\\\"][\\\"p\\\"]) != 0)\\n\"\n" + + ".ascii \"class BoostUnorderedFoaTableCoreCumulativeStatsPrinter:\\n\"\n" + ".ascii \" def __init__(self, val):\\n\"\n" + ".ascii \" self.val = val\\n\"\n" + + ".ascii \" def to_string(self):\\n\"\n" + ".ascii \" return \\\"[stats]\\\"\\n\"\n" + + ".ascii \" def display_hint(self):\\n\"\n" + ".ascii \" return \\\"map\\\"\\n\"\n" + + ".ascii \" def children(self):\\n\"\n" + ".ascii \" def generator():\\n\"\n" + ".ascii \" members = [\\\"insertion\\\", \\\"successful_lookup\\\", \\\"unsuccessful_lookup\\\"]\\n\"\n" + ".ascii \" for member in members:\\n\"\n" + ".ascii \" yield \\\"\\\", member\\n\"\n" + ".ascii \" yield \\\"\\\", self.val[member]\\n\"\n" + ".ascii \" return generator()\\n\"\n" + + ".ascii \"class BoostUnorderedFoaCumulativeStatsPrinter:\\n\"\n" + ".ascii \" def __init__(self, val):\\n\"\n" + ".ascii \" self.val = val\\n\"\n" + ".ascii \" self.n = self.val[\\\"n\\\"]\\n\"\n" + ".ascii \" self.N = self.val.type.template_argument(0)\\n\"\n" + + ".ascii \" def display_hint(self):\\n\"\n" + ".ascii \" return \\\"map\\\"\\n\"\n" + + ".ascii \" def children(self):\\n\"\n" + ".ascii \" def generator():\\n\"\n" + ".ascii \" yield \\\"\\\", \\\"count\\\"\\n\"\n" + ".ascii \" yield \\\"\\\", self.n\\n\"\n" + + ".ascii \" sequence_stats_data = gdb.lookup_type(\\\"boost::unordered::detail::foa::sequence_stats_data\\\")\\n\"\n" + ".ascii \" data = self.val[\\\"data\\\"]\\n\"\n" + ".ascii \" arr = data.address.reinterpret_cast(sequence_stats_data.pointer())\\n\"\n" + ".ascii \" def build_string(idx):\\n\"\n" + ".ascii \" entry = arr[idx]\\n\"\n" + ".ascii \" avg = float(entry[\\\"m\\\"])\\n\"\n" + ".ascii \" var = float(entry[\\\"s\\\"] / self.n) if (self.n != 0) else 0.0\\n\"\n" + ".ascii \" dev = math.sqrt(var)\\n\"\n" + ".ascii \" return f\\\"{{avg = {avg}, var = {var}, dev = {dev}}}\\\"\\n\"\n" + + ".ascii \" if self.N > 0:\\n\"\n" + ".ascii \" yield \\\"\\\", \\\"probe_length\\\"\\n\"\n" + ".ascii \" yield \\\"\\\", build_string(0)\\n\"\n" + ".ascii \" if self.N > 1:\\n\"\n" + ".ascii \" yield \\\"\\\", \\\"num_comparisons\\\"\\n\"\n" + ".ascii \" yield \\\"\\\", build_string(1)\\n\"\n" + + ".ascii \" return generator()\\n\"\n" + + ".ascii \"class BoostUnorderedFoaPrinter:\\n\"\n" + ".ascii \" def __init__(self, val):\\n\"\n" + ".ascii \" self.val = BoostUnorderedHelpers.maybe_unwrap_reference(val)\\n\"\n" + ".ascii \" self.name = f\\\"{self.val.type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n" + ".ascii \" self.name = self.name.replace(\\\"boost::unordered::\\\", \\\"boost::\\\")\\n\"\n" + ".ascii \" self.is_map = self.name.endswith(\\\"map\\\")\\n\"\n" + ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"table_\\\"][\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n" + + ".ascii \" def to_string(self):\\n\"\n" + ".ascii \" size = BoostUnorderedHelpers.maybe_unwrap_atomic(self.val[\\\"table_\\\"][\\\"size_ctrl\\\"][\\\"size\\\"])\\n\"\n" + ".ascii \" return f\\\"{self.name} with {size} elements\\\"\\n\"\n" + + ".ascii \" def display_hint(self):\\n\"\n" + ".ascii \" return \\\"map\\\"\\n\"\n" + + ".ascii \" def is_regular_layout(self, group):\\n\"\n" + ".ascii \" typename = group[\\\"m\\\"].type.strip_typedefs()\\n\"\n" + ".ascii \" array_size = typename.sizeof // typename.target().sizeof\\n\"\n" + ".ascii \" if array_size == 16:\\n\"\n" + ".ascii \" return True\\n\"\n" + ".ascii \" elif array_size == 2:\\n\"\n" + ".ascii \" return False\\n\"\n" + + ".ascii \" def match_occupied(self, group):\\n\"\n" + ".ascii \" m = group[\\\"m\\\"]\\n\"\n" + ".ascii \" at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b][\\\"n\\\"])\\n\"\n" + + ".ascii \" if self.is_regular_layout(group):\\n\"\n" + ".ascii \" bits = [1 << b for b in range(16) if at(b) == 0]\\n\"\n" + ".ascii \" return 0x7FFF & ~sum(bits)\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" xx = at(0) | at(1)\\n\"\n" + ".ascii \" yy = xx | (xx >> 32)\\n\"\n" + ".ascii \" return 0x7FFF & (yy | (yy >> 16))\\n\"\n" + + ".ascii \" def is_sentinel(self, group, pos):\\n\"\n" + ".ascii \" m = group[\\\"m\\\"]\\n\"\n" + ".ascii \" at = lambda b: BoostUnorderedHelpers.maybe_unwrap_atomic(m[b][\\\"n\\\"])\\n\"\n" + + ".ascii \" N = group[\\\"N\\\"]\\n\"\n" + ".ascii \" sentinel_ = group[\\\"sentinel_\\\"]\\n\"\n" + ".ascii \" if self.is_regular_layout(group):\\n\"\n" + ".ascii \" return pos == N-1 and at(N-1) == sentinel_\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" return pos == N-1 and (at(0) & 0x4000400040004000) == 0x4000 and (at(1) & 0x4000400040004000) == 0\\n\"\n" + + ".ascii \" def children(self):\\n\"\n" + ".ascii \" def generator():\\n\"\n" + ".ascii \" table = self.val[\\\"table_\\\"]\\n\"\n" + ".ascii \" groups = self.cpo.to_address(table[\\\"arrays\\\"][\\\"groups_\\\"])\\n\"\n" + ".ascii \" elements = self.cpo.to_address(table[\\\"arrays\\\"][\\\"elements_\\\"])\\n\"\n" + + ".ascii \" pc_ = groups.cast(gdb.lookup_type(\\\"unsigned char\\\").pointer())\\n\"\n" + ".ascii \" p_ = elements\\n\"\n" + ".ascii \" first_time = True\\n\"\n" + ".ascii \" mask = 0\\n\"\n" + ".ascii \" n0 = 0\\n\"\n" + ".ascii \" n = 0\\n\"\n" + + ".ascii \" count = 0\\n\"\n" + ".ascii \" while p_ != 0:\\n\"\n" + ".ascii \" # This if block mirrors the condition in the begin() call\\n\"\n" + ".ascii \" if (not first_time) or (self.match_occupied(groups.dereference()) & 1):\\n\"\n" + ".ascii \" pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(p_)\\n\"\n" + ".ascii \" value = self.cpo.to_address(pointer).dereference()\\n\"\n" + ".ascii \" if self.is_map:\\n\"\n" + ".ascii \" first = value[\\\"first\\\"]\\n\"\n" + ".ascii \" second = value[\\\"second\\\"]\\n\"\n" + ".ascii \" yield \\\"\\\", first\\n\"\n" + ".ascii \" yield \\\"\\\", second\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" yield \\\"\\\", count\\n\"\n" + ".ascii \" yield \\\"\\\", value\\n\"\n" + ".ascii \" count += 1\\n\"\n" + ".ascii \" first_time = False\\n\"\n" + + ".ascii \" n0 = pc_.cast(gdb.lookup_type(\\\"uintptr_t\\\")) % groups.dereference().type.sizeof\\n\"\n" + ".ascii \" pc_ = self.cpo.next(pc_, -n0)\\n\"\n" + + ".ascii \" mask = (self.match_occupied(pc_.cast(groups.type).dereference()) >> (n0+1)) << (n0+1)\\n\"\n" + ".ascii \" while mask == 0:\\n\"\n" + ".ascii \" pc_ = self.cpo.next(pc_, groups.dereference().type.sizeof)\\n\"\n" + ".ascii \" p_ = self.cpo.next(p_, groups.dereference()[\\\"N\\\"])\\n\"\n" + ".ascii \" mask = self.match_occupied(pc_.cast(groups.type).dereference())\\n\"\n" + + ".ascii \" n = BoostUnorderedHelpers.countr_zero(mask)\\n\"\n" + ".ascii \" if self.is_sentinel(pc_.cast(groups.type).dereference(), n):\\n\"\n" + ".ascii \" p_ = 0\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" pc_ = self.cpo.next(pc_, n)\\n\"\n" + ".ascii \" p_ = self.cpo.next(p_, n - n0)\\n\"\n" + + ".ascii \" return generator()\\n\"\n" + + ".ascii \"class BoostUnorderedFoaIteratorPrinter:\\n\"\n" + ".ascii \" def __init__(self, val):\\n\"\n" + ".ascii \" self.val = val\\n\"\n" + ".ascii \" self.cpo = BoostUnorderedPointerCustomizationPoint(self.val[\\\"p_\\\"])\\n\"\n" + + ".ascii \" def to_string(self):\\n\"\n" + ".ascii \" if self.valid():\\n\"\n" + ".ascii \" element = self.cpo.to_address(self.val[\\\"p_\\\"])\\n\"\n" + ".ascii \" pointer = BoostUnorderedHelpers.maybe_unwrap_foa_element(element)\\n\"\n" + ".ascii \" value = self.cpo.to_address(pointer).dereference()\\n\"\n" + ".ascii \" return f\\\"iterator = {{ {value} }}\\\"\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" return \\\"iterator = { end iterator }\\\"\\n\"\n" + + ".ascii \" def valid(self):\\n\"\n" + ".ascii \" return (self.cpo.to_address(self.val[\\\"p_\\\"]) != 0) and (self.cpo.to_address(self.val[\\\"pc_\\\"]) != 0)\\n\"\n" + + ".ascii \"def boost_unordered_build_pretty_printer():\\n\"\n" + ".ascii \" pp = gdb.printing.RegexpCollectionPrettyPrinter(\\\"boost_unordered\\\")\\n\"\n" + ".ascii \" add_template_printer = lambda name, printer: pp.add_printer(name, f\\\"^{name}<.*>$\\\", printer)\\n\"\n" + ".ascii \" add_concrete_printer = lambda name, printer: pp.add_printer(name, f\\\"^{name}$\\\", printer)\\n\"\n" + + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_map\\\", BoostUnorderedFcaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_multimap\\\", BoostUnorderedFcaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_set\\\", BoostUnorderedFcaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_multiset\\\", BoostUnorderedFcaPrinter)\\n\"\n" + + ".ascii \" add_template_printer(\\\"boost::unordered::detail::iterator_detail::iterator\\\", BoostUnorderedFcaIteratorPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::detail::iterator_detail::c_iterator\\\", BoostUnorderedFcaIteratorPrinter)\\n\"\n" + + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_flat_map\\\", BoostUnorderedFoaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_flat_set\\\", BoostUnorderedFoaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_node_map\\\", BoostUnorderedFoaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::unordered_node_set\\\", BoostUnorderedFoaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_flat_map\\\", BoostUnorderedFoaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_flat_set\\\", BoostUnorderedFoaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_node_map\\\", BoostUnorderedFoaPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::concurrent_node_set\\\", BoostUnorderedFoaPrinter)\\n\"\n" + + ".ascii \" add_template_printer(\\\"boost::unordered::detail::foa::table_iterator\\\", BoostUnorderedFoaIteratorPrinter)\\n\"\n" + + ".ascii \" add_concrete_printer(\\\"boost::unordered::detail::foa::table_core_cumulative_stats\\\", BoostUnorderedFoaTableCoreCumulativeStatsPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::detail::foa::cumulative_stats\\\", BoostUnorderedFoaCumulativeStatsPrinter)\\n\"\n" + ".ascii \" add_template_printer(\\\"boost::unordered::detail::foa::concurrent_cumulative_stats\\\", BoostUnorderedFoaCumulativeStatsPrinter)\\n\"\n" + + ".ascii \" return pp\\n\"\n" + + ".ascii \"gdb.printing.register_pretty_printer(gdb.current_objfile(), boost_unordered_build_pretty_printer())\\n\"\n" + + + + ".ascii \"# https://sourceware.org/gdb/current/onlinedocs/gdb.html/Writing-an-Xmethod.html\\n\"\n" + ".ascii \"class BoostUnorderedFoaGetStatsMethod(gdb.xmethod.XMethod):\\n\"\n" + ".ascii \" def __init__(self):\\n\"\n" + ".ascii \" gdb.xmethod.XMethod.__init__(self, \\\"get_stats\\\")\\n\"\n" + + ".ascii \" def get_worker(self, method_name):\\n\"\n" + ".ascii \" if method_name == \\\"get_stats\\\":\\n\"\n" + ".ascii \" return BoostUnorderedFoaGetStatsWorker()\\n\"\n" + + ".ascii \"class BoostUnorderedFoaGetStatsWorker(gdb.xmethod.XMethodWorker):\\n\"\n" + ".ascii \" def get_arg_types(self):\\n\"\n" + ".ascii \" return None\\n\"\n" + + ".ascii \" def get_result_type(self, obj):\\n\"\n" + ".ascii \" return gdb.lookup_type(\\\"boost::unordered::detail::foa::table_core_cumulative_stats\\\")\\n\"\n" + + ".ascii \" def __call__(self, obj):\\n\"\n" + ".ascii \" try:\\n\"\n" + ".ascii \" return obj[\\\"table_\\\"][\\\"cstats\\\"]\\n\"\n" + ".ascii \" except gdb.error:\\n\"\n" + ".ascii \" print(\\\"Error: Binary was compiled without stats. Recompile with `BOOST_UNORDERED_ENABLE_STATS` defined.\\\")\\n\"\n" + ".ascii \" return\\n\"\n" + + ".ascii \"class BoostUnorderedFoaMatcher(gdb.xmethod.XMethodMatcher):\\n\"\n" + ".ascii \" def __init__(self):\\n\"\n" + ".ascii \" gdb.xmethod.XMethodMatcher.__init__(self, 'BoostUnorderedFoaMatcher')\\n\"\n" + ".ascii \" self.methods = [BoostUnorderedFoaGetStatsMethod()]\\n\"\n" + + ".ascii \" def match(self, class_type, method_name):\\n\"\n" + ".ascii \" template_name = f\\\"{class_type.strip_typedefs()}\\\".split(\\\"<\\\")[0]\\n\"\n" + ".ascii \" regex = \\\"^boost::unordered::(unordered|concurrent)_(flat|node)_(map|set)$\\\"\\n\"\n" + ".ascii \" if not re.match(regex, template_name):\\n\"\n" + ".ascii \" return None\\n\"\n" + + ".ascii \" workers = []\\n\"\n" + ".ascii \" for method in self.methods:\\n\"\n" + ".ascii \" if method.enabled:\\n\"\n" + ".ascii \" worker = method.get_worker(method_name)\\n\"\n" + ".ascii \" if worker:\\n\"\n" + ".ascii \" workers.append(worker)\\n\"\n" + ".ascii \" return workers\\n\"\n" + + ".ascii \"gdb.xmethod.register_xmethod_matcher(None, BoostUnorderedFoaMatcher())\\n\"\n" + + + + ".ascii \"\\\"\\\"\\\" Fancy pointer support \\\"\\\"\\\"\\n\"\n" + + ".ascii \"\\\"\\\"\\\"\\n\"\n" + ".ascii \"To allow your own fancy pointer type to interact with Boost.Unordered GDB pretty-printers,\\n\"\n" + ".ascii \"create a pretty-printer for your own type with the following additional methods.\\n\"\n" + + ".ascii \"(Note, this is assuming the presence of a type alias `pointer` for the underlying\\n\"\n" + ".ascii \"raw pointer type, Substitute whichever name is applicable in your case.)\\n\"\n" + + ".ascii \"`boost_to_address(fancy_ptr)`\\n\"\n" + ".ascii \" * A static method, but `@staticmethod` is not required\\n\"\n" + ".ascii \" * Parameter `fancy_ptr` of type `gdb.Value`\\n\"\n" + ".ascii \" * Its `.type` will be your fancy pointer type\\n\"\n" + ".ascii \" * Returns a `gdb.Value` with the raw pointer equivalent to your fancy pointer\\n\"\n" + ".ascii \" * This method should be equivalent to calling `operator->()` on your fancy pointer in C++\\n\"\n" + + ".ascii \"`boost_next(raw_ptr, offset)`\\n\"\n" + ".ascii \" * Parameter `raw_ptr` of type `gdb.Value`\\n\"\n" + ".ascii \" * Its `.type` will be `pointer`\\n\"\n" + ".ascii \" * Parameter `offset`\\n\"\n" + ".ascii \" * Either has integer type, or is of type `gdb.Value` with an underlying integer\\n\"\n" + ".ascii \" * Returns a `gdb.Value` with the raw pointer equivalent to your fancy pointer, as if you did the following operations\\n\"\n" + ".ascii \" 1. Convert the incoming raw pointer to your fancy pointer\\n\"\n" + ".ascii \" 2. Use operator+= to add the offset to the fancy pointer\\n\"\n" + ".ascii \" 3. Convert back to the raw pointer\\n\"\n" + ".ascii \" * Note, you will not actually do these operations as stated. You will do equivalent lower-level operations that emulate having done the above\\n\"\n" + ".ascii \" * Ultimately, it will be as if you called `operator+()` on your fancy pointer in C++, but using only raw pointers\\n\"\n" + + ".ascii \"Example\\n\"\n" + ".ascii \"```\\n\"\n" + ".ascii \"class MyFancyPtrPrinter:\\n\"\n" + ".ascii \" ...\\n\"\n" + + ".ascii \" # Equivalent to `operator->()`\\n\"\n" + ".ascii \" def boost_to_address(fancy_ptr):\\n\"\n" + ".ascii \" ...\\n\"\n" + ".ascii \" return ...\\n\"\n" + + ".ascii \" # Equivalent to `operator+()`\\n\"\n" + ".ascii \" def boost_next(raw_ptr, offset):\\n\"\n" + ".ascii \" ...\\n\"\n" + ".ascii \" return ...\\n\"\n" + + ".ascii \" ...\\n\"\n" + ".ascii \"```\\n\"\n" + ".ascii \"\\\"\\\"\\\"\\n\"\n" + + ".byte 0\n" + ".popsection\n"); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#endif // defined(__ELF__) +#endif // !defined(BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS) + +#endif // !defined(BOOST_UNORDERED_UNORDERED_PRINTERS_HPP) diff --git a/src/boost/version.hpp b/src/boost/version.hpp new file mode 100644 index 00000000..606b4268 --- /dev/null +++ b/src/boost/version.hpp @@ -0,0 +1,32 @@ +// Boost version.hpp configuration header file ------------------------------// + +// (C) Copyright John maddock 1999. 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) + +// See http://www.boost.org/libs/config for documentation + +#ifndef BOOST_VERSION_HPP +#define BOOST_VERSION_HPP + +// +// Caution: this is the only Boost header that is guaranteed +// to change with every Boost release. Including this header +// will cause a recompile every time a new Boost version is +// used. +// +// BOOST_VERSION % 100 is the patch level +// BOOST_VERSION / 100 % 1000 is the minor version +// BOOST_VERSION / 100000 is the major version + +#define BOOST_VERSION 108800 + +// +// BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION +// but as a *string* in the form "x_y[_z]" where x is the major version +// number, y is the minor version number, and z is the patch level if not 0. +// This is used by to select which library version to link to. + +#define BOOST_LIB_VERSION "1_88" + +#endif diff --git a/src/config.cpp b/src/config.cpp index 70593750..253e9ef7 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -184,6 +184,8 @@ Config::Config() _map["func.unlink"] = &func.unlink; _map["func.utimens"] = &func.utimens; _map["fuse_msg_size"] = &fuse_msg_size; + _map["handle-killpriv"] = &handle_killpriv; + _map["handle-killpriv-v2"] = &handle_killpriv_v2; _map["ignorepponrename"] = &ignorepponrename; _map["inodecalc"] = &inodecalc; _map["kernel_cache"] = &kernel_cache; @@ -197,6 +199,7 @@ Config::Config() _map["moveonenospc"] = &moveonenospc; _map["nfsopenhack"] = &nfsopenhack; _map["nullrw"] = &nullrw; + _map["passthrough"] = &passthrough; _map["pid"] = &pid; _map["parallel-direct-writes"] = ¶llel_direct_writes; _map["pin-threads"] = &fuse_pin_threads; diff --git a/src/config.hpp b/src/config.hpp index ca20e347..a5d0b2fc 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -41,11 +41,10 @@ #include "rwlock.hpp" #include "tofrom_wrapper.hpp" -#include "ghc/filesystem.hpp" - #include "fuse.h" #include +#include #include #include #include @@ -53,12 +52,12 @@ #include -typedef ToFromWrapper ConfigBOOL; -typedef ToFromWrapper ConfigUINT64; -typedef ToFromWrapper ConfigINT; -typedef ToFromWrapper ConfigSTR; -typedef ToFromWrapper ConfigPath; -typedef std::map Str2TFStrMap; +typedef ToFromWrapper ConfigBOOL; +typedef ToFromWrapper ConfigUINT64; +typedef ToFromWrapper ConfigINT; +typedef ToFromWrapper ConfigSTR; +typedef ToFromWrapper ConfigPath; +typedef std::map Str2TFStrMap; extern const std::string CONTROLFILE; @@ -130,6 +129,8 @@ public: ConfigSTR fsname; Funcs func; ConfigPageSize fuse_msg_size; + ConfigBOOL handle_killpriv = true; + ConfigBOOL handle_killpriv_v2 = true; ConfigBOOL ignorepponrename; InodeCalc inodecalc; ConfigBOOL kernel_cache; @@ -142,6 +143,7 @@ public: MoveOnENOSPC moveonenospc; NFSOpenHack nfsopenhack; ConfigBOOL nullrw; + ConfigBOOL passthrough = false; ConfigBOOL parallel_direct_writes; ConfigGetPid pid; ConfigBOOL posix_acl; diff --git a/src/fileinfo.hpp b/src/fileinfo.hpp index d77fd953..3a54ba85 100644 --- a/src/fileinfo.hpp +++ b/src/fileinfo.hpp @@ -50,6 +50,13 @@ public: { } + FileInfo(const FileInfo *fi_) + : FH(fi_->fusepath), + fd(fi_->fd), + branch(fi_->branch), + direct_io(fi_->direct_io) + { + } public: int fd; diff --git a/src/fs_clonefile.cpp b/src/fs_clonefile.cpp index 69d94c04..19f878e8 100644 --- a/src/fs_clonefile.cpp +++ b/src/fs_clonefile.cpp @@ -53,7 +53,7 @@ namespace fs struct stat src_st; rv = fs::fstat(src_fd_,&src_st); - if(rv == -1) + if(rv < 0) return -1; rv = fs::copydata(src_fd_,dst_fd_,src_st.st_size); diff --git a/src/fs_copydata_copy_file_range.cpp b/src/fs_copydata_copy_file_range.cpp index 5722750b..3c4e1375 100644 --- a/src/fs_copydata_copy_file_range.cpp +++ b/src/fs_copydata_copy_file_range.cpp @@ -62,7 +62,7 @@ namespace fs struct stat st; rv = fs::fstat(src_fd_,&st); - if(rv == -1) + if(rv < 0) return -1; return l::copydata_copy_file_range(src_fd_, diff --git a/src/fs_copydata_readwrite.cpp b/src/fs_copydata_readwrite.cpp index abf0c449..753e927c 100644 --- a/src/fs_copydata_readwrite.cpp +++ b/src/fs_copydata_readwrite.cpp @@ -100,7 +100,7 @@ namespace fs struct stat st; rv = fs::fstat(src_fd_,&st); - if(rv == -1) + if(rv < 0) return -1; return l::copydata_readwrite(src_fd_, diff --git a/src/fs_devid.hpp b/src/fs_devid.hpp index 2ad50954..b2b2efc3 100644 --- a/src/fs_devid.hpp +++ b/src/fs_devid.hpp @@ -33,7 +33,7 @@ namespace fs struct stat st; rv = fs::fstat(fd_,&st); - if(rv == -1) + if(rv < 0) return -1; return st.st_dev; diff --git a/src/fs_fchmod.hpp b/src/fs_fchmod.hpp index 5d8c8195..91ef0b89 100644 --- a/src/fs_fchmod.hpp +++ b/src/fs_fchmod.hpp @@ -61,7 +61,7 @@ namespace fs error = errno; rv = fs::fstat(fd_,&tmpst); - if(rv == -1) + if(rv < 0) return -1; if((st_.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS)) diff --git a/src/fs_fchown.hpp b/src/fs_fchown.hpp index f8d92561..0f45d0f8 100644 --- a/src/fs_fchown.hpp +++ b/src/fs_fchown.hpp @@ -63,7 +63,7 @@ namespace fs error = errno; rv = fs::fstat(fd_,&tmpst); - if(rv == -1) + if(rv < 0) return -1; if((st_.st_uid != tmpst.st_uid) || diff --git a/src/fs_file_size.cpp b/src/fs_file_size.cpp index 5528dbe1..ca94e14d 100644 --- a/src/fs_file_size.cpp +++ b/src/fs_file_size.cpp @@ -30,7 +30,7 @@ namespace fs struct stat st; rv = fs::fstat(fd_,&st); - if(rv == -1) + if(rv < 0) return -1; return st.st_size; diff --git a/src/fs_findonfs.cpp b/src/fs_findonfs.cpp index bfe76fb1..b662348f 100644 --- a/src/fs_findonfs.cpp +++ b/src/fs_findonfs.cpp @@ -40,7 +40,7 @@ namespace l std::string fullpath; rv = fs::fstat(fd_,&st); - if(rv == -1) + if(rv < 0) return -1; dev = st.st_dev; diff --git a/src/fs_fstat.hpp b/src/fs_fstat.hpp index 702b1030..4733c56b 100644 --- a/src/fs_fstat.hpp +++ b/src/fs_fstat.hpp @@ -19,6 +19,7 @@ #pragma once +#include #include #include #include @@ -32,6 +33,10 @@ namespace fs fstat(const int fd_, struct stat *st_) { - return ::fstat(fd_,st_); + int rv; + + rv = ::fstat(fd_,st_); + + return ((rv == -1) ? -errno : rv); } } diff --git a/src/fs_fstatat.hpp b/src/fs_fstatat.hpp index cfada9fb..e7d0ee9c 100644 --- a/src/fs_fstatat.hpp +++ b/src/fs_fstatat.hpp @@ -34,10 +34,14 @@ namespace fs struct stat *statbuf_, const int flags_) { - return ::fstatat(dirfd_, - pathname_, - statbuf_, - flags_); + int rv; + + rv = ::fstatat(dirfd_, + pathname_, + statbuf_, + flags_); + + return ((rv == -1) ? -errno : rv); } static diff --git a/src/fs_futimens_generic.hpp b/src/fs_futimens_generic.hpp index ead03dc8..f8deba71 100644 --- a/src/fs_futimens_generic.hpp +++ b/src/fs_futimens_generic.hpp @@ -133,8 +133,8 @@ namespace l return 0; rv = fs::fstatat(dirfd_,path_,&st,flags_); - if(rv == -1) - return -1; + if(rv < 0) + return rv; atime = fs::stat_atime(st); mtime = fs::stat_mtime(st); diff --git a/src/fs_inode.cpp b/src/fs_inode.cpp index fc1e4bc4..7301fb91 100644 --- a/src/fs_inode.cpp +++ b/src/fs_inode.cpp @@ -19,25 +19,20 @@ #include "fs_inode.hpp" #include "ef.hpp" -#include "errno.hpp" #include "rapidhash.h" #include -#include #include -#include #include -using namespace nonstd; - -typedef uint64_t (*inodefunc_t)(const string_view, - const string_view, +typedef uint64_t (*inodefunc_t)(const std::string_view, + const std::string_view, const mode_t, const ino_t); -static uint64_t hybrid_hash(const string_view, - const string_view, +static uint64_t hybrid_hash(const std::string_view, + const std::string_view, const mode_t, const ino_t); @@ -56,20 +51,20 @@ h64_to_h32(uint64_t h_) static uint64_t -passthrough(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +passthrough(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { return ino_; } static uint64_t -path_hash(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +path_hash(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t seed; @@ -80,10 +75,10 @@ path_hash(const string_view branch_path_, static uint64_t -path_hash32(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +path_hash32(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t h; @@ -97,10 +92,10 @@ path_hash32(const string_view branch_path_, static uint64_t -devino_hash(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +devino_hash(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t seed; @@ -112,10 +107,10 @@ devino_hash(const string_view branch_path_, static uint64_t -devino_hash32(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +devino_hash32(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { uint64_t h; @@ -129,10 +124,10 @@ devino_hash32(const string_view branch_path_, static uint64_t -hybrid_hash(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +hybrid_hash(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { return (S_ISDIR(mode_) ? path_hash(branch_path_,fusepath_,mode_,ino_) : @@ -141,10 +136,10 @@ hybrid_hash(const string_view branch_path_, static uint64_t -hybrid_hash32(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) +hybrid_hash32(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { return (S_ISDIR(mode_) ? path_hash32(branch_path_,fusepath_,mode_,ino_) : @@ -200,18 +195,18 @@ namespace fs } uint64_t - calc(const string_view branch_path_, - const string_view fusepath_, - const mode_t mode_, - const ino_t ino_) + calc(const std::string_view branch_path_, + const std::string_view fusepath_, + const mode_t mode_, + const ino_t ino_) { return g_func(branch_path_,fusepath_,mode_,ino_); } void - calc(const string_view branch_path_, - const string_view fusepath_, - struct stat *st_) + calc(const std::string_view branch_path_, + const std::string_view fusepath_, + struct stat *st_) { st_->st_ino = calc(branch_path_, fusepath_, @@ -220,9 +215,9 @@ namespace fs } void - calc(const string_view branch_path_, - const string_view fusepath_, - struct fuse_statx *st_) + calc(const std::string_view branch_path_, + const std::string_view fusepath_, + struct fuse_statx *st_) { st_->ino = calc(branch_path_, fusepath_, diff --git a/src/fs_inode.hpp b/src/fs_inode.hpp index fab78df7..ba3cefeb 100644 --- a/src/fs_inode.hpp +++ b/src/fs_inode.hpp @@ -20,11 +20,9 @@ #include "fuse_kernel.h" -#include "nonstd/string_view.hpp" -#include "ghc/filesystem.hpp" - #include #include +#include #include @@ -36,16 +34,16 @@ namespace fs int set_algo(const std::string &s); std::string get_algo(void); - uint64_t calc(const nonstd::string_view basepath, - const nonstd::string_view fusepath, - const mode_t mode, - const ino_t ino); - - void calc(const nonstd::string_view basepath, - const nonstd::string_view fusepath, - struct stat *st); - void calc(const nonstd::string_view basepath, - const nonstd::string_view fusepath, - struct fuse_statx *st); + uint64_t calc(const std::string_view basepath, + const std::string_view fusepath, + const mode_t mode, + const ino_t ino); + + void calc(const std::string_view basepath, + const std::string_view fusepath, + struct stat *st); + void calc(const std::string_view basepath, + const std::string_view fusepath, + struct fuse_statx *st); } } diff --git a/src/fs_openat.hpp b/src/fs_openat.hpp index 9448d8ac..ce384a67 100644 --- a/src/fs_openat.hpp +++ b/src/fs_openat.hpp @@ -18,10 +18,13 @@ #pragma once -#include -#include -#include +#include +#include + #include +#include +#include +#include namespace fs { @@ -38,4 +41,28 @@ namespace fs return ((rv == -1) ? -errno : rv); } + + static + inline + int + openat(const int dirfd_, + const std::string &pathname_, + const int flags_) + { + return fs::openat(dirfd_, + pathname_.c_str(), + flags_); + } + + static + inline + int + openat(const int dirfd_, + const std::filesystem::path &pathname_, + const int flags_) + { + return fs::openat(dirfd_, + pathname_.c_str(), + flags_); + } } diff --git a/src/fs_path.hpp b/src/fs_path.hpp index bbe131fb..5f175e44 100644 --- a/src/fs_path.hpp +++ b/src/fs_path.hpp @@ -16,15 +16,15 @@ #pragma once -#include "ghc/filesystem.hpp" #include #include +#include namespace fs { - typedef ghc::filesystem::path Path; + typedef std::filesystem::path Path; namespace path { diff --git a/src/fs_utimensat_generic.hpp b/src/fs_utimensat_generic.hpp index 2bd5bf26..de274485 100644 --- a/src/fs_utimensat_generic.hpp +++ b/src/fs_utimensat_generic.hpp @@ -136,8 +136,8 @@ namespace l return 0; rv = fs::fstatat(dirfd_,path_,&st,flags_); - if(rv == -1) - return -1; + if(rv < 0) + return rv; atime = fs::stat_atime(st); mtime = fs::stat_mtime(st); diff --git a/src/fs_wait_for_mount.cpp b/src/fs_wait_for_mount.cpp index e0209d8e..04069a24 100644 --- a/src/fs_wait_for_mount.cpp +++ b/src/fs_wait_for_mount.cpp @@ -20,8 +20,9 @@ #include "syslog.hpp" #include "fs_exists.hpp" -#include "fs_lstat.hpp" #include "fs_lgetxattr.hpp" +#include "fs_lstat.hpp" +#include "fs_stat.hpp" #include #include @@ -35,19 +36,6 @@ namespace fs constexpr std::chrono::milliseconds SLEEP_DURATION = std::chrono::milliseconds(333); -namespace std -{ - template<> - struct hash - { - std::size_t - operator()(fs::Path const &path_) const noexcept - { - return std::hash{}(path_.string()); - } - }; -} - static bool _branch_is_mounted(const struct stat &src_st_, diff --git a/src/fs_wait_for_mount.hpp b/src/fs_wait_for_mount.hpp index 87718b1e..87194d5a 100644 --- a/src/fs_wait_for_mount.hpp +++ b/src/fs_wait_for_mount.hpp @@ -17,10 +17,7 @@ #pragma once -#include "ghc/filesystem.hpp" - #include "fs_pathvector.hpp" -#include "fs_stat.hpp" #include #include diff --git a/src/fuse_chmod.cpp b/src/fuse_chmod.cpp index b6557398..a177d78a 100644 --- a/src/fuse_chmod.cpp +++ b/src/fuse_chmod.cpp @@ -91,20 +91,29 @@ namespace l } } +static +int +_chmod(const char *fusepath_, + const mode_t mode_) +{ + Config::Read cfg; + const fuse_context *fc = fuse_get_context(); + const ugid::Set ugid(fc->uid,fc->gid); + + return l::chmod(cfg->func.chmod.policy, + cfg->func.getattr.policy, + cfg->branches, + fusepath_, + mode_); +} + + namespace FUSE { int chmod(const char *fusepath_, mode_t mode_) { - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - return l::chmod(cfg->func.chmod.policy, - cfg->func.getattr.policy, - cfg->branches, - fusepath_, - mode_); + return ::_chmod(fusepath_,mode_); } } diff --git a/src/fuse_create.cpp b/src/fuse_create.cpp index 1c7e0840..b799e79b 100644 --- a/src/fuse_create.cpp +++ b/src/fuse_create.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "state.hpp" + #include "config.hpp" #include "errno.hpp" #include "fileinfo.hpp" @@ -21,6 +23,7 @@ #include "fs_clonepath.hpp" #include "fs_open.hpp" #include "fs_path.hpp" +#include "fuse_passthrough.hpp" #include "procfs_get_name.hpp" #include "ugid.hpp" @@ -30,184 +33,308 @@ #include -namespace l +/* + The kernel expects being able to issue read requests when running + with writeback caching enabled so we must change O_WRONLY to + O_RDWR. + + With writeback caching enabled the kernel handles O_APPEND. Could + be an issue if the underlying file changes out of band but that is + true of any caching. +*/ +static +void +_tweak_flags_writeback_cache(int *flags_) { - /* - The kernel expects being able to issue read requests when running - with writeback caching enabled so we must change O_WRONLY to - O_RDWR. - - With writeback caching enabled the kernel handles O_APPEND. Could - be an issue if the underlying file changes out of band but that is - true of any caching. - */ - static - void - tweak_flags_writeback_cache(int *flags_) - { - if((*flags_ & O_ACCMODE) == O_WRONLY) - *flags_ = ((*flags_ & ~O_ACCMODE) | O_RDWR); - if(*flags_ & O_APPEND) - *flags_ &= ~O_APPEND; - } + if((*flags_ & O_ACCMODE) == O_WRONLY) + *flags_ = ((*flags_ & ~O_ACCMODE) | O_RDWR); + if(*flags_ & O_APPEND) + *flags_ &= ~O_APPEND; +} - static - bool - rdonly(const int flags_) - { - return ((flags_ & O_ACCMODE) == O_RDONLY); - } +static +bool +_rdonly(const int flags_) +{ + return ((flags_ & O_ACCMODE) == O_RDONLY); +} - static - bool - calculate_flush(FlushOnClose const flushonclose_, - int const flags_) - { - switch(flushonclose_) - { - case FlushOnCloseEnum::NEVER: - return false; - case FlushOnCloseEnum::OPENED_FOR_WRITE: - return !l::rdonly(flags_); - case FlushOnCloseEnum::ALWAYS: - return true; - } - - return true; - } +static +bool +_calculate_flush(FlushOnClose const flushonclose_, + int const flags_) +{ + switch(flushonclose_) + { + case FlushOnCloseEnum::NEVER: + return false; + case FlushOnCloseEnum::OPENED_FOR_WRITE: + return !::_rdonly(flags_); + case FlushOnCloseEnum::ALWAYS: + return true; + } + + return true; +} - static - void - config_to_ffi_flags(Config::Read &cfg_, - const int tid_, - fuse_file_info_t *ffi_) - { - switch(cfg_->cache_files) - { - case CacheFiles::ENUM::LIBFUSE: - ffi_->direct_io = cfg_->direct_io; - ffi_->keep_cache = cfg_->kernel_cache; - ffi_->auto_cache = cfg_->auto_cache; - break; - case CacheFiles::ENUM::OFF: - ffi_->direct_io = 1; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::PARTIAL: - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::FULL: - ffi_->direct_io = 0; - ffi_->keep_cache = 1; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::AUTO_FULL: - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 1; - break; - case CacheFiles::ENUM::PER_PROCESS: - std::string proc_name; - - proc_name = procfs::get_name(tid_); - if(cfg_->cache_files_process_names.count(proc_name) == 0) - { - ffi_->direct_io = 1; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - } - else - { - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - } - break; - } - - if(cfg_->parallel_direct_writes == true) - ffi_->parallel_direct_writes = ffi_->direct_io; - } +static +void +_config_to_ffi_flags(Config::Read &cfg_, + const int tid_, + fuse_file_info_t *ffi_) +{ + switch(cfg_->cache_files) + { + case CacheFiles::ENUM::LIBFUSE: + ffi_->direct_io = cfg_->direct_io; + ffi_->keep_cache = cfg_->kernel_cache; + ffi_->auto_cache = cfg_->auto_cache; + break; + case CacheFiles::ENUM::OFF: + ffi_->direct_io = 1; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + break; + case CacheFiles::ENUM::PARTIAL: + ffi_->direct_io = 0; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + break; + case CacheFiles::ENUM::FULL: + ffi_->direct_io = 0; + ffi_->keep_cache = 1; + ffi_->auto_cache = 0; + break; + case CacheFiles::ENUM::AUTO_FULL: + ffi_->direct_io = 0; + ffi_->keep_cache = 0; + ffi_->auto_cache = 1; + break; + case CacheFiles::ENUM::PER_PROCESS: + std::string proc_name; + + proc_name = procfs::get_name(tid_); + if(cfg_->cache_files_process_names.count(proc_name) == 0) + { + ffi_->direct_io = 1; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + } + else + { + ffi_->direct_io = 0; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + } + break; + } + + if(cfg_->parallel_direct_writes == true) + ffi_->parallel_direct_writes = ffi_->direct_io; +} - static - int - create_core(const std::string &fullpath_, - mode_t mode_, - const mode_t umask_, - const int flags_) - { - if(!fs::acl::dir_has_defaults(fullpath_)) - mode_ &= ~umask_; +static +int +_create_core(const std::string &fullpath_, + mode_t mode_, + const mode_t umask_, + const int flags_) +{ + if(!fs::acl::dir_has_defaults(fullpath_)) + mode_ &= ~umask_; - return fs::open(fullpath_,flags_,mode_); - } + return fs::open(fullpath_,flags_,mode_); +} - static - int - create_core(const Branch *branch_, - const char *fusepath_, - fuse_file_info_t *ffi_, - const mode_t mode_, - const mode_t umask_) - { - int rv; - FileInfo *fi; - std::string fullpath; +static +int +_create_core(const Branch *branch_, + const char *fusepath_, + fuse_file_info_t *ffi_, + const mode_t mode_, + const mode_t umask_) +{ + int rv; + FileInfo *fi; + std::string fullpath; - fullpath = fs::path::make(branch_->path,fusepath_); + fullpath = fs::path::make(branch_->path,fusepath_); - rv = l::create_core(fullpath,mode_,umask_,ffi_->flags); - if(rv == -1) - return -errno; + rv = ::_create_core(fullpath,mode_,umask_,ffi_->flags); + if(rv == -1) + return -errno; - fi = new FileInfo(rv,branch_,fusepath_,ffi_->direct_io); + fi = new FileInfo(rv,branch_,fusepath_,ffi_->direct_io); - ffi_->fh = reinterpret_cast(fi); + ffi_->fh = reinterpret_cast(fi); + return 0; +} + +static +int +_create(const Policy::Search &searchFunc_, + const Policy::Create &createFunc_, + const Branches &branches_, + const char *fusepath_, + fuse_file_info_t *ffi_, + const mode_t mode_, + const mode_t umask_) +{ + int rv; + std::string fullpath; + std::string fusedirpath; + std::vector createpaths; + std::vector existingpaths; + + fusedirpath = fs::path::dirname(fusepath_); + + rv = searchFunc_(branches_,fusedirpath,existingpaths); + if(rv == -1) + return -errno; + + rv = createFunc_(branches_,fusedirpath,createpaths); + if(rv == -1) + return -errno; + + rv = fs::clonepath_as_root(existingpaths[0]->path, + createpaths[0]->path, + fusedirpath); + if(rv == -1) + return -errno; + + return ::_create_core(createpaths[0], + fusepath_, + ffi_, + mode_, + umask_); +} + +static +int +_create_for_insert_lambda(const fuse_context *fc_, + const char *fusepath_, + const mode_t mode_, + fuse_file_info_t *ffi_, + State::OpenFile *of_) +{ + int rv; + FileInfo *fi; + Config::Read cfg; + const ugid::Set ugid(fc_->uid,fc_->gid); + + ::_config_to_ffi_flags(cfg,fc_->pid,ffi_); + if(cfg->writeback_cache) + ::_tweak_flags_writeback_cache(&ffi_->flags); + ffi_->noflush = !::_calculate_flush(cfg->flushonclose, + ffi_->flags); + + rv = ::_create(cfg->func.getattr.policy, + cfg->func.create.policy, + cfg->branches, + fusepath_, + ffi_, + mode_, + fc_->umask); + if(rv == -EROFS) + { + Config::Write()->branches.find_and_set_mode_ro(); + rv = ::_create(cfg->func.getattr.policy, + cfg->func.create.policy, + cfg->branches, + fusepath_, + ffi_, + mode_, + fc_->umask); + } + + if(rv < 0) + return rv; + + fi = reinterpret_cast(ffi_->fh); + + of_->ref_count = 1; + of_->fi = fi; + + if(cfg->passthrough == false) return 0; - } - static - int - create(const Policy::Search &searchFunc_, - const Policy::Create &createFunc_, - const Branches &branches_, - const char *fusepath_, - fuse_file_info_t *ffi_, - const mode_t mode_, - const mode_t umask_) - { - int rv; - std::string fullpath; - std::string fusedirpath; - std::vector createpaths; - std::vector existingpaths; - - fusedirpath = fs::path::dirname(fusepath_); - - rv = searchFunc_(branches_,fusedirpath,existingpaths); - if(rv == -1) - return -errno; - - rv = createFunc_(branches_,fusedirpath,createpaths); - if(rv == -1) - return -errno; - - rv = fs::clonepath_as_root(existingpaths[0]->path, - createpaths[0]->path, - fusedirpath); - if(rv == -1) - return -errno; - - return l::create_core(createpaths[0], - fusepath_, - ffi_, - mode_, - umask_); - } + of_->backing_id = FUSE::passthrough_open(fc_,fi->fd); + if(of_->backing_id < 0) + return 0; + + ffi_->backing_id = of_->backing_id; + ffi_->passthrough = true; + ffi_->keep_cache = false; + + return 0; +} + +static +inline +constexpr +auto +_create_insert_lambda(const fuse_context *fc_, + const char *fusepath_, + const mode_t mode_, + fuse_file_info_t *ffi_, + int *_rv_) +{ + return + [=](auto &val_) + { + *_rv_ = ::_create_for_insert_lambda(fc_, + fusepath_, + mode_, + ffi_, + &val_.second); + fmt::print("create insert {} {}\n", + fc_->nodeid, + ffi_->backing_id); + }; +} + +// This function should never be called? +static +inline +constexpr +auto +_create_update_lambda() +{ + return + [=](auto &val_) + { + fmt::print(stderr,"THIS SHOULD NOT HAPPEN"); + abort(); + }; +} + +static +int +_create(const fuse_context *fc_, + const char *fusepath_, + mode_t mode_, + fuse_file_info_t *ffi_) +{ + int rv; + auto &of = state.open_files; + + rv = -EINVAL; + of.try_emplace_and_visit(fc_->nodeid, + ::_create_insert_lambda(fc_,fusepath_,mode_,ffi_,&rv), + ::_create_update_lambda()); + + // Can't abort an emplace_and_visit and can't assume another thread + // hasn't created an entry since this failure so erase only if + // ref_count is default (0). + if(rv < 0) + of.erase_if(fc_->nodeid, + [](auto &val_) + { + return (val_.second.ref_count <= 0); + }); + + return rv; } namespace FUSE @@ -217,38 +344,9 @@ namespace FUSE mode_t mode_, fuse_file_info_t *ffi_) { - int rv; Config::Read cfg; const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); - - l::config_to_ffi_flags(cfg,fc->pid,ffi_); - - if(cfg->writeback_cache) - l::tweak_flags_writeback_cache(&ffi_->flags); - - ffi_->noflush = !l::calculate_flush(cfg->flushonclose, - ffi_->flags); - - rv = l::create(cfg->func.getattr.policy, - cfg->func.create.policy, - cfg->branches, - fusepath_, - ffi_, - mode_, - fc->umask); - if(rv == -EROFS) - { - Config::Write()->branches.find_and_set_mode_ro(); - rv = l::create(cfg->func.getattr.policy, - cfg->func.create.policy, - cfg->branches, - fusepath_, - ffi_, - mode_, - fc->umask); - } - return rv; + return ::_create(fc,fusepath_,mode_,ffi_); } } diff --git a/src/fuse_fallocate.cpp b/src/fuse_fallocate.cpp index c1b4e82d..2ce66055 100644 --- a/src/fuse_fallocate.cpp +++ b/src/fuse_fallocate.cpp @@ -41,12 +41,12 @@ namespace l namespace FUSE { int - fallocate(const fuse_file_info_t *ffi_, - int mode_, - off_t offset_, - off_t len_) + fallocate(const uint64_t fh_, + int mode_, + off_t offset_, + off_t len_) { - FileInfo *fi = reinterpret_cast(ffi_->fh); + FileInfo *fi = reinterpret_cast(fh_); return l::fallocate(fi->fd, mode_, diff --git a/src/fuse_fallocate.hpp b/src/fuse_fallocate.hpp index 978cc032..cdc3ff24 100644 --- a/src/fuse_fallocate.hpp +++ b/src/fuse_fallocate.hpp @@ -22,8 +22,8 @@ namespace FUSE { int - fallocate(const fuse_file_info_t *ffi, - int mode, - off_t offset, - off_t len); + fallocate(const uint64_t fh, + int mode, + off_t offset, + off_t len); } diff --git a/src/fuse_fchmod.cpp b/src/fuse_fchmod.cpp index 27d802de..4b8558fc 100644 --- a/src/fuse_fchmod.cpp +++ b/src/fuse_fchmod.cpp @@ -17,6 +17,7 @@ #include "errno.hpp" #include "fileinfo.hpp" #include "fs_fchmod.hpp" +#include "state.hpp" #include "fuse.h" @@ -41,10 +42,26 @@ namespace l namespace FUSE { int - fchmod(const fuse_file_info_t *ffi_, - const mode_t mode_) + fchmod(const uint64_t fh_, + const mode_t mode_) { - FileInfo *fi = reinterpret_cast(ffi_->fh); + uint64_t fh; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } + + if(fh == 0) + return -ENOENT; + + FileInfo *fi = reinterpret_cast(fh); return l::fchmod(fi->fd,mode_); } diff --git a/src/fuse_fchmod.hpp b/src/fuse_fchmod.hpp index 64f9e7a5..99723f35 100644 --- a/src/fuse_fchmod.hpp +++ b/src/fuse_fchmod.hpp @@ -24,6 +24,6 @@ namespace FUSE { int - fchmod(const fuse_file_info_t *ffi, - const mode_t mode); + fchmod(const uint64_t fh, + const mode_t mode); } diff --git a/src/fuse_fchown.cpp b/src/fuse_fchown.cpp index 48e8aa16..1cc92f97 100644 --- a/src/fuse_fchown.cpp +++ b/src/fuse_fchown.cpp @@ -17,6 +17,7 @@ #include "errno.hpp" #include "fileinfo.hpp" #include "fs_fchown.hpp" +#include "state.hpp" #include "fuse.h" @@ -44,11 +45,27 @@ namespace l namespace FUSE { int - fchown(const fuse_file_info_t *ffi_, - const uid_t uid_, - const gid_t gid_) + fchown(const uint64_t fh_, + const uid_t uid_, + const gid_t gid_) { - FileInfo *fi = reinterpret_cast(ffi_->fh); + uint64_t fh; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } + + if(fh == 0) + return -ENOENT; + + FileInfo *fi = reinterpret_cast(fh); return l::fchown(fi->fd,uid_,gid_); } diff --git a/src/fuse_fchown.hpp b/src/fuse_fchown.hpp index 991734f6..f743a910 100644 --- a/src/fuse_fchown.hpp +++ b/src/fuse_fchown.hpp @@ -22,7 +22,7 @@ namespace FUSE { int - fchown(const fuse_file_info_t *ffi, - uid_t uid, - gid_t gid); + fchown(const uint64_t fh, + uid_t uid, + gid_t gid); } diff --git a/src/fuse_fgetattr.cpp b/src/fuse_fgetattr.cpp index 7c9369a1..9a1f4335 100644 --- a/src/fuse_fgetattr.cpp +++ b/src/fuse_fgetattr.cpp @@ -19,34 +19,61 @@ #include "fileinfo.hpp" #include "fs_fstat.hpp" #include "fs_inode.hpp" +#include "state.hpp" #include "fuse.h" +static +int +_fgetattr(const FileInfo *fi_, + struct stat *st_, + fuse_timeouts_t *timeout_) +{ + int rv; + Config::Read cfg; + + rv = fs::fstat(fi_->fd,st_); + if(rv < 0) + return rv; + + fs::inode::calc(fi_->branch.path, + fi_->fusepath, + st_); + + timeout_->entry = ((rv >= 0) ? + cfg->cache_entry : + cfg->cache_negative_entry); + timeout_->attr = cfg->cache_attr; + + return rv; +} + namespace FUSE { int - fgetattr(const fuse_file_info_t *ffi_, - struct stat *st_, - fuse_timeouts_t *timeout_) + fgetattr(const uint64_t fh_, + struct stat *st_, + fuse_timeouts_t *timeout_) { - int rv; - Config::Read cfg; - FileInfo *fi = reinterpret_cast(ffi_->fh); + uint64_t fh; + const fuse_context *fc = fuse_get_context(); - rv = fs::fstat(fi->fd,st_); - if(rv == -1) - return -errno; + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } - fs::inode::calc(fi->branch.path, - fi->fusepath, - st_); + if(fh == 0) + return -ENOENT; + + FileInfo *fi = reinterpret_cast(fh); - timeout_->entry = ((rv >= 0) ? - cfg->cache_entry : - cfg->cache_negative_entry); - timeout_->attr = cfg->cache_attr; - - return rv; + return ::_fgetattr(fi,st_,timeout_); } } diff --git a/src/fuse_fgetattr.hpp b/src/fuse_fgetattr.hpp index e58a061a..9a9def7c 100644 --- a/src/fuse_fgetattr.hpp +++ b/src/fuse_fgetattr.hpp @@ -26,7 +26,7 @@ namespace FUSE { int - fgetattr(const fuse_file_info_t *ffi, - struct stat *st, - fuse_timeouts_t *timeout); + fgetattr(const uint64_t fh, + struct stat *st, + fuse_timeouts_t *timeout); } diff --git a/src/fuse_free_hide.cpp b/src/fuse_free_hide.cpp deleted file mode 100644 index 4c057d5f..00000000 --- a/src/fuse_free_hide.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - ISC License - - Copyright (c) 2019, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "fileinfo.hpp" -#include "fs_close.hpp" - -#include - - -namespace FUSE -{ - int - free_hide(const uint64_t fh_) - { - FileInfo *fi = reinterpret_cast(fh_); - - fs::close(fi->fd); - - delete fi; - - return 0; - } -} diff --git a/src/fuse_free_hide.hpp b/src/fuse_free_hide.hpp deleted file mode 100644 index 8b6be9ee..00000000 --- a/src/fuse_free_hide.hpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - ISC License - - Copyright (c) 2019, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#pragma once - -#include - - -namespace FUSE -{ - int - free_hide(const uint64_t fh); -} diff --git a/src/fuse_fsync.cpp b/src/fuse_fsync.cpp index 1ab9824b..77d789dc 100644 --- a/src/fuse_fsync.cpp +++ b/src/fuse_fsync.cpp @@ -45,10 +45,10 @@ namespace l namespace FUSE { int - fsync(const fuse_file_info_t *ffi_, - int isdatasync_) + fsync(const uint64_t fh_, + int isdatasync_) { - FileInfo *fi = reinterpret_cast(ffi_->fh); + FileInfo *fi = reinterpret_cast(fh_); return l::fsync(fi->fd,isdatasync_); } diff --git a/src/fuse_fsync.hpp b/src/fuse_fsync.hpp index 58302504..d62574e1 100644 --- a/src/fuse_fsync.hpp +++ b/src/fuse_fsync.hpp @@ -22,7 +22,7 @@ namespace FUSE { int - fsync(const fuse_file_info_t *ffi, - int isdatasync); + fsync(const uint64_t fh, + int isdatasync); } diff --git a/src/fuse_ftruncate.cpp b/src/fuse_ftruncate.cpp index 4e3116d4..3212e702 100644 --- a/src/fuse_ftruncate.cpp +++ b/src/fuse_ftruncate.cpp @@ -17,6 +17,7 @@ #include "errno.hpp" #include "fileinfo.hpp" #include "fs_ftruncate.hpp" +#include "state.hpp" #include "fuse.h" @@ -39,10 +40,23 @@ namespace l namespace FUSE { int - ftruncate(const fuse_file_info_t *ffi_, - off_t size_) + ftruncate(const uint64_t fh_, + off_t size_) { - FileInfo *fi = reinterpret_cast(ffi_->fh); + uint64_t fh; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } + + FileInfo *fi = reinterpret_cast(fh); return l::ftruncate(fi->fd,size_); } diff --git a/src/fuse_ftruncate.hpp b/src/fuse_ftruncate.hpp index 16d1c720..0b7751d2 100644 --- a/src/fuse_ftruncate.hpp +++ b/src/fuse_ftruncate.hpp @@ -25,6 +25,6 @@ namespace FUSE { int - ftruncate(const fuse_file_info_t *ffi, - off_t size); + ftruncate(const uint64_t fh, + off_t size); } diff --git a/src/fuse_futimens.cpp b/src/fuse_futimens.cpp index 8dd27323..e0fd9016 100644 --- a/src/fuse_futimens.cpp +++ b/src/fuse_futimens.cpp @@ -17,6 +17,7 @@ #include "errno.hpp" #include "fileinfo.hpp" #include "fs_futimens.hpp" +#include "state.hpp" #include "fuse.h" @@ -43,10 +44,23 @@ namespace l namespace FUSE { int - futimens(const fuse_file_info_t *ffi_, - const struct timespec ts_[2]) + futimens(const uint64_t fh_, + const struct timespec ts_[2]) { - FileInfo *fi = reinterpret_cast(ffi_->fh); + uint64_t fh; + const fuse_context *fc = fuse_get_context(); + + fh = fh_; + if(fh == 0) + { + state.open_files.cvisit(fc->nodeid, + [&](auto &val_) + { + fh = reinterpret_cast(val_.second.fi); + }); + } + + FileInfo *fi = reinterpret_cast(fh); return l::futimens(fi->fd,ts_); } diff --git a/src/fuse_futimens.hpp b/src/fuse_futimens.hpp index 7e373cc4..37f69233 100644 --- a/src/fuse_futimens.hpp +++ b/src/fuse_futimens.hpp @@ -24,6 +24,6 @@ namespace FUSE { int - futimens(const fuse_file_info_t *ffi, - const timespec ts[2]); + futimens(const uint64_t fh, + const timespec ts[2]); } diff --git a/src/fuse_getattr.cpp b/src/fuse_getattr.cpp index acd2c52f..c0dae147 100644 --- a/src/fuse_getattr.cpp +++ b/src/fuse_getattr.cpp @@ -16,10 +16,13 @@ #include "config.hpp" #include "errno.hpp" +#include "fs_fstat.hpp" #include "fs_inode.hpp" #include "fs_lstat.hpp" #include "fs_path.hpp" #include "fs_stat.hpp" +#include "fuse_fgetattr.hpp" +#include "state.hpp" #include "symlinkify.hpp" #include "ugid.hpp" diff --git a/src/fuse_init.cpp b/src/fuse_init.cpp index c896f52a..ae6fcfb5 100644 --- a/src/fuse_init.cpp +++ b/src/fuse_init.cpp @@ -16,6 +16,7 @@ #include "config.hpp" #include "fs_readahead.hpp" +#include "state.hpp" #include "syslog.hpp" #include "ugid.hpp" @@ -24,8 +25,9 @@ #include "fuse.h" -#include #include +#include +#include namespace l @@ -201,8 +203,11 @@ namespace FUSE l::want_if_capable(conn_,FUSE_CAP_DIRECT_IO_ALLOW_MMAP,&cfg->direct_io_allow_mmap); l::want_if_capable(conn_,FUSE_CAP_DONT_MASK); l::want_if_capable(conn_,FUSE_CAP_EXPORT_SUPPORT,&cfg->export_support); + l::want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV,&cfg->handle_killpriv); + l::want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV_V2,&cfg->handle_killpriv_v2); l::want_if_capable(conn_,FUSE_CAP_IOCTL_DIR); l::want_if_capable(conn_,FUSE_CAP_PARALLEL_DIROPS); + l::want_if_capable(conn_,FUSE_CAP_PASSTHROUGH); l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&cfg->posix_acl); l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS,&cfg->readdirplus); l::want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&cfg->writeback_cache); @@ -213,6 +218,8 @@ namespace FUSE l::spawn_thread_to_set_readahead(); + state.proc_self_fd_fd = open("/proc/self/fd",O_RDWR|O_PATH|O_DIRECTORY); + return NULL; } } diff --git a/src/fuse_link.cpp b/src/fuse_link.cpp index 6d5453fc..1b5eb0fa 100644 --- a/src/fuse_link.cpp +++ b/src/fuse_link.cpp @@ -22,11 +22,11 @@ #include "fs_path.hpp" #include "fuse_getattr.hpp" #include "fuse_symlink.hpp" -#include "ghc/filesystem.hpp" #include "ugid.hpp" #include "fuse.h" +#include #include #include diff --git a/src/fuse_open.cpp b/src/fuse_open.cpp index 00d88b0d..a78c00aa 100644 --- a/src/fuse_open.cpp +++ b/src/fuse_open.cpp @@ -14,6 +14,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "state.hpp" + #include "config.hpp" #include "errno.hpp" #include "fileinfo.hpp" @@ -21,8 +23,10 @@ #include "fs_fchmod.hpp" #include "fs_lchmod.hpp" #include "fs_open.hpp" +#include "fs_openat.hpp" #include "fs_path.hpp" #include "fs_stat.hpp" +#include "fuse_passthrough.hpp" #include "procfs_get_name.hpp" #include "stat_util.hpp" #include "ugid.hpp" @@ -33,241 +37,395 @@ #include #include +static +bool +_rdonly(const int flags_) +{ + return ((flags_ & O_ACCMODE) == O_RDONLY); +} -namespace l +static +int +_lchmod_and_open_if_not_writable_and_empty(const std::string &fullpath_, + const int flags_) { - static - bool - rdonly(const int flags_) - { - return ((flags_ & O_ACCMODE) == O_RDONLY); - } + int rv; + struct stat st; - static - int - lchmod_and_open_if_not_writable_and_empty(const std::string &fullpath_, - const int flags_) - { - int rv; - struct stat st; + rv = fs::lstat(fullpath_,&st); + if(rv == -1) + return (errno=EACCES,-1); - rv = fs::lstat(fullpath_,&st); - if(rv == -1) - return (errno=EACCES,-1); + if(StatUtil::writable(st)) + return (errno=EACCES,-1); - if(StatUtil::writable(st)) - return (errno=EACCES,-1); + rv = fs::lchmod(fullpath_,(st.st_mode|S_IWUSR|S_IWGRP)); + if(rv == -1) + return (errno=EACCES,-1); - rv = fs::lchmod(fullpath_,(st.st_mode|S_IWUSR|S_IWGRP)); - if(rv == -1) - return (errno=EACCES,-1); + rv = fs::open(fullpath_,flags_); + if(rv == -1) + return (errno=EACCES,-1); + + fs::fchmod(rv,st.st_mode); - rv = fs::open(fullpath_,flags_); - if(rv == -1) + return rv; +} + +static +int +_nfsopenhack(const std::string &fullpath_, + const int flags_, + const NFSOpenHack nfsopenhack_) +{ + switch(nfsopenhack_) + { + default: + case NFSOpenHack::ENUM::OFF: return (errno=EACCES,-1); + case NFSOpenHack::ENUM::GIT: + if(::_rdonly(flags_)) + return (errno=EACCES,-1); + if(fullpath_.find("/.git/") == std::string::npos) + return (errno=EACCES,-1); + return ::_lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_); + case NFSOpenHack::ENUM::ALL: + if(::_rdonly(flags_)) + return (errno=EACCES,-1); + return ::_lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_); + } +} - fs::fchmod(rv,st.st_mode); +/* + The kernel expects being able to issue read requests when running + with writeback caching enabled so we must change O_WRONLY to + O_RDWR. - return rv; - } + With writeback caching enabled the kernel handles O_APPEND. Could + be an issue if the underlying file changes out of band but that is + true of any caching. +*/ +static +void +_tweak_flags_writeback_cache(int *flags_) +{ + if((*flags_ & O_ACCMODE) == O_WRONLY) + *flags_ = ((*flags_ & ~O_ACCMODE) | O_RDWR); + if(*flags_ & O_APPEND) + *flags_ &= ~O_APPEND; +} - static - int - nfsopenhack(const std::string &fullpath_, - const int flags_, - const NFSOpenHack nfsopenhack_) - { - switch(nfsopenhack_) - { - default: - case NFSOpenHack::ENUM::OFF: - return (errno=EACCES,-1); - case NFSOpenHack::ENUM::GIT: - if(l::rdonly(flags_)) - return (errno=EACCES,-1); - if(fullpath_.find("/.git/") == std::string::npos) - return (errno=EACCES,-1); - return l::lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_); - case NFSOpenHack::ENUM::ALL: - if(l::rdonly(flags_)) - return (errno=EACCES,-1); - return l::lchmod_and_open_if_not_writable_and_empty(fullpath_,flags_); - } - } +static +bool +_calculate_flush(FlushOnClose const flushonclose_, + int const flags_) +{ + switch(flushonclose_) + { + case FlushOnCloseEnum::NEVER: + return false; + case FlushOnCloseEnum::OPENED_FOR_WRITE: + return !::_rdonly(flags_); + case FlushOnCloseEnum::ALWAYS: + return true; + } + + return true; +} - /* - The kernel expects being able to issue read requests when running - with writeback caching enabled so we must change O_WRONLY to - O_RDWR. - - With writeback caching enabled the kernel handles O_APPEND. Could - be an issue if the underlying file changes out of band but that is - true of any caching. - */ - static - void - tweak_flags_writeback_cache(int *flags_) - { - if((*flags_ & O_ACCMODE) == O_WRONLY) - *flags_ = ((*flags_ & ~O_ACCMODE) | O_RDWR); - if(*flags_ & O_APPEND) - *flags_ &= ~O_APPEND; - } +static +void +_config_to_ffi_flags(Config::Read &cfg_, + const int tid_, + fuse_file_info_t *ffi_) +{ + switch(cfg_->cache_files) + { + case CacheFiles::ENUM::LIBFUSE: + ffi_->direct_io = cfg_->direct_io; + ffi_->keep_cache = cfg_->kernel_cache; + ffi_->auto_cache = cfg_->auto_cache; + break; + case CacheFiles::ENUM::OFF: + ffi_->direct_io = 1; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + break; + case CacheFiles::ENUM::PARTIAL: + ffi_->direct_io = 0; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + break; + case CacheFiles::ENUM::FULL: + ffi_->direct_io = 0; + ffi_->keep_cache = 1; + ffi_->auto_cache = 0; + break; + case CacheFiles::ENUM::AUTO_FULL: + ffi_->direct_io = 0; + ffi_->keep_cache = 0; + ffi_->auto_cache = 1; + break; + case CacheFiles::ENUM::PER_PROCESS: + std::string proc_name; + + proc_name = procfs::get_name(tid_); + if(cfg_->cache_files_process_names.count(proc_name) == 0) + { + ffi_->direct_io = 1; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + } + else + { + ffi_->direct_io = 0; + ffi_->keep_cache = 0; + ffi_->auto_cache = 0; + } + break; + } + + if(cfg_->parallel_direct_writes == true) + ffi_->parallel_direct_writes = ffi_->direct_io; +} - static - bool - calculate_flush(FlushOnClose const flushonclose_, - int const flags_) - { - switch(flushonclose_) - { - case FlushOnCloseEnum::NEVER: - return false; - case FlushOnCloseEnum::OPENED_FOR_WRITE: - return !l::rdonly(flags_); - case FlushOnCloseEnum::ALWAYS: - return true; - } - - return true; - } +static +int +_open_core(const int dirfd_, + const std::string &filepath_, + const Branch *branch_, + const char *fusepath_, + fuse_file_info_t *ffi_, + const bool link_cow_, + const NFSOpenHack nfsopenhack_) +{ + int fd; + FileInfo *fi; - static - void - config_to_ffi_flags(Config::Read &cfg_, - const int tid_, - fuse_file_info_t *ffi_) - { - switch(cfg_->cache_files) - { - case CacheFiles::ENUM::LIBFUSE: - ffi_->direct_io = cfg_->direct_io; - ffi_->keep_cache = cfg_->kernel_cache; - ffi_->auto_cache = cfg_->auto_cache; - break; - case CacheFiles::ENUM::OFF: - ffi_->direct_io = 1; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::PARTIAL: - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::FULL: - ffi_->direct_io = 0; - ffi_->keep_cache = 1; - ffi_->auto_cache = 0; - break; - case CacheFiles::ENUM::AUTO_FULL: - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 1; - break; - case CacheFiles::ENUM::PER_PROCESS: - std::string proc_name; - - proc_name = procfs::get_name(tid_); - if(cfg_->cache_files_process_names.count(proc_name) == 0) - { - ffi_->direct_io = 1; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - } - else - { - ffi_->direct_io = 0; - ffi_->keep_cache = 0; - ffi_->auto_cache = 0; - } - break; - } - - if(cfg_->parallel_direct_writes == true) - ffi_->parallel_direct_writes = ffi_->direct_io; - } + if(link_cow_ && fs::cow::is_eligible(filepath_.c_str(),ffi_->flags)) + fs::cow::break_link(filepath_.c_str()); - static - int - open_core(const Branch *branch_, - const char *fusepath_, - fuse_file_info_t *ffi_, - const bool link_cow_, - const NFSOpenHack nfsopenhack_) - { - int fd; - FileInfo *fi; - std::string fullpath; + fd = fs::openat(dirfd_,filepath_,ffi_->flags); + if((fd == -1) && (errno == EACCES)) + fd = ::_nfsopenhack(filepath_,ffi_->flags,nfsopenhack_); + if(fd == -1) + return -errno; - fullpath = fs::path::make(branch_->path,fusepath_); + fi = new FileInfo(fd,branch_,fusepath_,ffi_->direct_io); - if(link_cow_ && fs::cow::is_eligible(fullpath.c_str(),ffi_->flags)) - fs::cow::break_link(fullpath.c_str()); + ffi_->fh = reinterpret_cast(fi); - fd = fs::open(fullpath,ffi_->flags); - if((fd == -1) && (errno == EACCES)) - fd = l::nfsopenhack(fullpath,ffi_->flags,nfsopenhack_); - if(fd == -1) - return -errno; + return 0; +} + +static +int +_open(const Policy::Search &searchFunc_, + const Branches &ibranches_, + const char *fusepath_, + fuse_file_info_t *ffi_, + const bool link_cow_, + const NFSOpenHack nfsopenhack_) +{ + int rv; + std::string filepath; + std::vector obranches; + + rv = searchFunc_(ibranches_,fusepath_,obranches); + if(rv == -1) + return -errno; + + filepath = fs::path::make(obranches[0]->path,fusepath_); + rv = ::_open_core(AT_FDCWD, + filepath, + obranches[0], + fusepath_, + ffi_, + link_cow_, + nfsopenhack_); + + return rv; +} + +static +int +_open_for_insert_lambda(const fuse_context *fc_, + const char *fusepath_, + fuse_file_info_t *ffi_, + State::OpenFile *of_) +{ + int rv; + FileInfo *fi; + Config::Read cfg; + const ugid::Set ugid(fc_->uid,fc_->gid); - fi = new FileInfo(fd,branch_,fusepath_,ffi_->direct_io); + ::_config_to_ffi_flags(cfg,fc_->pid,ffi_); + + if(cfg->writeback_cache) + ::_tweak_flags_writeback_cache(&ffi_->flags); + + ffi_->noflush = !::_calculate_flush(cfg->flushonclose, + ffi_->flags); + + rv = ::_open(cfg->func.open.policy, + cfg->branches, + fusepath_, + ffi_, + cfg->link_cow, + cfg->nfsopenhack); + + if(rv < 0) + return rv; - ffi_->fh = reinterpret_cast(fi); + fi = reinterpret_cast(ffi_->fh); + of_->ref_count = 1; + of_->fi = fi; + + if(cfg->passthrough == false) return 0; - } - static - int - open(const Policy::Search &searchFunc_, - const Branches &ibranches_, - const char *fusepath_, - fuse_file_info_t *ffi_, - const bool link_cow_, - const NFSOpenHack nfsopenhack_) - { - int rv; - std::vector obranches; - - rv = searchFunc_(ibranches_,fusepath_,obranches); - if(rv == -1) - return -errno; - - return l::open_core(obranches[0], - fusepath_, - ffi_, - link_cow_, - nfsopenhack_); - } + of_->backing_id = FUSE::passthrough_open(fc_,fi->fd); + if(of_->backing_id <= 0) + return 0; + + ffi_->backing_id = of_->backing_id; + ffi_->passthrough = true; + ffi_->keep_cache = false; + + return 0; } +static +int +_open_for_update_lambda(const fuse_context *fc_, + const char *fusepath_, + fuse_file_info_t *ffi_, + State::OpenFile *of_) +{ + int rv; + Config::Read cfg; + const ugid::Set ugid(fc_->uid,fc_->gid); + + ::_config_to_ffi_flags(cfg,fc_->pid,ffi_); + + if(cfg->writeback_cache) + ::_tweak_flags_writeback_cache(&ffi_->flags); + + ffi_->noflush = !::_calculate_flush(cfg->flushonclose, + ffi_->flags); + + rv = ::_open_core(state.proc_self_fd_fd, + fmt::format("{}",of_->fi->fd), + &of_->fi->branch, + fusepath_, + ffi_, + false, // link_cow, need to always open the original + cfg->nfsopenhack); + if(rv < 0) + return rv; + + of_->ref_count++; + + ffi_->backing_id = of_->backing_id; + ffi_->passthrough = true; + ffi_->keep_cache = false; + + return rv; +} + +static +inline +constexpr +auto +_open_insert_lambda(const fuse_context *fc_, + const char *fusepath_, + fuse_file_info_t *ffi_, + int *_rv_) +{ + return + [=](auto &val_) + { + *_rv_ = ::_open_for_insert_lambda(fc_, + fusepath_, + ffi_, + &val_.second); + fmt::print("open insert {} {}\n", + fc_->nodeid, + ffi_->backing_id); + }; +} + +static +inline +constexpr +auto +_open_update_lambda(const fuse_context *fc_, + const char *fusepath_, + fuse_file_info_t *ffi_, + int *_rv_) +{ + return + [=](auto &val_) + { + // For the edge case where insert succeeded but the open failed + // and hadn't been cleaned up yet. There unfortunately is no way + // to abort an insert. + if(val_.second.ref_count <= 0) + { + *_rv_ = ::_open_for_insert_lambda(fc_, + fusepath_, + ffi_, + &val_.second); + return; + } + + *_rv_ = ::_open_for_update_lambda(fc_, + fusepath_, + ffi_, + &val_.second); + fmt::print("open update {} {}\n", + fc_->nodeid, + ffi_->backing_id); + }; +} + +static +int +_open(const fuse_context *fc_, + const char *fusepath_, + fuse_file_info_t *ffi_) +{ + int rv; + auto &of = state.open_files; + + rv = -EINVAL; + of.try_emplace_and_visit(fc_->nodeid, + ::_open_insert_lambda(fc_,fusepath_,ffi_,&rv), + ::_open_update_lambda(fc_,fusepath_,ffi_,&rv)); + + // Can't abort an emplace_and_visit and can't assume another thread + // hasn't created an entry since this failure so erase only if + // ref_count is default (0). + if(rv < 0) + of.erase_if(fc_->nodeid, + [](auto &val_) + { + return (val_.second.ref_count <= 0); + }); + + return rv; +} + + namespace FUSE { int open(const char *fusepath_, fuse_file_info_t *ffi_) { - int rv; - Config::Read cfg; - const fuse_context *fc = fuse_get_context(); - const ugid::Set ugid(fc->uid,fc->gid); + const fuse_context *fc = fuse_get_context(); - l::config_to_ffi_flags(cfg,fc->pid,ffi_); - - if(cfg->writeback_cache) - l::tweak_flags_writeback_cache(&ffi_->flags); - - ffi_->noflush = !l::calculate_flush(cfg->flushonclose, - ffi_->flags); - - rv = l::open(cfg->func.open.policy, - cfg->branches, - fusepath_, - ffi_, - cfg->link_cow, - cfg->nfsopenhack); - - return rv; + return ::_open(fc,fusepath_,ffi_); } } diff --git a/src/fuse_passthrough.hpp b/src/fuse_passthrough.hpp new file mode 100644 index 00000000..91338b22 --- /dev/null +++ b/src/fuse_passthrough.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "ugid.hpp" + +#include "fuse.h" + +namespace FUSE +{ + static + inline + int + passthrough_open(const fuse_context *fc_, + const int fd_) + { + const ugid::SetRootGuard _; + + return fuse_passthrough_open(fc_,fd_); + } + + static + inline + int + passthrough_close(const fuse_context *fc_, + const int backing_id_) + { + const ugid::SetRootGuard _; + + return fuse_passthrough_close(fc_,backing_id_); + } +} diff --git a/src/fuse_prepare_hide.cpp b/src/fuse_prepare_hide.cpp deleted file mode 100644 index fbd741ea..00000000 --- a/src/fuse_prepare_hide.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - ISC License - - Copyright (c) 2019, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "fuse_open.hpp" - -#include - -#include - - -namespace FUSE -{ - int - prepare_hide(const char *fusepath_, - uint64_t *fh_) - { - int rv; - fuse_file_info_t ffi = {0}; - - ffi.flags = O_RDONLY|O_NOFOLLOW; - rv = FUSE::open(fusepath_,&ffi); - if(rv < 0) - return rv; - - *fh_ = ffi.fh; - - return 0; - } -} diff --git a/src/fuse_prepare_hide.hpp b/src/fuse_prepare_hide.hpp deleted file mode 100644 index 9e38760b..00000000 --- a/src/fuse_prepare_hide.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - ISC License - - Copyright (c) 2019, Antonio SJ Musumeci - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#pragma once - -#include - - -namespace FUSE -{ - int - prepare_hide(const char *name, - uint64_t *fh); -} diff --git a/src/fuse_release.cpp b/src/fuse_release.cpp index 03b6dcdb..dc8c804f 100644 --- a/src/fuse_release.cpp +++ b/src/fuse_release.cpp @@ -14,38 +14,91 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "state.hpp" + #include "config.hpp" -#include "errno.hpp" #include "fileinfo.hpp" #include "fs_close.hpp" #include "fs_fadvise.hpp" +#include "fuse_passthrough.hpp" #include "fuse.h" -#include +static +constexpr +auto +_erase_if_lambda(const fuse_context *fc_, + FileInfo *fi_, + bool *existed_in_map_) +{ + return + [=](auto &val_) + { + *existed_in_map_ = true; + fmt::print("release erase {} {}\n", + val_.first, + val_.second.backing_id); -namespace l -{ - static - int - release(FileInfo *fi_, - const bool dropcacheonclose_) - { - // according to Feh of nocache calling it once doesn't always work - // https://github.com/Feh/nocache - if(dropcacheonclose_) - { - fs::fadvise_dontneed(fi_->fd); - fs::fadvise_dontneed(fi_->fd); - } + if(fi_ != val_.second.fi) + { + fs::close(fi_->fd); + delete fi_; + } - fs::close(fi_->fd); + val_.second.ref_count--; + if(val_.second.ref_count > 0) + return false; - delete fi_; + if(val_.second.backing_id > 0) + FUSE::passthrough_close(fc_,val_.second.backing_id); + fs::close(val_.second.fi->fd); + delete val_.second.fi; + + return true; + }; +} + +static +int +_release(const fuse_context *fc_, + FileInfo *fi_, + const bool dropcacheonclose_) +{ + bool existed_in_map; + // according to Feh of nocache calling it once doesn't always work + // https://github.com/Feh/nocache + if(dropcacheonclose_) + { + fs::fadvise_dontneed(fi_->fd); + fs::fadvise_dontneed(fi_->fd); + } + + // Because of course the API doesn't tell you if the key + // existed. Just how many it erased and in this case I only want to + // erase if there are no more open files. + existed_in_map = false; + state.open_files.erase_if(fc_->nodeid, + ::_erase_if_lambda(fc_,fi_,&existed_in_map)); + if(existed_in_map) return 0; - } + + fs::close(fi_->fd); + delete fi_; + + return 0; +} + +static +int +_release(const fuse_context *fc_, + const fuse_file_info_t *ffi_) +{ + Config::Read cfg; + FileInfo *fi = reinterpret_cast(ffi_->fh); + + return ::_release(fc_,fi,cfg->dropcacheonclose); } namespace FUSE @@ -53,9 +106,8 @@ namespace FUSE int release(const fuse_file_info_t *ffi_) { - Config::Read cfg; - FileInfo *fi = reinterpret_cast(ffi_->fh); + const fuse_context *fc = fuse_get_context(); - return l::release(fi,cfg->dropcacheonclose); + return ::_release(fc,ffi_); } } diff --git a/src/fuse_rename.cpp b/src/fuse_rename.cpp index cf3f04bb..6baad57b 100644 --- a/src/fuse_rename.cpp +++ b/src/fuse_rename.cpp @@ -27,15 +27,12 @@ #include "fuse_symlink.hpp" #include "ugid.hpp" -#include "ghc/filesystem.hpp" - #include +#include +#include #include #include -#include - -namespace gfs = ghc::filesystem; namespace error { @@ -91,19 +88,19 @@ namespace l static int - rename_create_path(const Policy::Search &searchPolicy_, - const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const gfs::path &oldfusepath_, - const gfs::path &newfusepath_) + rename_create_path(const Policy::Search &searchPolicy_, + const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) { int rv; int error; StrVec toremove; std::vector newbranches; std::vector oldbranches; - gfs::path oldfullpath; - gfs::path newfullpath; + std::filesystem::path oldfullpath; + std::filesystem::path newfullpath; rv = actionPolicy_(branches_,oldfusepath_,oldbranches); if(rv == -1) @@ -151,17 +148,17 @@ namespace l static int - rename_preserve_path(const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const gfs::path &oldfusepath_, - const gfs::path &newfusepath_) + rename_preserve_path(const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) { int rv; bool success; StrVec toremove; std::vector oldbranches; - gfs::path oldfullpath; - gfs::path newfullpath; + std::filesystem::path oldfullpath; + std::filesystem::path newfullpath; rv = actionPolicy_(branches_,oldfusepath_,oldbranches); if(rv == -1) @@ -203,11 +200,11 @@ namespace l static void - rename_exdev_rename_back(const std::vector &branches_, - const gfs::path &oldfusepath_) + rename_exdev_rename_back(const std::vector &branches_, + const std::filesystem::path &oldfusepath_) { - gfs::path oldpath; - gfs::path newpath; + std::filesystem::path oldpath; + std::filesystem::path newpath; for(auto &branch : branches_) { @@ -224,14 +221,14 @@ namespace l static int - rename_exdev_rename_target(const Policy::Action &actionPolicy_, - const Branches::Ptr &ibranches_, - const gfs::path &oldfusepath_, - std::vector &obranches_) + rename_exdev_rename_target(const Policy::Action &actionPolicy_, + const Branches::Ptr &ibranches_, + const std::filesystem::path &oldfusepath_, + std::vector &obranches_) { int rv; - gfs::path clonesrc; - gfs::path clonetgt; + std::filesystem::path clonesrc; + std::filesystem::path clonetgt; rv = actionPolicy_(ibranches_,oldfusepath_,obranches_); if(rv == -1) @@ -272,14 +269,14 @@ namespace l static int - rename_exdev_rel_symlink(const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const gfs::path &oldfusepath_, - const gfs::path &newfusepath_) + rename_exdev_rel_symlink(const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) { int rv; - gfs::path target; - gfs::path linkpath; + std::filesystem::path target; + std::filesystem::path linkpath; std::vector branches; rv = l::rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches); @@ -300,15 +297,15 @@ namespace l static int - rename_exdev_abs_symlink(const Policy::Action &actionPolicy_, - const Branches::Ptr &branches_, - const gfs::path &mount_, - const gfs::path &oldfusepath_, - const gfs::path &newfusepath_) + rename_exdev_abs_symlink(const Policy::Action &actionPolicy_, + const Branches::Ptr &branches_, + const std::filesystem::path &mount_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) { int rv; - gfs::path target; - gfs::path linkpath; + std::filesystem::path target; + std::filesystem::path linkpath; std::vector branches; rv = l::rename_exdev_rename_target(actionPolicy_,branches_,oldfusepath_,branches); @@ -329,9 +326,9 @@ namespace l static int - rename_exdev(Config::Read &cfg_, - const gfs::path &oldfusepath_, - const gfs::path &newfusepath_) + rename_exdev(Config::Read &cfg_, + const std::filesystem::path &oldfusepath_, + const std::filesystem::path &newfusepath_) { switch(cfg_->rename_exdev) { @@ -355,9 +352,9 @@ namespace l static int - rename(Config::Read &cfg_, - const gfs::path &oldpath_, - const gfs::path &newpath_) + rename(Config::Read &cfg_, + const std::filesystem::path &oldpath_, + const std::filesystem::path &newpath_) { if(cfg_->func.create.policy.path_preserving() && !cfg_->ignorepponrename) return l::rename_preserve_path(cfg_->func.rename.policy, @@ -381,8 +378,8 @@ namespace FUSE { int rv; Config::Read cfg; - gfs::path oldfusepath(oldfusepath_); - gfs::path newfusepath(newfusepath_); + std::filesystem::path oldfusepath(oldfusepath_); + std::filesystem::path newfusepath(newfusepath_); const fuse_context *fc = fuse_get_context(); const ugid::Set ugid(fc->uid,fc->gid); diff --git a/src/ghc/filesystem.hpp b/src/ghc/filesystem.hpp deleted file mode 100644 index 8aa4167a..00000000 --- a/src/ghc/filesystem.hpp +++ /dev/null @@ -1,6072 +0,0 @@ -//--------------------------------------------------------------------------------------- -// -// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14/C++17/C++20 -// -//--------------------------------------------------------------------------------------- -// -// Copyright (c) 2018, Steffen Schümann -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//--------------------------------------------------------------------------------------- -#ifndef GHC_FILESYSTEM_H -#define GHC_FILESYSTEM_H - -// #define BSD manifest constant only in -// sys/param.h -#ifndef _WIN32 -#include -#endif - -#ifndef GHC_OS_DETECTED -#if defined(__APPLE__) && defined(__MACH__) -#define GHC_OS_APPLE -#elif defined(__linux__) -#define GHC_OS_LINUX -#if defined(__ANDROID__) -#define GHC_OS_ANDROID -#endif -#elif defined(_WIN64) -#define GHC_OS_WINDOWS -#define GHC_OS_WIN64 -#elif defined(_WIN32) -#define GHC_OS_WINDOWS -#define GHC_OS_WIN32 -#elif defined(__CYGWIN__) -#define GHC_OS_CYGWIN -#elif defined(__sun) && defined(__SVR4) -#define GHC_OS_SOLARIS -#elif defined(__svr4__) -#define GHC_OS_SYS5R4 -#elif defined(BSD) -#define GHC_OS_BSD -#elif defined(__EMSCRIPTEN__) -#define GHC_OS_WEB -#include -#elif defined(__QNX__) -#define GHC_OS_QNX -#elif defined(__HAIKU__) -#define GHC_OS_HAIKU -#else -#error "Operating system currently not supported!" -#endif -#define GHC_OS_DETECTED -#if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -#if _MSVC_LANG == 201703L -#define GHC_FILESYSTEM_RUNNING_CPP17 -#else -#define GHC_FILESYSTEM_RUNNING_CPP20 -#endif -#elif (defined(__cplusplus) && __cplusplus >= 201703L) -#if __cplusplus == 201703L -#define GHC_FILESYSTEM_RUNNING_CPP17 -#else -#define GHC_FILESYSTEM_RUNNING_CPP20 -#endif -#endif -#endif - -#if defined(GHC_FILESYSTEM_IMPLEMENTATION) -#define GHC_EXPAND_IMPL -#define GHC_INLINE -#ifdef GHC_OS_WINDOWS -#ifndef GHC_FS_API -#define GHC_FS_API -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#else -#ifndef GHC_FS_API -#define GHC_FS_API __attribute__((visibility("default"))) -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS __attribute__((visibility("default"))) -#endif -#endif -#elif defined(GHC_FILESYSTEM_FWD) -#define GHC_INLINE -#ifdef GHC_OS_WINDOWS -#ifndef GHC_FS_API -#define GHC_FS_API extern -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#else -#ifndef GHC_FS_API -#define GHC_FS_API extern -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#endif -#else -#define GHC_EXPAND_IMPL -#define GHC_INLINE inline -#ifndef GHC_FS_API -#define GHC_FS_API -#endif -#ifndef GHC_FS_API_CLASS -#define GHC_FS_API_CLASS -#endif -#endif - -#ifdef GHC_EXPAND_IMPL - -#ifdef GHC_OS_WINDOWS -#include -// additional includes -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef GHC_OS_ANDROID -#include -#if __ANDROID_API__ < 12 -#include -#endif -#include -#define statvfs statfs -#else -#include -#endif -#ifdef GHC_OS_CYGWIN -#include -#endif -#if !defined(__ANDROID__) || __ANDROID_API__ >= 26 -#include -#endif -#endif -#ifdef GHC_OS_APPLE -#include -#endif - -#if defined(__cpp_impl_three_way_comparison) && defined(__has_include) -#if __has_include() -#define GHC_HAS_THREEWAY_COMP -#include -#endif -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#else // GHC_EXPAND_IMPL - -#if defined(__cpp_impl_three_way_comparison) && defined(__has_include) -#if __has_include() -#define GHC_HAS_THREEWAY_COMP -#include -#endif -#endif -#include -#include -#include -#include -#include -#include -#include -#ifdef GHC_OS_WINDOWS -#include -#endif -#endif // GHC_EXPAND_IMPL - -// After standard library includes. -// Standard library support for std::string_view. -#if defined(__cpp_lib_string_view) -#define GHC_HAS_STD_STRING_VIEW -#elif defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 4000) && (__cplusplus >= 201402) -#define GHC_HAS_STD_STRING_VIEW -#elif defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE >= 7) && (__cplusplus >= 201703) -#define GHC_HAS_STD_STRING_VIEW -#elif defined(_MSC_VER) && (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) -#define GHC_HAS_STD_STRING_VIEW -#endif - -// Standard library support for std::experimental::string_view. -#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 3700 && _LIBCPP_VERSION < 7000) && (__cplusplus >= 201402) -#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW -#elif defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)) && (__cplusplus >= 201402) -#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW -#elif defined(__GLIBCXX__) && defined(_GLIBCXX_USE_DUAL_ABI) && (__cplusplus >= 201402) -// macro _GLIBCXX_USE_DUAL_ABI is always defined in libstdc++ from gcc-5 and newer -#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW -#endif - -#if defined(GHC_HAS_STD_STRING_VIEW) -#include -#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) -#include -#endif - -#if !defined(GHC_OS_WINDOWS) && !defined(PATH_MAX) -#define PATH_MAX 4096 -#endif - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Behaviour Switches (see README.md, should match the config in test/filesystem_test.cpp): -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Enforce C++17 API where possible when compiling for C++20, handles the following cases: -// * fs::path::u8string() returns std::string instead of std::u8string -// #define GHC_FILESYSTEM_ENFORCE_CPP17_API -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2682 disables the since then invalid use of the copy option create_symlinks on directories -// configure LWG conformance () -#define LWG_2682_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2395 makes crate_directory/create_directories not emit an error if there is a regular -// file with that name, it is superseded by P1164R1, so only activate if really needed -// #define LWG_2935_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2936 enables new element wise (more expensive) path comparison -// * if this->root_name().native().compare(p.root_name().native()) != 0 return result -// * if this->has_root_directory() and !p.has_root_directory() return -1 -// * if !this->has_root_directory() and p.has_root_directory() return -1 -// * else result of element wise comparison of path iteration where first comparison is != 0 or 0 -// if all comparisons are 0 (on Windows this implementation does case-insensitive root_name() -// comparison) -#define LWG_2936_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// LWG #2937 enforces that fs::equivalent emits an error, if !fs::exists(p1)||!exists(p2) -#define LWG_2937_BEHAVIOUR -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// UTF8-Everywhere is the original behaviour of ghc::filesystem. But since v1.5 the Windows -// version defaults to std::wstring storage backend. Still all std::string will be interpreted -// as UTF-8 encoded. With this define you can enforce the old behavior on Windows, using -// std::string as backend and for fs::path::native() and char for fs::path::c_str(). This -// needs more conversions, so it is (and was before v1.5) slower, bot might help keeping source -// homogeneous in a multi-platform project. -// #define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Raise errors/exceptions when invalid unicode codepoints or UTF-8 sequences are found, -// instead of replacing them with the unicode replacement character (U+FFFD). -// #define GHC_RAISE_UNICODE_ERRORS -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Automatic prefix windows path with "\\?\" if they would break the MAX_PATH length. -// instead of replacing them with the unicode replacement character (U+FFFD). -#ifndef GHC_WIN_DISABLE_AUTO_PREFIXES -#define GHC_WIN_AUTO_PREFIX_LONG_PATH -#endif // GHC_WIN_DISABLE_AUTO_PREFIXES -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch) -#define GHC_FILESYSTEM_VERSION 10515L - -#if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)) -#define GHC_WITH_EXCEPTIONS -#endif -#if !defined(GHC_WITH_EXCEPTIONS) && defined(GHC_RAISE_UNICODE_ERRORS) -#error "Can't raise unicode errors with exception support disabled" -#endif - -namespace ghc { -namespace filesystem { - -#if defined(GHC_HAS_CUSTOM_STRING_VIEW) -#define GHC_WITH_STRING_VIEW -#elif defined(GHC_HAS_STD_STRING_VIEW) -#define GHC_WITH_STRING_VIEW -using std::basic_string_view; -#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) -#define GHC_WITH_STRING_VIEW -using std::experimental::basic_string_view; -#endif - -// temporary existing exception type for yet unimplemented parts -class GHC_FS_API_CLASS not_implemented_exception : public std::logic_error -{ -public: - not_implemented_exception() - : std::logic_error("function not implemented yet.") - { - } -}; - -template -class path_helper_base -{ -public: - using value_type = char_type; -#ifdef GHC_OS_WINDOWS - static constexpr value_type preferred_separator = '\\'; -#else - static constexpr value_type preferred_separator = '/'; -#endif -}; - -#if __cplusplus < 201703L -template -constexpr char_type path_helper_base::preferred_separator; -#endif - -#ifdef GHC_OS_WINDOWS -class path; -namespace detail { -bool has_executable_extension(const path& p); -} -#endif - -// [fs.class.path] class path -class GHC_FS_API_CLASS path -#if defined(GHC_OS_WINDOWS) && !defined(GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) -#define GHC_USE_WCHAR_T -#define GHC_NATIVEWP(p) p.c_str() -#define GHC_PLATFORM_LITERAL(str) L##str - : private path_helper_base -{ -public: - using path_helper_base::value_type; -#else -#define GHC_NATIVEWP(p) p.wstring().c_str() -#define GHC_PLATFORM_LITERAL(str) str - : private path_helper_base -{ -public: - using path_helper_base::value_type; -#endif - using string_type = std::basic_string; - using path_helper_base::preferred_separator; - - // [fs.enum.path.format] enumeration format - /// The path format in which the constructor argument is given. - enum format { - generic_format, ///< The generic format, internally used by - ///< ghc::filesystem::path with slashes - native_format, ///< The format native to the current platform this code - ///< is build for - auto_format, ///< Try to auto-detect the format, fallback to native - }; - - template - struct _is_basic_string : std::false_type - { - }; - template - struct _is_basic_string> : std::true_type - { - }; - template - struct _is_basic_string, std::allocator>> : std::true_type - { - }; -#ifdef GHC_WITH_STRING_VIEW - template - struct _is_basic_string> : std::true_type - { - }; - template - struct _is_basic_string>> : std::true_type - { - }; -#endif - - template - using path_type = typename std::enable_if::value, path>::type; - template -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) - using path_from_string = - typename std::enable_if<_is_basic_string::value || std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value, - path>::type; - template - using path_type_EcharT = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value, path>::type; -#else - using path_from_string = - typename std::enable_if<_is_basic_string::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || - std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value, - path>::type; - template - using path_type_EcharT = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value, path>::type; -#endif - // [fs.path.construct] constructors and destructor - path() noexcept; - path(const path& p); - path(path&& p) noexcept; - path(string_type&& source, format fmt = auto_format); - template > - path(const Source& source, format fmt = auto_format); - template - path(InputIterator first, InputIterator last, format fmt = auto_format); -#ifdef GHC_WITH_EXCEPTIONS - template > - path(const Source& source, const std::locale& loc, format fmt = auto_format); - template - path(InputIterator first, InputIterator last, const std::locale& loc, format fmt = auto_format); -#endif - ~path(); - - // [fs.path.assign] assignments - path& operator=(const path& p); - path& operator=(path&& p) noexcept; - path& operator=(string_type&& source); - path& assign(string_type&& source); - template - path& operator=(const Source& source); - template - path& assign(const Source& source); - template - path& assign(InputIterator first, InputIterator last); - - // [fs.path.append] appends - path& operator/=(const path& p); - template - path& operator/=(const Source& source); - template - path& append(const Source& source); - template - path& append(InputIterator first, InputIterator last); - - // [fs.path.concat] concatenation - path& operator+=(const path& x); - path& operator+=(const string_type& x); -#ifdef GHC_WITH_STRING_VIEW - path& operator+=(basic_string_view x); -#endif - path& operator+=(const value_type* x); - path& operator+=(value_type x); - template - path_from_string& operator+=(const Source& x); - template - path_type_EcharT& operator+=(EcharT x); - template - path& concat(const Source& x); - template - path& concat(InputIterator first, InputIterator last); - - // [fs.path.modifiers] modifiers - void clear() noexcept; - path& make_preferred(); - path& remove_filename(); - path& replace_filename(const path& replacement); - path& replace_extension(const path& replacement = path()); - void swap(path& rhs) noexcept; - - // [fs.path.native.obs] native format observers - const string_type& native() const noexcept; - const value_type* c_str() const noexcept; - operator string_type() const; - template , class Allocator = std::allocator> - std::basic_string string(const Allocator& a = Allocator()) const; - std::string string() const; - std::wstring wstring() const; -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) - std::u8string u8string() const; -#else - std::string u8string() const; -#endif - std::u16string u16string() const; - std::u32string u32string() const; - - // [fs.path.generic.obs] generic format observers - template , class Allocator = std::allocator> - std::basic_string generic_string(const Allocator& a = Allocator()) const; - std::string generic_string() const; - std::wstring generic_wstring() const; -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) - std::u8string generic_u8string() const; -#else - std::string generic_u8string() const; -#endif - std::u16string generic_u16string() const; - std::u32string generic_u32string() const; - - // [fs.path.compare] compare - int compare(const path& p) const noexcept; - int compare(const string_type& s) const; -#ifdef GHC_WITH_STRING_VIEW - int compare(basic_string_view s) const; -#endif - int compare(const value_type* s) const; - - // [fs.path.decompose] decomposition - path root_name() const; - path root_directory() const; - path root_path() const; - path relative_path() const; - path parent_path() const; - path filename() const; - path stem() const; - path extension() const; - - // [fs.path.query] query - bool empty() const noexcept; - bool has_root_name() const; - bool has_root_directory() const; - bool has_root_path() const; - bool has_relative_path() const; - bool has_parent_path() const; - bool has_filename() const; - bool has_stem() const; - bool has_extension() const; - bool is_absolute() const; - bool is_relative() const; - - // [fs.path.gen] generation - path lexically_normal() const; - path lexically_relative(const path& base) const; - path lexically_proximate(const path& base) const; - - // [fs.path.itr] iterators - class iterator; - using const_iterator = iterator; - iterator begin() const; - iterator end() const; - -private: - using impl_value_type = value_type; - using impl_string_type = std::basic_string; - friend class directory_iterator; - void append_name(const value_type* name); - static constexpr impl_value_type generic_separator = '/'; - template - class input_iterator_range - { - public: - typedef InputIterator iterator; - typedef InputIterator const_iterator; - typedef typename InputIterator::difference_type difference_type; - - input_iterator_range(const InputIterator& first, const InputIterator& last) - : _first(first) - , _last(last) - { - } - - InputIterator begin() const { return _first; } - InputIterator end() const { return _last; } - - private: - InputIterator _first; - InputIterator _last; - }; - friend void swap(path& lhs, path& rhs) noexcept; - friend size_t hash_value(const path& p) noexcept; - friend path canonical(const path& p, std::error_code& ec); - friend bool create_directories(const path& p, std::error_code& ec) noexcept; - string_type::size_type root_name_length() const noexcept; - void postprocess_path_with_format(format fmt); - void check_long_path(); - impl_string_type _path; -#ifdef GHC_OS_WINDOWS - void handle_prefixes(); - friend bool detail::has_executable_extension(const path& p); -#ifdef GHC_WIN_AUTO_PREFIX_LONG_PATH - string_type::size_type _prefixLength{0}; -#else // GHC_WIN_AUTO_PREFIX_LONG_PATH - static const string_type::size_type _prefixLength{0}; -#endif // GHC_WIN_AUTO_PREFIX_LONG_PATH -#else - static const string_type::size_type _prefixLength{0}; -#endif -}; - -// [fs.path.nonmember] path non-member functions -GHC_FS_API void swap(path& lhs, path& rhs) noexcept; -GHC_FS_API size_t hash_value(const path& p) noexcept; -#ifdef GHC_HAS_THREEWAY_COMP -GHC_FS_API std::strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept; -#endif -GHC_FS_API bool operator==(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator!=(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator<(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator<=(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator>(const path& lhs, const path& rhs) noexcept; -GHC_FS_API bool operator>=(const path& lhs, const path& rhs) noexcept; -GHC_FS_API path operator/(const path& lhs, const path& rhs); - -// [fs.path.io] path inserter and extractor -template -std::basic_ostream& operator<<(std::basic_ostream& os, const path& p); -template -std::basic_istream& operator>>(std::basic_istream& is, path& p); - -// [pfs.path.factory] path factory functions -template > -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -[[deprecated("use ghc::filesystem::path::path() with std::u8string instead")]] -#endif -path u8path(const Source& source); -template -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -[[deprecated("use ghc::filesystem::path::path() with std::u8string instead")]] -#endif -path u8path(InputIterator first, InputIterator last); - -// [fs.class.filesystem_error] class filesystem_error -class GHC_FS_API_CLASS filesystem_error : public std::system_error -{ -public: - filesystem_error(const std::string& what_arg, std::error_code ec); - filesystem_error(const std::string& what_arg, const path& p1, std::error_code ec); - filesystem_error(const std::string& what_arg, const path& p1, const path& p2, std::error_code ec); - const path& path1() const noexcept; - const path& path2() const noexcept; - const char* what() const noexcept override; - -private: - std::string _what_arg; - std::error_code _ec; - path _p1, _p2; -}; - -class GHC_FS_API_CLASS path::iterator -{ -public: - using value_type = const path; - using difference_type = std::ptrdiff_t; - using pointer = const path*; - using reference = const path&; - using iterator_category = std::bidirectional_iterator_tag; - - iterator(); - iterator(const path& p, const impl_string_type::const_iterator& pos); - iterator& operator++(); - iterator operator++(int); - iterator& operator--(); - iterator operator--(int); - bool operator==(const iterator& other) const; - bool operator!=(const iterator& other) const; - reference operator*() const; - pointer operator->() const; - -private: - friend class path; - impl_string_type::const_iterator increment(const impl_string_type::const_iterator& pos) const; - impl_string_type::const_iterator decrement(const impl_string_type::const_iterator& pos) const; - void updateCurrent(); - impl_string_type::const_iterator _first; - impl_string_type::const_iterator _last; - impl_string_type::const_iterator _prefix; - impl_string_type::const_iterator _root; - impl_string_type::const_iterator _iter; - path _current; -}; - -struct space_info -{ - uintmax_t capacity; - uintmax_t free; - uintmax_t available; -}; - -// [fs.enum] enumerations -// [fs.enum.file_type] -enum class file_type { - none, - not_found, - regular, - directory, - symlink, - block, - character, - fifo, - socket, - unknown, -}; - -// [fs.enum.perms] -enum class perms : uint16_t { - none = 0, - - owner_read = 0400, - owner_write = 0200, - owner_exec = 0100, - owner_all = 0700, - - group_read = 040, - group_write = 020, - group_exec = 010, - group_all = 070, - - others_read = 04, - others_write = 02, - others_exec = 01, - others_all = 07, - - all = 0777, - set_uid = 04000, - set_gid = 02000, - sticky_bit = 01000, - - mask = 07777, - unknown = 0xffff -}; - -// [fs.enum.perm.opts] -enum class perm_options : uint16_t { - replace = 3, - add = 1, - remove = 2, - nofollow = 4, -}; - -// [fs.enum.copy.opts] -enum class copy_options : uint16_t { - none = 0, - - skip_existing = 1, - overwrite_existing = 2, - update_existing = 4, - - recursive = 8, - - copy_symlinks = 0x10, - skip_symlinks = 0x20, - - directories_only = 0x40, - create_symlinks = 0x80, -#ifndef GHC_OS_WEB - create_hard_links = 0x100 -#endif -}; - -// [fs.enum.dir.opts] -enum class directory_options : uint16_t { - none = 0, - follow_directory_symlink = 1, - skip_permission_denied = 2, -}; - -// [fs.class.file_status] class file_status -class GHC_FS_API_CLASS file_status -{ -public: - // [fs.file_status.cons] constructors and destructor - file_status() noexcept; - explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; - file_status(const file_status&) noexcept; - file_status(file_status&&) noexcept; - ~file_status(); - // assignments: - file_status& operator=(const file_status&) noexcept; - file_status& operator=(file_status&&) noexcept; - // [fs.file_status.mods] modifiers - void type(file_type ft) noexcept; - void permissions(perms prms) noexcept; - // [fs.file_status.obs] observers - file_type type() const noexcept; - perms permissions() const noexcept; - friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } - -private: - file_type _type; - perms _perms; -}; - -using file_time_type = std::chrono::time_point; - -// [fs.class.directory_entry] Class directory_entry -class GHC_FS_API_CLASS directory_entry -{ -public: - // [fs.dir.entry.cons] constructors and destructor - directory_entry() noexcept = default; - directory_entry(const directory_entry&) = default; - directory_entry(directory_entry&&) noexcept = default; -#ifdef GHC_WITH_EXCEPTIONS - explicit directory_entry(const path& p); -#endif - directory_entry(const path& p, std::error_code& ec); - ~directory_entry(); - - // assignments: - directory_entry& operator=(const directory_entry&) = default; - directory_entry& operator=(directory_entry&&) noexcept = default; - - // [fs.dir.entry.mods] modifiers -#ifdef GHC_WITH_EXCEPTIONS - void assign(const path& p); - void replace_filename(const path& p); - void refresh(); -#endif - void assign(const path& p, std::error_code& ec); - void replace_filename(const path& p, std::error_code& ec); - void refresh(std::error_code& ec) noexcept; - - // [fs.dir.entry.obs] observers - const filesystem::path& path() const noexcept; - operator const filesystem::path&() const noexcept; -#ifdef GHC_WITH_EXCEPTIONS - bool exists() const; - bool is_block_file() const; - bool is_character_file() const; - bool is_directory() const; - bool is_fifo() const; - bool is_other() const; - bool is_regular_file() const; - bool is_socket() const; - bool is_symlink() const; - uintmax_t file_size() const; - file_time_type last_write_time() const; - file_status status() const; - file_status symlink_status() const; -#endif - bool exists(std::error_code& ec) const noexcept; - bool is_block_file(std::error_code& ec) const noexcept; - bool is_character_file(std::error_code& ec) const noexcept; - bool is_directory(std::error_code& ec) const noexcept; - bool is_fifo(std::error_code& ec) const noexcept; - bool is_other(std::error_code& ec) const noexcept; - bool is_regular_file(std::error_code& ec) const noexcept; - bool is_socket(std::error_code& ec) const noexcept; - bool is_symlink(std::error_code& ec) const noexcept; - uintmax_t file_size(std::error_code& ec) const noexcept; - file_time_type last_write_time(std::error_code& ec) const noexcept; - file_status status(std::error_code& ec) const noexcept; - file_status symlink_status(std::error_code& ec) const noexcept; - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS - uintmax_t hard_link_count() const; -#endif - uintmax_t hard_link_count(std::error_code& ec) const noexcept; -#endif - -#ifdef GHC_HAS_THREEWAY_COMP - std::strong_ordering operator<=>(const directory_entry& rhs) const noexcept; -#endif - bool operator<(const directory_entry& rhs) const noexcept; - bool operator==(const directory_entry& rhs) const noexcept; - bool operator!=(const directory_entry& rhs) const noexcept; - bool operator<=(const directory_entry& rhs) const noexcept; - bool operator>(const directory_entry& rhs) const noexcept; - bool operator>=(const directory_entry& rhs) const noexcept; - -private: - friend class directory_iterator; -#ifdef GHC_WITH_EXCEPTIONS - file_type status_file_type() const; -#endif - file_type status_file_type(std::error_code& ec) const noexcept; - filesystem::path _path; - file_status _status; - file_status _symlink_status; - uintmax_t _file_size = static_cast(-1); -#ifndef GHC_OS_WINDOWS - uintmax_t _hard_link_count = static_cast(-1); -#endif - time_t _last_write_time = 0; -}; - -// [fs.class.directory.iterator] Class directory_iterator -class GHC_FS_API_CLASS directory_iterator -{ -public: - class GHC_FS_API_CLASS proxy - { - public: - const directory_entry& operator*() const& noexcept { return _dir_entry; } - directory_entry operator*() && noexcept { return std::move(_dir_entry); } - - private: - explicit proxy(const directory_entry& dir_entry) - : _dir_entry(dir_entry) - { - } - friend class directory_iterator; - friend class recursive_directory_iterator; - directory_entry _dir_entry; - }; - using iterator_category = std::input_iterator_tag; - using value_type = directory_entry; - using difference_type = std::ptrdiff_t; - using pointer = const directory_entry*; - using reference = const directory_entry&; - - // [fs.dir.itr.members] member functions - directory_iterator() noexcept; -#ifdef GHC_WITH_EXCEPTIONS - explicit directory_iterator(const path& p); - directory_iterator(const path& p, directory_options options); -#endif - directory_iterator(const path& p, std::error_code& ec) noexcept; - directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept; - directory_iterator(const directory_iterator& rhs); - directory_iterator(directory_iterator&& rhs) noexcept; - ~directory_iterator(); - directory_iterator& operator=(const directory_iterator& rhs); - directory_iterator& operator=(directory_iterator&& rhs) noexcept; - const directory_entry& operator*() const; - const directory_entry* operator->() const; -#ifdef GHC_WITH_EXCEPTIONS - directory_iterator& operator++(); -#endif - directory_iterator& increment(std::error_code& ec) noexcept; - - // other members as required by [input.iterators] -#ifdef GHC_WITH_EXCEPTIONS - proxy operator++(int) - { - proxy p{**this}; - ++*this; - return p; - } -#endif - bool operator==(const directory_iterator& rhs) const; - bool operator!=(const directory_iterator& rhs) const; - -private: - friend class recursive_directory_iterator; - class impl; - std::shared_ptr _impl; -}; - -// [fs.dir.itr.nonmembers] directory_iterator non-member functions -GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept; -GHC_FS_API directory_iterator end(const directory_iterator&) noexcept; - -// [fs.class.re.dir.itr] class recursive_directory_iterator -class GHC_FS_API_CLASS recursive_directory_iterator -{ -public: - using iterator_category = std::input_iterator_tag; - using value_type = directory_entry; - using difference_type = std::ptrdiff_t; - using pointer = const directory_entry*; - using reference = const directory_entry&; - - // [fs.rec.dir.itr.members] constructors and destructor - recursive_directory_iterator() noexcept; -#ifdef GHC_WITH_EXCEPTIONS - explicit recursive_directory_iterator(const path& p); - recursive_directory_iterator(const path& p, directory_options options); -#endif - recursive_directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept; - recursive_directory_iterator(const path& p, std::error_code& ec) noexcept; - recursive_directory_iterator(const recursive_directory_iterator& rhs); - recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; - ~recursive_directory_iterator(); - - // [fs.rec.dir.itr.members] observers - directory_options options() const; - int depth() const; - bool recursion_pending() const; - - const directory_entry& operator*() const; - const directory_entry* operator->() const; - - // [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& - recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs); - recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept; -#ifdef GHC_WITH_EXCEPTIONS - recursive_directory_iterator& operator++(); -#endif - recursive_directory_iterator& increment(std::error_code& ec) noexcept; - -#ifdef GHC_WITH_EXCEPTIONS - void pop(); -#endif - void pop(std::error_code& ec); - void disable_recursion_pending(); - - // other members as required by [input.iterators] -#ifdef GHC_WITH_EXCEPTIONS - directory_iterator::proxy operator++(int) - { - directory_iterator::proxy proxy{**this}; - ++*this; - return proxy; - } -#endif - bool operator==(const recursive_directory_iterator& rhs) const; - bool operator!=(const recursive_directory_iterator& rhs) const; - -private: - struct recursive_directory_iterator_impl - { - directory_options _options; - bool _recursion_pending; - std::stack _dir_iter_stack; - recursive_directory_iterator_impl(directory_options options, bool recursion_pending) - : _options(options) - , _recursion_pending(recursion_pending) - { - } - }; - std::shared_ptr _impl; -}; - -// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions -GHC_FS_API recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; -GHC_FS_API recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; - -// [fs.op.funcs] filesystem operations -#ifdef GHC_WITH_EXCEPTIONS -GHC_FS_API path absolute(const path& p); -GHC_FS_API path canonical(const path& p); -GHC_FS_API void copy(const path& from, const path& to); -GHC_FS_API void copy(const path& from, const path& to, copy_options options); -GHC_FS_API bool copy_file(const path& from, const path& to); -GHC_FS_API bool copy_file(const path& from, const path& to, copy_options option); -GHC_FS_API void copy_symlink(const path& existing_symlink, const path& new_symlink); -GHC_FS_API bool create_directories(const path& p); -GHC_FS_API bool create_directory(const path& p); -GHC_FS_API bool create_directory(const path& p, const path& attributes); -GHC_FS_API void create_directory_symlink(const path& to, const path& new_symlink); -GHC_FS_API void create_symlink(const path& to, const path& new_symlink); -GHC_FS_API path current_path(); -GHC_FS_API void current_path(const path& p); -GHC_FS_API bool exists(const path& p); -GHC_FS_API bool equivalent(const path& p1, const path& p2); -GHC_FS_API uintmax_t file_size(const path& p); -GHC_FS_API bool is_block_file(const path& p); -GHC_FS_API bool is_character_file(const path& p); -GHC_FS_API bool is_directory(const path& p); -GHC_FS_API bool is_empty(const path& p); -GHC_FS_API bool is_fifo(const path& p); -GHC_FS_API bool is_other(const path& p); -GHC_FS_API bool is_regular_file(const path& p); -GHC_FS_API bool is_socket(const path& p); -GHC_FS_API bool is_symlink(const path& p); -GHC_FS_API file_time_type last_write_time(const path& p); -GHC_FS_API void last_write_time(const path& p, file_time_type new_time); -GHC_FS_API void permissions(const path& p, perms prms, perm_options opts = perm_options::replace); -GHC_FS_API path proximate(const path& p, const path& base = current_path()); -GHC_FS_API path read_symlink(const path& p); -GHC_FS_API path relative(const path& p, const path& base = current_path()); -GHC_FS_API bool remove(const path& p); -GHC_FS_API uintmax_t remove_all(const path& p); -GHC_FS_API void rename(const path& from, const path& to); -GHC_FS_API void resize_file(const path& p, uintmax_t size); -GHC_FS_API space_info space(const path& p); -GHC_FS_API file_status status(const path& p); -GHC_FS_API file_status symlink_status(const path& p); -GHC_FS_API path temp_directory_path(); -GHC_FS_API path weakly_canonical(const path& p); -#endif -GHC_FS_API path absolute(const path& p, std::error_code& ec); -GHC_FS_API path canonical(const path& p, std::error_code& ec); -GHC_FS_API void copy(const path& from, const path& to, std::error_code& ec) noexcept; -GHC_FS_API void copy(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept; -GHC_FS_API bool copy_file(const path& from, const path& to, std::error_code& ec) noexcept; -GHC_FS_API bool copy_file(const path& from, const path& to, copy_options option, std::error_code& ec) noexcept; -GHC_FS_API void copy_symlink(const path& existing_symlink, const path& new_symlink, std::error_code& ec) noexcept; -GHC_FS_API bool create_directories(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool create_directory(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool create_directory(const path& p, const path& attributes, std::error_code& ec) noexcept; -GHC_FS_API void create_directory_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept; -GHC_FS_API void create_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept; -GHC_FS_API path current_path(std::error_code& ec); -GHC_FS_API void current_path(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool exists(file_status s) noexcept; -GHC_FS_API bool exists(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool equivalent(const path& p1, const path& p2, std::error_code& ec) noexcept; -GHC_FS_API uintmax_t file_size(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_block_file(file_status s) noexcept; -GHC_FS_API bool is_block_file(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_character_file(file_status s) noexcept; -GHC_FS_API bool is_character_file(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_directory(file_status s) noexcept; -GHC_FS_API bool is_directory(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_empty(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_fifo(file_status s) noexcept; -GHC_FS_API bool is_fifo(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_other(file_status s) noexcept; -GHC_FS_API bool is_other(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_regular_file(file_status s) noexcept; -GHC_FS_API bool is_regular_file(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_socket(file_status s) noexcept; -GHC_FS_API bool is_socket(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool is_symlink(file_status s) noexcept; -GHC_FS_API bool is_symlink(const path& p, std::error_code& ec) noexcept; -GHC_FS_API file_time_type last_write_time(const path& p, std::error_code& ec) noexcept; -GHC_FS_API void last_write_time(const path& p, file_time_type new_time, std::error_code& ec) noexcept; -GHC_FS_API void permissions(const path& p, perms prms, std::error_code& ec) noexcept; -GHC_FS_API void permissions(const path& p, perms prms, perm_options opts, std::error_code& ec) noexcept; -GHC_FS_API path proximate(const path& p, std::error_code& ec); -GHC_FS_API path proximate(const path& p, const path& base, std::error_code& ec); -GHC_FS_API path read_symlink(const path& p, std::error_code& ec); -GHC_FS_API path relative(const path& p, std::error_code& ec); -GHC_FS_API path relative(const path& p, const path& base, std::error_code& ec); -GHC_FS_API bool remove(const path& p, std::error_code& ec) noexcept; -GHC_FS_API uintmax_t remove_all(const path& p, std::error_code& ec) noexcept; -GHC_FS_API void rename(const path& from, const path& to, std::error_code& ec) noexcept; -GHC_FS_API void resize_file(const path& p, uintmax_t size, std::error_code& ec) noexcept; -GHC_FS_API space_info space(const path& p, std::error_code& ec) noexcept; -GHC_FS_API file_status status(const path& p, std::error_code& ec) noexcept; -GHC_FS_API bool status_known(file_status s) noexcept; -GHC_FS_API file_status symlink_status(const path& p, std::error_code& ec) noexcept; -GHC_FS_API path temp_directory_path(std::error_code& ec) noexcept; -GHC_FS_API path weakly_canonical(const path& p, std::error_code& ec) noexcept; - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_FS_API void create_hard_link(const path& to, const path& new_hard_link); -GHC_FS_API uintmax_t hard_link_count(const path& p); -#endif -GHC_FS_API void create_hard_link(const path& to, const path& new_hard_link, std::error_code& ec) noexcept; -GHC_FS_API uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept; -#endif - -#if defined(GHC_OS_WINDOWS) && (!defined(__GLIBCXX__) || (defined(_GLIBCXX_HAVE__WFOPEN) && defined(_GLIBCXX_USE_WCHAR_T))) -#define GHC_HAS_FSTREAM_OPEN_WITH_WCHAR -#endif - -// Non-C++17 add-on std::fstream wrappers with path -template > -class basic_filebuf : public std::basic_filebuf -{ -public: - basic_filebuf() {} - ~basic_filebuf() override {} - basic_filebuf(const basic_filebuf&) = delete; - const basic_filebuf& operator=(const basic_filebuf&) = delete; - basic_filebuf* open(const path& p, std::ios_base::openmode mode) - { -#ifdef GHC_HAS_FSTREAM_OPEN_WITH_WCHAR - return std::basic_filebuf::open(p.wstring().c_str(), mode) ? this : 0; -#else - return std::basic_filebuf::open(p.string().c_str(), mode) ? this : 0; -#endif - } -}; - -template > -class basic_ifstream : public std::basic_ifstream -{ -public: - basic_ifstream() {} -#ifdef GHC_HAS_FSTREAM_OPEN_WITH_WCHAR - explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in) - : std::basic_ifstream(p.wstring().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream::open(p.wstring().c_str(), mode); } -#else - explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in) - : std::basic_ifstream(p.string().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream::open(p.string().c_str(), mode); } -#endif - basic_ifstream(const basic_ifstream&) = delete; - const basic_ifstream& operator=(const basic_ifstream&) = delete; - ~basic_ifstream() override {} -}; - -template > -class basic_ofstream : public std::basic_ofstream -{ -public: - basic_ofstream() {} -#ifdef GHC_HAS_FSTREAM_OPEN_WITH_WCHAR - explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out) - : std::basic_ofstream(p.wstring().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream::open(p.wstring().c_str(), mode); } -#else - explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out) - : std::basic_ofstream(p.string().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream::open(p.string().c_str(), mode); } -#endif - basic_ofstream(const basic_ofstream&) = delete; - const basic_ofstream& operator=(const basic_ofstream&) = delete; - ~basic_ofstream() override {} -}; - -template > -class basic_fstream : public std::basic_fstream -{ -public: - basic_fstream() {} -#ifdef GHC_HAS_FSTREAM_OPEN_WITH_WCHAR - explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) - : std::basic_fstream(p.wstring().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream::open(p.wstring().c_str(), mode); } -#else - explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) - : std::basic_fstream(p.string().c_str(), mode) - { - } - void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream::open(p.string().c_str(), mode); } -#endif - basic_fstream(const basic_fstream&) = delete; - const basic_fstream& operator=(const basic_fstream&) = delete; - ~basic_fstream() override {} -}; - -typedef basic_filebuf filebuf; -typedef basic_filebuf wfilebuf; -typedef basic_ifstream ifstream; -typedef basic_ifstream wifstream; -typedef basic_ofstream ofstream; -typedef basic_ofstream wofstream; -typedef basic_fstream fstream; -typedef basic_fstream wfstream; - -class GHC_FS_API_CLASS u8arguments -{ -public: - u8arguments(int& argc, char**& argv); - ~u8arguments() - { - _refargc = _argc; - _refargv = _argv; - } - - bool valid() const { return _isvalid; } - -private: - int _argc; - char** _argv; - int& _refargc; - char**& _refargv; - bool _isvalid; -#ifdef GHC_OS_WINDOWS - std::vector _args; - std::vector _argp; -#endif -}; - -//------------------------------------------------------------------------------------------------- -// Implementation -//------------------------------------------------------------------------------------------------- - -namespace detail { -enum utf8_states_t { S_STRT = 0, S_RJCT = 8 }; -GHC_FS_API void appendUTF8(std::string& str, uint32_t unicode); -GHC_FS_API bool is_surrogate(uint32_t c); -GHC_FS_API bool is_high_surrogate(uint32_t c); -GHC_FS_API bool is_low_surrogate(uint32_t c); -GHC_FS_API unsigned consumeUtf8Fragment(const unsigned state, const uint8_t fragment, uint32_t& codepoint); -enum class portable_error { - none = 0, - exists, - not_found, - not_supported, - not_implemented, - invalid_argument, - is_a_directory, -}; -GHC_FS_API std::error_code make_error_code(portable_error err); -#ifdef GHC_OS_WINDOWS -GHC_FS_API std::error_code make_system_error(uint32_t err = 0); -#else -GHC_FS_API std::error_code make_system_error(int err = 0); - -template -struct has_d_type : std::false_type{}; - -template -struct has_d_type : std::true_type {}; - -template -GHC_INLINE file_type file_type_from_dirent_impl(const T&, std::false_type) -{ - return file_type::none; -} - -template -GHC_INLINE file_type file_type_from_dirent_impl(const T& t, std::true_type) -{ - switch (t.d_type) { -#ifdef DT_BLK - case DT_BLK: - return file_type::block; -#endif -#ifdef DT_CHR - case DT_CHR: - return file_type::character; -#endif -#ifdef DT_DIR - case DT_DIR: - return file_type::directory; -#endif -#ifdef DT_FIFO - case DT_FIFO: - return file_type::fifo; -#endif -#ifdef DT_LNK - case DT_LNK: - return file_type::symlink; -#endif -#ifdef DT_REG - case DT_REG: - return file_type::regular; -#endif -#ifdef DT_SOCK - case DT_SOCK: - return file_type::socket; -#endif -#ifdef DT_UNKNOWN - case DT_UNKNOWN: - return file_type::none; -#endif - default: - return file_type::unknown; - } -} - -template -GHC_INLINE file_type file_type_from_dirent(const T& t) -{ - return file_type_from_dirent_impl(t, has_d_type{}); -} -#endif -} // namespace detail - -namespace detail { - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE std::error_code make_error_code(portable_error err) -{ -#ifdef GHC_OS_WINDOWS - switch (err) { - case portable_error::none: - return std::error_code(); - case portable_error::exists: - return std::error_code(ERROR_ALREADY_EXISTS, std::system_category()); - case portable_error::not_found: - return std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()); - case portable_error::not_supported: - return std::error_code(ERROR_NOT_SUPPORTED, std::system_category()); - case portable_error::not_implemented: - return std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category()); - case portable_error::invalid_argument: - return std::error_code(ERROR_INVALID_PARAMETER, std::system_category()); - case portable_error::is_a_directory: -#ifdef ERROR_DIRECTORY_NOT_SUPPORTED - return std::error_code(ERROR_DIRECTORY_NOT_SUPPORTED, std::system_category()); -#else - return std::error_code(ERROR_NOT_SUPPORTED, std::system_category()); -#endif - } -#else - switch (err) { - case portable_error::none: - return std::error_code(); - case portable_error::exists: - return std::error_code(EEXIST, std::system_category()); - case portable_error::not_found: - return std::error_code(ENOENT, std::system_category()); - case portable_error::not_supported: - return std::error_code(ENOTSUP, std::system_category()); - case portable_error::not_implemented: - return std::error_code(ENOSYS, std::system_category()); - case portable_error::invalid_argument: - return std::error_code(EINVAL, std::system_category()); - case portable_error::is_a_directory: - return std::error_code(EISDIR, std::system_category()); - } -#endif - return std::error_code(); -} - -#ifdef GHC_OS_WINDOWS -GHC_INLINE std::error_code make_system_error(uint32_t err) -{ - return std::error_code(err ? static_cast(err) : static_cast(::GetLastError()), std::system_category()); -} -#else -GHC_INLINE std::error_code make_system_error(int err) -{ - return std::error_code(err ? err : errno, std::system_category()); -} -#endif - -#endif // GHC_EXPAND_IMPL - -template -using EnableBitmask = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value, Enum>::type; -} // namespace detail - -template -constexpr detail::EnableBitmask operator&(Enum X, Enum Y) -{ - using underlying = typename std::underlying_type::type; - return static_cast(static_cast(X) & static_cast(Y)); -} - -template -constexpr detail::EnableBitmask operator|(Enum X, Enum Y) -{ - using underlying = typename std::underlying_type::type; - return static_cast(static_cast(X) | static_cast(Y)); -} - -template -constexpr detail::EnableBitmask operator^(Enum X, Enum Y) -{ - using underlying = typename std::underlying_type::type; - return static_cast(static_cast(X) ^ static_cast(Y)); -} - -template -constexpr detail::EnableBitmask operator~(Enum X) -{ - using underlying = typename std::underlying_type::type; - return static_cast(~static_cast(X)); -} - -template -detail::EnableBitmask& operator&=(Enum& X, Enum Y) -{ - X = X & Y; - return X; -} - -template -detail::EnableBitmask& operator|=(Enum& X, Enum Y) -{ - X = X | Y; - return X; -} - -template -detail::EnableBitmask& operator^=(Enum& X, Enum Y) -{ - X = X ^ Y; - return X; -} - -#ifdef GHC_EXPAND_IMPL - -namespace detail { - -GHC_INLINE bool in_range(uint32_t c, uint32_t lo, uint32_t hi) -{ - return (static_cast(c - lo) < (hi - lo + 1)); -} - -GHC_INLINE bool is_surrogate(uint32_t c) -{ - return in_range(c, 0xd800, 0xdfff); -} - -GHC_INLINE bool is_high_surrogate(uint32_t c) -{ - return (c & 0xfffffc00) == 0xd800; -} - -GHC_INLINE bool is_low_surrogate(uint32_t c) -{ - return (c & 0xfffffc00) == 0xdc00; -} - -GHC_INLINE void appendUTF8(std::string& str, uint32_t unicode) -{ - if (unicode <= 0x7f) { - str.push_back(static_cast(unicode)); - } - else if (unicode >= 0x80 && unicode <= 0x7ff) { - str.push_back(static_cast((unicode >> 6) + 192)); - str.push_back(static_cast((unicode & 0x3f) + 128)); - } - else if ((unicode >= 0x800 && unicode <= 0xd7ff) || (unicode >= 0xe000 && unicode <= 0xffff)) { - str.push_back(static_cast((unicode >> 12) + 224)); - str.push_back(static_cast(((unicode & 0xfff) >> 6) + 128)); - str.push_back(static_cast((unicode & 0x3f) + 128)); - } - else if (unicode >= 0x10000 && unicode <= 0x10ffff) { - str.push_back(static_cast((unicode >> 18) + 240)); - str.push_back(static_cast(((unicode & 0x3ffff) >> 12) + 128)); - str.push_back(static_cast(((unicode & 0xfff) >> 6) + 128)); - str.push_back(static_cast((unicode & 0x3f) + 128)); - } - else { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal code point for unicode character.", str, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - appendUTF8(str, 0xfffd); -#endif - } -} - -// Thanks to Bjoern Hoehrmann (https://bjoern.hoehrmann.de/utf-8/decoder/dfa/) -// and Taylor R Campbell for the ideas to this DFA approach of UTF-8 decoding; -// Generating debugging and shrinking my own DFA from scratch was a day of fun! -GHC_INLINE unsigned consumeUtf8Fragment(const unsigned state, const uint8_t fragment, uint32_t& codepoint) -{ - static const uint32_t utf8_state_info[] = { - // encoded states - 0x11111111u, 0x11111111u, 0x77777777u, 0x77777777u, 0x88888888u, 0x88888888u, 0x88888888u, 0x88888888u, 0x22222299u, 0x22222222u, 0x22222222u, 0x22222222u, 0x3333333au, 0x33433333u, 0x9995666bu, 0x99999999u, - 0x88888880u, 0x22818108u, 0x88888881u, 0x88888882u, 0x88888884u, 0x88888887u, 0x88888886u, 0x82218108u, 0x82281108u, 0x88888888u, 0x88888883u, 0x88888885u, 0u, 0u, 0u, 0u, - }; - uint8_t category = fragment < 128 ? 0 : (utf8_state_info[(fragment >> 3) & 0xf] >> ((fragment & 7) << 2)) & 0xf; - codepoint = (state ? (codepoint << 6) | (fragment & 0x3fu) : (0xffu >> category) & fragment); - return state == S_RJCT ? static_cast(S_RJCT) : static_cast((utf8_state_info[category + 16] >> (state << 2)) & 0xf); -} - -GHC_INLINE bool validUtf8(const std::string& utf8String) -{ - std::string::const_iterator iter = utf8String.begin(); - unsigned utf8_state = S_STRT; - std::uint32_t codepoint = 0; - while (iter < utf8String.end()) { - if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_RJCT) { - return false; - } - } - if (utf8_state) { - return false; - } - return true; -} - -} // namespace detail - -#endif - -namespace detail { - -template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 1)>::type* = nullptr> -inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - return StringType(utf8String.begin(), utf8String.end(), alloc); -} - -template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 2)>::type* = nullptr> -inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - StringType result(alloc); - result.reserve(utf8String.length()); - auto iter = utf8String.cbegin(); - unsigned utf8_state = S_STRT; - std::uint32_t codepoint = 0; - while (iter < utf8String.cend()) { - if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_STRT) { - if (codepoint <= 0xffff) { - result += static_cast(codepoint); - } - else { - codepoint -= 0x10000; - result += static_cast((codepoint >> 10) + 0xd800); - result += static_cast((codepoint & 0x3ff) + 0xdc00); - } - codepoint = 0; - } - else if (utf8_state == S_RJCT) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); - utf8_state = S_STRT; - codepoint = 0; -#endif - } - } - if (utf8_state) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); -#endif - } - return result; -} - -template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 4)>::type* = nullptr> -inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - StringType result(alloc); - result.reserve(utf8String.length()); - auto iter = utf8String.cbegin(); - unsigned utf8_state = S_STRT; - std::uint32_t codepoint = 0; - while (iter < utf8String.cend()) { - if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_STRT) { - result += static_cast(codepoint); - codepoint = 0; - } - else if (utf8_state == S_RJCT) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); - utf8_state = S_STRT; - codepoint = 0; -#endif - } - } - if (utf8_state) { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - result += static_cast(0xfffd); -#endif - } - return result; -} - -template -inline StringType fromUtf8(const charT (&utf8String)[N]) -{ -#ifdef GHC_WITH_STRING_VIEW - return fromUtf8(basic_string_view(utf8String, N - 1)); -#else - return fromUtf8(std::basic_string(utf8String, N - 1)); -#endif -} - -template ::value && (sizeof(typename strT::value_type) == 1), int>::type size = 1> -inline std::string toUtf8(const strT& unicodeString) -{ - return std::string(unicodeString.begin(), unicodeString.end()); -} - -template ::value && (sizeof(typename strT::value_type) == 2), int>::type size = 2> -inline std::string toUtf8(const strT& unicodeString) -{ - std::string result; - for (auto iter = unicodeString.begin(); iter != unicodeString.end(); ++iter) { - char32_t c = *iter; - if (is_surrogate(c)) { - ++iter; - if (iter != unicodeString.end() && is_high_surrogate(c) && is_low_surrogate(*iter)) { - appendUTF8(result, (char32_t(c) << 10) + *iter - 0x35fdc00); - } - else { -#ifdef GHC_RAISE_UNICODE_ERRORS - throw filesystem_error("Illegal code point for unicode character.", result, std::make_error_code(std::errc::illegal_byte_sequence)); -#else - appendUTF8(result, 0xfffd); - if (iter == unicodeString.end()) { - break; - } -#endif - } - } - else { - appendUTF8(result, c); - } - } - return result; -} - -template ::value && (sizeof(typename strT::value_type) == 4), int>::type size = 4> -inline std::string toUtf8(const strT& unicodeString) -{ - std::string result; - for (auto c : unicodeString) { - appendUTF8(result, static_cast(c)); - } - return result; -} - -template -inline std::string toUtf8(const charT* unicodeString) -{ -#ifdef GHC_WITH_STRING_VIEW - return toUtf8(basic_string_view>(unicodeString)); -#else - return toUtf8(std::basic_string>(unicodeString)); -#endif -} - -#ifdef GHC_USE_WCHAR_T -template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 1), bool>::type = false> -inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - auto temp = toUtf8(wString); - return StringType(temp.begin(), temp.end(), alloc); -} - -template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 2), bool>::type = false> -inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - return StringType(wString.begin(), wString.end(), alloc); -} - -template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 4), bool>::type = false> -inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) -{ - auto temp = toUtf8(wString); - return fromUtf8(temp, alloc); -} - -template ::value && (sizeof(typename strT::value_type) == 1), bool>::type = false> -inline std::wstring toWChar(const strT& unicodeString) -{ - return fromUtf8(unicodeString); -} - -template ::value && (sizeof(typename strT::value_type) == 2), bool>::type = false> -inline std::wstring toWChar(const strT& unicodeString) -{ - return std::wstring(unicodeString.begin(), unicodeString.end()); -} - -template ::value && (sizeof(typename strT::value_type) == 4), bool>::type = false> -inline std::wstring toWChar(const strT& unicodeString) -{ - auto temp = toUtf8(unicodeString); - return fromUtf8(temp); -} - -template -inline std::wstring toWChar(const charT* unicodeString) -{ -#ifdef GHC_WITH_STRING_VIEW - return toWChar(basic_string_view>(unicodeString)); -#else - return toWChar(std::basic_string>(unicodeString)); -#endif -} -#endif // GHC_USE_WCHAR_T - -} // namespace detail - -#ifdef GHC_EXPAND_IMPL - -namespace detail { - -template ::value, bool>::type = true> -GHC_INLINE bool startsWith(const strT& what, const strT& with) -{ - return with.length() <= what.length() && equal(with.begin(), with.end(), what.begin()); -} - -template ::value, bool>::type = true> -GHC_INLINE bool endsWith(const strT& what, const strT& with) -{ - return with.length() <= what.length() && what.compare(what.length() - with.length(), with.size(), with) == 0; -} - -} // namespace detail - -GHC_INLINE void path::check_long_path() -{ -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - if (is_absolute() && _path.length() >= MAX_PATH - 12 && !detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\")))) { - postprocess_path_with_format(native_format); - } -#endif -} - -GHC_INLINE void path::postprocess_path_with_format(path::format fmt) -{ -#ifdef GHC_RAISE_UNICODE_ERRORS - if (!detail::validUtf8(_path)) { - path t; - t._path = _path; - throw filesystem_error("Illegal byte sequence for unicode character.", t, std::make_error_code(std::errc::illegal_byte_sequence)); - } -#endif - switch (fmt) { -#ifdef GHC_OS_WINDOWS - case path::native_format: - case path::auto_format: - case path::generic_format: - for (auto& c : _path) { - if (c == generic_separator) { - c = preferred_separator; - } - } -#ifdef GHC_WIN_AUTO_PREFIX_LONG_PATH - if (is_absolute() && _path.length() >= MAX_PATH - 12 && !detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\")))) { - _path = GHC_PLATFORM_LITERAL("\\\\?\\") + _path; - } -#endif - handle_prefixes(); - break; -#else - case path::auto_format: - case path::native_format: - case path::generic_format: - // nothing to do - break; -#endif - } - if (_path.length() > _prefixLength + 2 && _path[_prefixLength] == preferred_separator && _path[_prefixLength + 1] == preferred_separator && _path[_prefixLength + 2] != preferred_separator) { - impl_string_type::iterator new_end = std::unique(_path.begin() + static_cast(_prefixLength) + 2, _path.end(), [](path::value_type lhs, path::value_type rhs) { return lhs == rhs && lhs == preferred_separator; }); - _path.erase(new_end, _path.end()); - } - else { - impl_string_type::iterator new_end = std::unique(_path.begin() + static_cast(_prefixLength), _path.end(), [](path::value_type lhs, path::value_type rhs) { return lhs == rhs && lhs == preferred_separator; }); - _path.erase(new_end, _path.end()); - } -} - -#endif // GHC_EXPAND_IMPL - -template -inline path::path(const Source& source, format fmt) -#ifdef GHC_USE_WCHAR_T - : _path(detail::toWChar(source)) -#else - : _path(detail::toUtf8(source)) -#endif -{ - postprocess_path_with_format(fmt); -} - -template -inline path u8path(const Source& source) -{ - return path(source); -} -template -inline path u8path(InputIterator first, InputIterator last) -{ - return path(first, last); -} - -template -inline path::path(InputIterator first, InputIterator last, format fmt) - : path(std::basic_string::value_type>(first, last), fmt) -{ - // delegated -} - -#ifdef GHC_EXPAND_IMPL - -namespace detail { - -GHC_INLINE bool equals_simple_insensitive(const path::value_type* str1, const path::value_type* str2) -{ -#ifdef GHC_OS_WINDOWS -#ifdef __GNUC__ - while (::tolower((unsigned char)*str1) == ::tolower((unsigned char)*str2++)) { - if (*str1++ == 0) - return true; - } - return false; -#else // __GNUC__ -#ifdef GHC_USE_WCHAR_T - return 0 == ::_wcsicmp(str1, str2); -#else // GHC_USE_WCHAR_T - return 0 == ::_stricmp(str1, str2); -#endif // GHC_USE_WCHAR_T -#endif // __GNUC__ -#else // GHC_OS_WINDOWS - return 0 == ::strcasecmp(str1, str2); -#endif // GHC_OS_WINDOWS -} - -GHC_INLINE int compare_simple_insensitive(const path::value_type* str1, size_t len1, const path::value_type* str2, size_t len2) -{ - while (len1 > 0 && len2 > 0 && ::tolower(static_cast(*str1)) == ::tolower(static_cast(*str2))) { - --len1; - --len2; - ++str1; - ++str2; - } - if (len1 && len2) { - return *str1 < *str2 ? -1 : 1; - } - if (len1 == 0 && len2 == 0) { - return 0; - } - return len1 == 0 ? -1 : 1; -} - -GHC_INLINE const char* strerror_adapter(char* gnu, char*) -{ - return gnu; -} - -GHC_INLINE const char* strerror_adapter(int posix, char* buffer) -{ - if (posix) { - return "Error in strerror_r!"; - } - return buffer; -} - -template -GHC_INLINE std::string systemErrorText(ErrorNumber code = 0) -{ -#if defined(GHC_OS_WINDOWS) - LPVOID msgBuf; - DWORD dw = code ? static_cast(code) : ::GetLastError(); - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&msgBuf, 0, NULL); - std::string msg = toUtf8(std::wstring((LPWSTR)msgBuf)); - LocalFree(msgBuf); - return msg; -#else - char buffer[512]; - return strerror_adapter(strerror_r(code ? code : errno, buffer, sizeof(buffer)), buffer); -#endif -} - -#ifdef GHC_OS_WINDOWS -using CreateSymbolicLinkW_fp = BOOLEAN(WINAPI*)(LPCWSTR, LPCWSTR, DWORD); -using CreateHardLinkW_fp = BOOLEAN(WINAPI*)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); - -GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink, bool to_directory, std::error_code& ec) -{ - std::error_code tec; - auto fs = status(target_name, tec); - if ((fs.type() == file_type::directory && !to_directory) || (fs.type() == file_type::regular && to_directory)) { - ec = detail::make_error_code(detail::portable_error::not_supported); - return; - } -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) -#pragma warning(push) -#pragma warning(disable : 4191) -#endif - static CreateSymbolicLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateSymbolicLinkW")); -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic pop -#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) -#pragma warning(pop) -#endif - if (api_call) { - if (api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 1 : 0) == 0) { - auto result = ::GetLastError(); - if (result == ERROR_PRIVILEGE_NOT_HELD && api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 3 : 2) != 0) { - return; - } - ec = detail::make_system_error(result); - } - } - else { - ec = detail::make_system_error(ERROR_NOT_SUPPORTED); - } -} - -GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlink, std::error_code& ec) -{ -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) -#pragma warning(push) -#pragma warning(disable : 4191) -#endif - static CreateHardLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW")); -#if defined(__GNUC__) && __GNUC__ >= 8 -#pragma GCC diagnostic pop -#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__clang__) -#pragma warning(pop) -#endif - if (api_call) { - if (api_call(GHC_NATIVEWP(new_hardlink), GHC_NATIVEWP(target_name), NULL) == 0) { - ec = detail::make_system_error(); - } - } - else { - ec = detail::make_system_error(ERROR_NOT_SUPPORTED); - } -} - -GHC_INLINE path getFullPathName(const wchar_t* p, std::error_code& ec) -{ - ULONG size = ::GetFullPathNameW(p, 0, 0, 0); - if (size) { - std::vector buf(size, 0); - ULONG s2 = GetFullPathNameW(p, size, buf.data(), nullptr); - if (s2 && s2 < size) { - return path(std::wstring(buf.data(), s2)); - } - } - ec = detail::make_system_error(); - return path(); -} - -#else -GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink, bool, std::error_code& ec) -{ - if (::symlink(target_name.c_str(), new_symlink.c_str()) != 0) { - ec = detail::make_system_error(); - } -} - -#ifndef GHC_OS_WEB -GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlink, std::error_code& ec) -{ - if (::link(target_name.c_str(), new_hardlink.c_str()) != 0) { - ec = detail::make_system_error(); - } -} -#endif -#endif - -template -GHC_INLINE file_status file_status_from_st_mode(T mode) -{ -#ifdef GHC_OS_WINDOWS - file_type ft = file_type::unknown; - if ((mode & _S_IFDIR) == _S_IFDIR) { - ft = file_type::directory; - } - else if ((mode & _S_IFREG) == _S_IFREG) { - ft = file_type::regular; - } - else if ((mode & _S_IFCHR) == _S_IFCHR) { - ft = file_type::character; - } - perms prms = static_cast(mode & 0xfff); - return file_status(ft, prms); -#else - file_type ft = file_type::unknown; - if (S_ISDIR(mode)) { - ft = file_type::directory; - } - else if (S_ISREG(mode)) { - ft = file_type::regular; - } - else if (S_ISCHR(mode)) { - ft = file_type::character; - } - else if (S_ISBLK(mode)) { - ft = file_type::block; - } - else if (S_ISFIFO(mode)) { - ft = file_type::fifo; - } - else if (S_ISLNK(mode)) { - ft = file_type::symlink; - } - else if (S_ISSOCK(mode)) { - ft = file_type::socket; - } - perms prms = static_cast(mode & 0xfff); - return file_status(ft, prms); -#endif -} - -#ifdef GHC_OS_WINDOWS - -class unique_handle -{ -public: - typedef HANDLE element_type; - - unique_handle() noexcept - : _handle(INVALID_HANDLE_VALUE) - { - } - explicit unique_handle(element_type h) noexcept - : _handle(h) - { - } - unique_handle(unique_handle&& u) noexcept - : _handle(u.release()) - { - } - ~unique_handle() { reset(); } - unique_handle& operator=(unique_handle&& u) noexcept - { - reset(u.release()); - return *this; - } - element_type get() const noexcept { return _handle; } - explicit operator bool() const noexcept { return _handle != INVALID_HANDLE_VALUE; } - element_type release() noexcept - { - element_type tmp = _handle; - _handle = INVALID_HANDLE_VALUE; - return tmp; - } - void reset(element_type h = INVALID_HANDLE_VALUE) noexcept - { - element_type tmp = _handle; - _handle = h; - if (tmp != INVALID_HANDLE_VALUE) { - CloseHandle(tmp); - } - } - void swap(unique_handle& u) noexcept { std::swap(_handle, u._handle); } - -private: - element_type _handle; -}; - -#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE -typedef struct _REPARSE_DATA_BUFFER -{ - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union - { - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct - { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; -} REPARSE_DATA_BUFFER; -#ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE -#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024) -#endif -#endif - -template -struct free_deleter -{ - void operator()(T* p) const { std::free(p); } -}; - -GHC_INLINE std::unique_ptr> getReparseData(const path& p, std::error_code& ec) -{ - unique_handle file(CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0)); - if (!file) { - ec = detail::make_system_error(); - return nullptr; - } - - std::unique_ptr> reparseData(reinterpret_cast(std::calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE))); - ULONG bufferUsed; - if (DeviceIoControl(file.get(), FSCTL_GET_REPARSE_POINT, 0, 0, reparseData.get(), MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bufferUsed, 0)) { - return reparseData; - } - else { - ec = detail::make_system_error(); - } - return nullptr; -} -#endif - -GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec) -{ -#ifdef GHC_OS_WINDOWS - path result; - auto reparseData = detail::getReparseData(p, ec); - if (!ec) { - if (reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag)) { - switch (reparseData->ReparseTag) { - case IO_REPARSE_TAG_SYMLINK: { - auto printName = std::wstring(&reparseData->SymbolicLinkReparseBuffer.PathBuffer[reparseData->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], reparseData->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR)); - auto substituteName = - std::wstring(&reparseData->SymbolicLinkReparseBuffer.PathBuffer[reparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], reparseData->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); - if (detail::endsWith(substituteName, printName) && detail::startsWith(substituteName, std::wstring(L"\\??\\"))) { - result = printName; - } - else { - result = substituteName; - } - if (reparseData->SymbolicLinkReparseBuffer.Flags & 0x1 /*SYMLINK_FLAG_RELATIVE*/) { - result = p.parent_path() / result; - } - break; - } - case IO_REPARSE_TAG_MOUNT_POINT: - result = detail::getFullPathName(GHC_NATIVEWP(p), ec); - // result = std::wstring(&reparseData->MountPointReparseBuffer.PathBuffer[reparseData->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], reparseData->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); - break; - default: - break; - } - } - } - return result; -#else - size_t bufferSize = 256; - while (true) { - std::vector buffer(bufferSize, static_cast(0)); - auto rc = ::readlink(p.c_str(), buffer.data(), buffer.size()); - if (rc < 0) { - ec = detail::make_system_error(); - return path(); - } - else if (rc < static_cast(bufferSize)) { - return path(std::string(buffer.data(), static_cast(rc))); - } - bufferSize *= 2; - } - return path(); -#endif -} - -#ifdef GHC_OS_WINDOWS -GHC_INLINE time_t timeFromFILETIME(const FILETIME& ft) -{ - ULARGE_INTEGER ull; - ull.LowPart = ft.dwLowDateTime; - ull.HighPart = ft.dwHighDateTime; - return static_cast(ull.QuadPart / 10000000ULL - 11644473600ULL); -} - -GHC_INLINE void timeToFILETIME(time_t t, FILETIME& ft) -{ - ULARGE_INTEGER ull; - ull.QuadPart = static_cast((t * 10000000LL) + 116444736000000000LL); - ft.dwLowDateTime = ull.LowPart; - ft.dwHighDateTime = ull.HighPart; -} - -template -GHC_INLINE uintmax_t hard_links_from_INFO(const INFO* info) -{ - return static_cast(-1); -} - -template <> -GHC_INLINE uintmax_t hard_links_from_INFO(const BY_HANDLE_FILE_INFORMATION* info) -{ - return info->nNumberOfLinks; -} - -template -GHC_INLINE bool is_symlink_from_INFO(const path &p, const INFO* info, std::error_code& ec) -{ - if ((info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - auto reparseData = detail::getReparseData(p, ec); - if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - return true; - } - } - return false; -} - -template <> -GHC_INLINE bool is_symlink_from_INFO(const path &, const WIN32_FIND_DATAW* info, std::error_code&) -{ - // dwReserved0 is undefined unless dwFileAttributes includes the - // FILE_ATTRIBUTE_REPARSE_POINT attribute according to microsoft - // documentation. In practice, dwReserved0 is not reset which - // causes it to report the incorrect symlink status. - // Note that microsoft documentation does not say whether there is - // a null value for dwReserved0, so we test for symlink directly - // instead of returning the tag which requires returning a null - // value for non-reparse-point files. - return (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && info->dwReserved0 == IO_REPARSE_TAG_SYMLINK; -} - -template -GHC_INLINE file_status status_from_INFO(const path& p, const INFO* info, std::error_code& ec, uintmax_t* sz = nullptr, time_t* lwt = nullptr) -{ - file_type ft = file_type::unknown; - if (is_symlink_from_INFO(p, info, ec)) { - ft = file_type::symlink; - } - else if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - ft = file_type::directory; - } - else { - ft = file_type::regular; - } - perms prms = perms::owner_read | perms::group_read | perms::others_read; - if (!(info->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { - prms = prms | perms::owner_write | perms::group_write | perms::others_write; - } - if (has_executable_extension(p)) { - prms = prms | perms::owner_exec | perms::group_exec | perms::others_exec; - } - if (sz) { - *sz = static_cast(info->nFileSizeHigh) << (sizeof(info->nFileSizeHigh) * 8) | info->nFileSizeLow; - } - if (lwt) { - *lwt = detail::timeFromFILETIME(info->ftLastWriteTime); - } - return file_status(ft, prms); -} - -#endif - -GHC_INLINE bool is_not_found_error(std::error_code& ec) -{ -#ifdef GHC_OS_WINDOWS - return ec.value() == ERROR_FILE_NOT_FOUND || ec.value() == ERROR_PATH_NOT_FOUND || ec.value() == ERROR_INVALID_NAME; -#else - return ec.value() == ENOENT || ec.value() == ENOTDIR; -#endif -} - -GHC_INLINE file_status symlink_status_ex(const path& p, std::error_code& ec, uintmax_t* sz = nullptr, uintmax_t* nhl = nullptr, time_t* lwt = nullptr) noexcept -{ -#ifdef GHC_OS_WINDOWS - file_status fs; - WIN32_FILE_ATTRIBUTE_DATA attr; - if (!GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { - ec = detail::make_system_error(); - } - else { - ec.clear(); - fs = detail::status_from_INFO(p, &attr, ec, sz, lwt); - if (nhl) { - *nhl = 0; - } - } - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found); - } - return ec ? file_status(file_type::none) : fs; -#else - (void)sz; - (void)nhl; - (void)lwt; - struct ::stat fs; - auto result = ::lstat(p.c_str(), &fs); - if (result == 0) { - ec.clear(); - file_status f_s = detail::file_status_from_st_mode(fs.st_mode); - return f_s; - } - ec = detail::make_system_error(); - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found, perms::unknown); - } - return file_status(file_type::none); -#endif -} - -GHC_INLINE file_status status_ex(const path& p, std::error_code& ec, file_status* sls = nullptr, uintmax_t* sz = nullptr, uintmax_t* nhl = nullptr, time_t* lwt = nullptr, int recurse_count = 0) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (recurse_count > 16) { - ec = detail::make_system_error(0x2A9 /*ERROR_STOPPED_ON_SYMLINK*/); - return file_status(file_type::unknown); - } - WIN32_FILE_ATTRIBUTE_DATA attr; - if (!::GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { - ec = detail::make_system_error(); - } - else if (attr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - auto reparseData = detail::getReparseData(p, ec); - if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - path target = resolveSymlink(p, ec); - file_status result; - if (!ec && !target.empty()) { - if (sls) { - *sls = status_from_INFO(p, &attr, ec); - } - return detail::status_ex(target, ec, nullptr, sz, nhl, lwt, recurse_count + 1); - } - return file_status(file_type::unknown); - } - } - if (ec) { - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found); - } - return file_status(file_type::none); - } - if (nhl) { - *nhl = 0; - } - return detail::status_from_INFO(p, &attr, ec, sz, lwt); -#else - (void)recurse_count; - struct ::stat st; - auto result = ::lstat(p.c_str(), &st); - if (result == 0) { - ec.clear(); - file_status fs = detail::file_status_from_st_mode(st.st_mode); - if (sls) { - *sls = fs; - } - if (fs.type() == file_type::symlink) { - result = ::stat(p.c_str(), &st); - if (result == 0) { - fs = detail::file_status_from_st_mode(st.st_mode); - } - else { - ec = detail::make_system_error(); - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found, perms::unknown); - } - return file_status(file_type::none); - } - } - if (sz) { - *sz = static_cast(st.st_size); - } - if (nhl) { - *nhl = st.st_nlink; - } - if (lwt) { - *lwt = st.st_mtime; - } - return fs; - } - else { - ec = detail::make_system_error(); - if (detail::is_not_found_error(ec)) { - return file_status(file_type::not_found, perms::unknown); - } - return file_status(file_type::none); - } -#endif -} - -} // namespace detail - -GHC_INLINE u8arguments::u8arguments(int& argc, char**& argv) - : _argc(argc) - , _argv(argv) - , _refargc(argc) - , _refargv(argv) - , _isvalid(false) -{ -#ifdef GHC_OS_WINDOWS - LPWSTR* p; - p = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - _args.reserve(static_cast(argc)); - _argp.reserve(static_cast(argc)); - for (size_t i = 0; i < static_cast(argc); ++i) { - _args.push_back(detail::toUtf8(std::wstring(p[i]))); - _argp.push_back((char*)_args[i].data()); - } - argv = _argp.data(); - ::LocalFree(p); - _isvalid = true; -#else - std::setlocale(LC_ALL, ""); -#if defined(__ANDROID__) && __ANDROID_API__ < 26 - _isvalid = true; -#else - if (detail::equals_simple_insensitive(::nl_langinfo(CODESET), "UTF-8")) { - _isvalid = true; - } -#endif -#endif -} - -//----------------------------------------------------------------------------- -// [fs.path.construct] constructors and destructor - -GHC_INLINE path::path() noexcept {} - -GHC_INLINE path::path(const path& p) - : _path(p._path) -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - , _prefixLength(p._prefixLength) -#endif -{ -} - -GHC_INLINE path::path(path&& p) noexcept - : _path(std::move(p._path)) -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - , _prefixLength(p._prefixLength) -#endif -{ -} - -GHC_INLINE path::path(string_type&& source, format fmt) - : _path(std::move(source)) -{ - postprocess_path_with_format(fmt); -} - -#endif // GHC_EXPAND_IMPL - -#ifdef GHC_WITH_EXCEPTIONS -template -inline path::path(const Source& source, const std::locale& loc, format fmt) - : path(source, fmt) -{ - std::string locName = loc.name(); - if (!(locName.length() >= 5 && (locName.substr(locName.length() - 5) == "UTF-8" || locName.substr(locName.length() - 5) == "utf-8"))) { - throw filesystem_error("This implementation only supports UTF-8 locales!", path(_path), detail::make_error_code(detail::portable_error::not_supported)); - } -} - -template -inline path::path(InputIterator first, InputIterator last, const std::locale& loc, format fmt) - : path(std::basic_string::value_type>(first, last), fmt) -{ - std::string locName = loc.name(); - if (!(locName.length() >= 5 && (locName.substr(locName.length() - 5) == "UTF-8" || locName.substr(locName.length() - 5) == "utf-8"))) { - throw filesystem_error("This implementation only supports UTF-8 locales!", path(_path), detail::make_error_code(detail::portable_error::not_supported)); - } -} -#endif - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE path::~path() {} - -//----------------------------------------------------------------------------- -// [fs.path.assign] assignments - -GHC_INLINE path& path::operator=(const path& p) -{ - _path = p._path; -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = p._prefixLength; -#endif - return *this; -} - -GHC_INLINE path& path::operator=(path&& p) noexcept -{ - _path = std::move(p._path); -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = p._prefixLength; -#endif - return *this; -} - -GHC_INLINE path& path::operator=(path::string_type&& source) -{ - return assign(source); -} - -GHC_INLINE path& path::assign(path::string_type&& source) -{ - _path = std::move(source); - postprocess_path_with_format(native_format); - return *this; -} - -#endif // GHC_EXPAND_IMPL - -template -inline path& path::operator=(const Source& source) -{ - return assign(source); -} - -template -inline path& path::assign(const Source& source) -{ -#ifdef GHC_USE_WCHAR_T - _path.assign(detail::toWChar(source)); -#else - _path.assign(detail::toUtf8(source)); -#endif - postprocess_path_with_format(native_format); - return *this; -} - -template <> -inline path& path::assign(const path& source) -{ - _path = source._path; -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = source._prefixLength; -#endif - return *this; -} - -template -inline path& path::assign(InputIterator first, InputIterator last) -{ - _path.assign(first, last); - postprocess_path_with_format(native_format); - return *this; -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.append] appends - -GHC_INLINE path& path::operator/=(const path& p) -{ - if (p.empty()) { - // was: if ((!has_root_directory() && is_absolute()) || has_filename()) - if (!_path.empty() && _path[_path.length() - 1] != preferred_separator && _path[_path.length() - 1] != ':') { - _path += preferred_separator; - } - return *this; - } - if ((p.is_absolute() && (_path != root_name()._path || p._path != "/")) || (p.has_root_name() && p.root_name() != root_name())) { - assign(p); - return *this; - } - if (p.has_root_directory()) { - assign(root_name()); - } - else if ((!has_root_directory() && is_absolute()) || has_filename()) { - _path += preferred_separator; - } - auto iter = p.begin(); - bool first = true; - if (p.has_root_name()) { - ++iter; - } - while (iter != p.end()) { - if (!first && !(!_path.empty() && _path[_path.length() - 1] == preferred_separator)) { - _path += preferred_separator; - } - first = false; - _path += (*iter++).native(); - } - check_long_path(); - return *this; -} - -GHC_INLINE void path::append_name(const value_type* name) -{ - if (_path.empty()) { - this->operator/=(path(name)); - } - else { - if (_path.back() != path::preferred_separator) { - _path.push_back(path::preferred_separator); - } - _path += name; - check_long_path(); - } -} - -#endif // GHC_EXPAND_IMPL - -template -inline path& path::operator/=(const Source& source) -{ - return append(source); -} - -template -inline path& path::append(const Source& source) -{ - return this->operator/=(path(source)); -} - -template <> -inline path& path::append(const path& p) -{ - return this->operator/=(p); -} - -template -inline path& path::append(InputIterator first, InputIterator last) -{ - std::basic_string::value_type> part(first, last); - return append(part); -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.concat] concatenation - -GHC_INLINE path& path::operator+=(const path& x) -{ - return concat(x._path); -} - -GHC_INLINE path& path::operator+=(const string_type& x) -{ - return concat(x); -} - -#ifdef GHC_WITH_STRING_VIEW -GHC_INLINE path& path::operator+=(basic_string_view x) -{ - return concat(x); -} -#endif - -GHC_INLINE path& path::operator+=(const value_type* x) -{ -#ifdef GHC_WITH_STRING_VIEW - basic_string_view part(x); -#else - string_type part(x); -#endif - return concat(part); -} - -GHC_INLINE path& path::operator+=(value_type x) -{ -#ifdef GHC_OS_WINDOWS - if (x == generic_separator) { - x = preferred_separator; - } -#endif - if (_path.empty() || _path.back() != preferred_separator) { - _path += x; - } - check_long_path(); - return *this; -} - -#endif // GHC_EXPAND_IMPL - -template -inline path::path_from_string& path::operator+=(const Source& x) -{ - return concat(x); -} - -template -inline path::path_type_EcharT& path::operator+=(EcharT x) -{ -#ifdef GHC_WITH_STRING_VIEW - basic_string_view part(&x, 1); -#else - std::basic_string part(1, x); -#endif - concat(part); - return *this; -} - -template -inline path& path::concat(const Source& x) -{ - path p(x); - _path += p._path; - postprocess_path_with_format(native_format); - return *this; -} -template -inline path& path::concat(InputIterator first, InputIterator last) -{ - _path.append(first, last); - postprocess_path_with_format(native_format); - return *this; -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.modifiers] modifiers -GHC_INLINE void path::clear() noexcept -{ - _path.clear(); -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = 0; -#endif -} - -GHC_INLINE path& path::make_preferred() -{ - // as this filesystem implementation only uses generic_format - // internally, this must be a no-op - return *this; -} - -GHC_INLINE path& path::remove_filename() -{ - if (has_filename()) { - _path.erase(_path.size() - filename()._path.size()); - } - return *this; -} - -GHC_INLINE path& path::replace_filename(const path& replacement) -{ - remove_filename(); - return append(replacement); -} - -GHC_INLINE path& path::replace_extension(const path& replacement) -{ - if (has_extension()) { - _path.erase(_path.size() - extension()._path.size()); - } - if (!replacement.empty() && replacement._path[0] != '.') { - _path += '.'; - } - return concat(replacement); -} - -GHC_INLINE void path::swap(path& rhs) noexcept -{ - _path.swap(rhs._path); -#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - std::swap(_prefixLength, rhs._prefixLength); -#endif -} - -//----------------------------------------------------------------------------- -// [fs.path.native.obs] native format observers -GHC_INLINE const path::string_type& path::native() const noexcept -{ - return _path; -} - -GHC_INLINE const path::value_type* path::c_str() const noexcept -{ - return native().c_str(); -} - -GHC_INLINE path::operator path::string_type() const -{ - return native(); -} - -#endif // GHC_EXPAND_IMPL - -template -inline std::basic_string path::string(const Allocator& a) const -{ -#ifdef GHC_USE_WCHAR_T - return detail::fromWChar>(_path, a); -#else - return detail::fromUtf8>(_path, a); -#endif -} - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE std::string path::string() const -{ -#ifdef GHC_USE_WCHAR_T - return detail::toUtf8(native()); -#else - return native(); -#endif -} - -GHC_INLINE std::wstring path::wstring() const -{ -#ifdef GHC_USE_WCHAR_T - return native(); -#else - return detail::fromUtf8(native()); -#endif -} - -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -GHC_INLINE std::u8string path::u8string() const -{ -#ifdef GHC_USE_WCHAR_T - return std::u8string(reinterpret_cast(detail::toUtf8(native()).c_str())); -#else - return std::u8string(reinterpret_cast(c_str())); -#endif -} -#else -GHC_INLINE std::string path::u8string() const -{ -#ifdef GHC_USE_WCHAR_T - return detail::toUtf8(native()); -#else - return native(); -#endif -} -#endif - -GHC_INLINE std::u16string path::u16string() const -{ - // TODO: optimize - return detail::fromUtf8(string()); -} - -GHC_INLINE std::u32string path::u32string() const -{ - // TODO: optimize - return detail::fromUtf8(string()); -} - -#endif // GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.generic.obs] generic format observers -template -inline std::basic_string path::generic_string(const Allocator& a) const -{ -#ifdef GHC_OS_WINDOWS -#ifdef GHC_USE_WCHAR_T - auto result = detail::fromWChar, path::string_type>(_path, a); -#else - auto result = detail::fromUtf8>(_path, a); -#endif - for (auto& c : result) { - if (c == preferred_separator) { - c = generic_separator; - } - } - return result; -#else - return detail::fromUtf8>(_path, a); -#endif -} - -#ifdef GHC_EXPAND_IMPL - -GHC_INLINE std::string path::generic_string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return _path; -#endif -} - -GHC_INLINE std::wstring path::generic_wstring() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return detail::fromUtf8(_path); -#endif -} // namespace filesystem - -#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) -GHC_INLINE std::u8string path::generic_u8string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return std::u8string(reinterpret_cast(_path.c_str())); -#endif -} -#else -GHC_INLINE std::string path::generic_u8string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return _path; -#endif -} -#endif - -GHC_INLINE std::u16string path::generic_u16string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return detail::fromUtf8(_path); -#endif -} - -GHC_INLINE std::u32string path::generic_u32string() const -{ -#ifdef GHC_OS_WINDOWS - return generic_string(); -#else - return detail::fromUtf8(_path); -#endif -} - -//----------------------------------------------------------------------------- -// [fs.path.compare] compare -GHC_INLINE int path::compare(const path& p) const noexcept -{ -#ifdef LWG_2936_BEHAVIOUR - auto rnl1 = root_name_length(); - auto rnl2 = p.root_name_length(); -#ifdef GHC_OS_WINDOWS - auto rnc = detail::compare_simple_insensitive(_path.c_str(), rnl1, p._path.c_str(), rnl2); -#else - auto rnc = _path.compare(0, rnl1, p._path, 0, (std::min(rnl1, rnl2))); -#endif - if (rnc) { - return rnc; - } - bool hrd1 = has_root_directory(), hrd2 = p.has_root_directory(); - if (hrd1 != hrd2) { - return hrd1 ? 1 : -1; - } - if (hrd1) { - ++rnl1; - ++rnl2; - } - auto iter1 = _path.begin() + static_cast(rnl1); - auto iter2 = p._path.begin() + static_cast(rnl2); - while (iter1 != _path.end() && iter2 != p._path.end() && *iter1 == *iter2) { - ++iter1; - ++iter2; - } - if (iter1 == _path.end()) { - return iter2 == p._path.end() ? 0 : -1; - } - if (iter2 == p._path.end()) { - return 1; - } - if (*iter1 == preferred_separator) { - return -1; - } - if (*iter2 == preferred_separator) { - return 1; - } - return *iter1 < *iter2 ? -1 : 1; -#else // LWG_2936_BEHAVIOUR -#ifdef GHC_OS_WINDOWS - auto rnl1 = root_name_length(); - auto rnl2 = p.root_name_length(); - auto rnc = detail::compare_simple_insensitive(_path.c_str(), rnl1, p._path.c_str(), rnl2); - if (rnc) { - return rnc; - } - return _path.compare(rnl1, std::string::npos, p._path, rnl2, std::string::npos); -#else - return _path.compare(p._path); -#endif -#endif -} - -GHC_INLINE int path::compare(const string_type& s) const -{ - return compare(path(s)); -} - -#ifdef GHC_WITH_STRING_VIEW -GHC_INLINE int path::compare(basic_string_view s) const -{ - return compare(path(s)); -} -#endif - -GHC_INLINE int path::compare(const value_type* s) const -{ - return compare(path(s)); -} - -//----------------------------------------------------------------------------- -// [fs.path.decompose] decomposition -#ifdef GHC_OS_WINDOWS -GHC_INLINE void path::handle_prefixes() -{ -#if defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) - _prefixLength = 0; - if (_path.length() >= 6 && _path[2] == '?' && std::toupper(static_cast(_path[4])) >= 'A' && std::toupper(static_cast(_path[4])) <= 'Z' && _path[5] == ':') { - if (detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\"))) || detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\??\\")))) { - _prefixLength = 4; - } - } -#endif // GHC_WIN_AUTO_PREFIX_LONG_PATH -} -#endif - -GHC_INLINE path::string_type::size_type path::root_name_length() const noexcept -{ -#ifdef GHC_OS_WINDOWS - if (_path.length() >= _prefixLength + 2 && std::toupper(static_cast(_path[_prefixLength])) >= 'A' && std::toupper(static_cast(_path[_prefixLength])) <= 'Z' && _path[_prefixLength + 1] == ':') { - return 2; - } -#endif - if (_path.length() > _prefixLength + 2 && _path[_prefixLength] == preferred_separator && _path[_prefixLength + 1] == preferred_separator && _path[_prefixLength + 2] != preferred_separator && std::isprint(_path[_prefixLength + 2])) { - impl_string_type::size_type pos = _path.find(preferred_separator, _prefixLength + 3); - if (pos == impl_string_type::npos) { - return _path.length(); - } - else { - return pos; - } - } - return 0; -} - -GHC_INLINE path path::root_name() const -{ - return path(_path.substr(_prefixLength, root_name_length()), native_format); -} - -GHC_INLINE path path::root_directory() const -{ - if (has_root_directory()) { - static const path _root_dir(std::string(1, preferred_separator), native_format); - return _root_dir; - } - return path(); -} - -GHC_INLINE path path::root_path() const -{ - return path(root_name().string() + root_directory().string(), native_format); -} - -GHC_INLINE path path::relative_path() const -{ - auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); - return path(_path.substr((std::min)(rootPathLen, _path.length())), generic_format); -} - -GHC_INLINE path path::parent_path() const -{ - auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); - if (rootPathLen < _path.length()) { - if (empty()) { - return path(); - } - else { - auto piter = end(); - auto iter = piter.decrement(_path.end()); - if (iter > _path.begin() + static_cast(rootPathLen) && *iter != preferred_separator) { - --iter; - } - return path(_path.begin(), iter, native_format); - } - } - else { - return *this; - } -} - -GHC_INLINE path path::filename() const -{ - return !has_relative_path() ? path() : path(*--end()); -} - -GHC_INLINE path path::stem() const -{ - impl_string_type fn = filename().native(); - if (fn != "." && fn != "..") { - impl_string_type::size_type pos = fn.rfind('.'); - if (pos != impl_string_type::npos && pos > 0) { - return path{fn.substr(0, pos), native_format}; - } - } - return path{fn, native_format}; -} - -GHC_INLINE path path::extension() const -{ - if (has_relative_path()) { - auto iter = end(); - const auto& fn = *--iter; - impl_string_type::size_type pos = fn._path.rfind('.'); - if (pos != std::string::npos && pos > 0 && fn._path != "..") { - return path(fn._path.substr(pos), native_format); - } - } - return path(); -} - -#ifdef GHC_OS_WINDOWS -namespace detail { -GHC_INLINE bool has_executable_extension(const path& p) -{ - if (p.has_relative_path()) { - auto iter = p.end(); - const auto& fn = *--iter; - auto pos = fn._path.find_last_of('.'); - if (pos == std::string::npos || pos == 0 || fn._path.length() - pos != 3) { - return false; - } - const path::value_type* ext = fn._path.c_str() + pos + 1; - if (detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("exe")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("cmd")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("bat")) || - detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("com"))) { - return true; - } - } - return false; -} -} // namespace detail -#endif - -//----------------------------------------------------------------------------- -// [fs.path.query] query -GHC_INLINE bool path::empty() const noexcept -{ - return _path.empty(); -} - -GHC_INLINE bool path::has_root_name() const -{ - return root_name_length() > 0; -} - -GHC_INLINE bool path::has_root_directory() const -{ - auto rootLen = _prefixLength + root_name_length(); - return (_path.length() > rootLen && _path[rootLen] == preferred_separator); -} - -GHC_INLINE bool path::has_root_path() const -{ - return has_root_name() || has_root_directory(); -} - -GHC_INLINE bool path::has_relative_path() const -{ - auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); - return rootPathLen < _path.length(); -} - -GHC_INLINE bool path::has_parent_path() const -{ - return !parent_path().empty(); -} - -GHC_INLINE bool path::has_filename() const -{ - return has_relative_path() && !filename().empty(); -} - -GHC_INLINE bool path::has_stem() const -{ - return !stem().empty(); -} - -GHC_INLINE bool path::has_extension() const -{ - return !extension().empty(); -} - -GHC_INLINE bool path::is_absolute() const -{ -#ifdef GHC_OS_WINDOWS - return has_root_name() && has_root_directory(); -#else - return has_root_directory(); -#endif -} - -GHC_INLINE bool path::is_relative() const -{ - return !is_absolute(); -} - -//----------------------------------------------------------------------------- -// [fs.path.gen] generation -GHC_INLINE path path::lexically_normal() const -{ - path dest; - bool lastDotDot = false; - for (string_type s : *this) { - if (s == ".") { - dest /= ""; - continue; - } - else if (s == ".." && !dest.empty()) { - auto root = root_path(); - if (dest == root) { - continue; - } - else if (*(--dest.end()) != "..") { - if (dest._path.back() == preferred_separator) { - dest._path.pop_back(); - } - dest.remove_filename(); - continue; - } - } - if (!(s.empty() && lastDotDot)) { - dest /= s; - } - lastDotDot = s == ".."; - } - if (dest.empty()) { - dest = "."; - } - return dest; -} - -GHC_INLINE path path::lexically_relative(const path& base) const -{ - if (root_name() != base.root_name() || is_absolute() != base.is_absolute() || (!has_root_directory() && base.has_root_directory())) { - return path(); - } - const_iterator a = begin(), b = base.begin(); - while (a != end() && b != base.end() && *a == *b) { - ++a; - ++b; - } - if (a == end() && b == base.end()) { - return path("."); - } - int count = 0; - for (const auto& element : input_iterator_range(b, base.end())) { - if (element != "." && element != "" && element != "..") { - ++count; - } - else if (element == "..") { - --count; - } - } - if (count < 0) { - return path(); - } - path result; - for (int i = 0; i < count; ++i) { - result /= ".."; - } - for (const auto& element : input_iterator_range(a, end())) { - result /= element; - } - return result; -} - -GHC_INLINE path path::lexically_proximate(const path& base) const -{ - path result = lexically_relative(base); - return result.empty() ? *this : result; -} - -//----------------------------------------------------------------------------- -// [fs.path.itr] iterators -GHC_INLINE path::iterator::iterator() {} - -GHC_INLINE path::iterator::iterator(const path& p, const impl_string_type::const_iterator& pos) - : _first(p._path.begin()) - , _last(p._path.end()) - , _prefix(_first + static_cast(p._prefixLength)) - , _root(p.has_root_directory() ? _first + static_cast(p._prefixLength + p.root_name_length()) : _last) - , _iter(pos) -{ - if (pos != _last) { - updateCurrent(); - } -} - -GHC_INLINE path::impl_string_type::const_iterator path::iterator::increment(const path::impl_string_type::const_iterator& pos) const -{ - path::impl_string_type::const_iterator i = pos; - bool fromStart = i == _first || i == _prefix; - if (i != _last) { - if (fromStart && i == _first && _prefix > _first) { - i = _prefix; - } - else if (*i++ == preferred_separator) { - // we can only sit on a slash if it is a network name or a root - if (i != _last && *i == preferred_separator) { - if (fromStart && !(i + 1 != _last && *(i + 1) == preferred_separator)) { - // leadind double slashes detected, treat this and the - // following until a slash as one unit - i = std::find(++i, _last, preferred_separator); - } - else { - // skip redundant slashes - while (i != _last && *i == preferred_separator) { - ++i; - } - } - } - } - else { -#ifdef GHC_OS_WINDOWS - if (fromStart && i != _last && *i == ':') { - ++i; - } - else { -#else - { -#endif - i = std::find(i, _last, preferred_separator); - } - } - } - return i; -} - -GHC_INLINE path::impl_string_type::const_iterator path::iterator::decrement(const path::impl_string_type::const_iterator& pos) const -{ - path::impl_string_type::const_iterator i = pos; - if (i != _first) { - --i; - // if this is now the root slash or the trailing slash, we are done, - // else check for network name - if (i != _root && (pos != _last || *i != preferred_separator)) { -#ifdef GHC_OS_WINDOWS - static const impl_string_type seps = GHC_PLATFORM_LITERAL("\\:"); - i = std::find_first_of(std::reverse_iterator(i), std::reverse_iterator(_first), seps.begin(), seps.end()).base(); - if (i > _first && *i == ':') { - i++; - } -#else - i = std::find(std::reverse_iterator(i), std::reverse_iterator(_first), preferred_separator).base(); -#endif - // Now we have to check if this is a network name - if (i - _first == 2 && *_first == preferred_separator && *(_first + 1) == preferred_separator) { - i -= 2; - } - } - } - return i; -} - -GHC_INLINE void path::iterator::updateCurrent() -{ - if ((_iter == _last) || (_iter != _first && _iter != _last && (*_iter == preferred_separator && _iter != _root) && (_iter + 1 == _last))) { - _current.clear(); - } - else { - _current.assign(_iter, increment(_iter)); - } -} - -GHC_INLINE path::iterator& path::iterator::operator++() -{ - _iter = increment(_iter); - while (_iter != _last && // we didn't reach the end - _iter != _root && // this is not a root position - *_iter == preferred_separator && // we are on a separator - (_iter + 1) != _last // the slash is not the last char - ) { - ++_iter; - } - updateCurrent(); - return *this; -} - -GHC_INLINE path::iterator path::iterator::operator++(int) -{ - path::iterator i{*this}; - ++(*this); - return i; -} - -GHC_INLINE path::iterator& path::iterator::operator--() -{ - _iter = decrement(_iter); - updateCurrent(); - return *this; -} - -GHC_INLINE path::iterator path::iterator::operator--(int) -{ - auto i = *this; - --(*this); - return i; -} - -GHC_INLINE bool path::iterator::operator==(const path::iterator& other) const -{ - return _iter == other._iter; -} - -GHC_INLINE bool path::iterator::operator!=(const path::iterator& other) const -{ - return _iter != other._iter; -} - -GHC_INLINE path::iterator::reference path::iterator::operator*() const -{ - return _current; -} - -GHC_INLINE path::iterator::pointer path::iterator::operator->() const -{ - return &_current; -} - -GHC_INLINE path::iterator path::begin() const -{ - return iterator(*this, _path.begin()); -} - -GHC_INLINE path::iterator path::end() const -{ - return iterator(*this, _path.end()); -} - -//----------------------------------------------------------------------------- -// [fs.path.nonmember] path non-member functions -GHC_INLINE void swap(path& lhs, path& rhs) noexcept -{ - swap(lhs._path, rhs._path); -} - -GHC_INLINE size_t hash_value(const path& p) noexcept -{ - return std::hash()(p.generic_string()); -} - -#ifdef GHC_HAS_THREEWAY_COMP -GHC_INLINE std::strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) <=> 0; -} -#endif - -GHC_INLINE bool operator==(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) == 0; -} - -GHC_INLINE bool operator!=(const path& lhs, const path& rhs) noexcept -{ - return !(lhs == rhs); -} - -GHC_INLINE bool operator<(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) < 0; -} - -GHC_INLINE bool operator<=(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) <= 0; -} - -GHC_INLINE bool operator>(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) > 0; -} - -GHC_INLINE bool operator>=(const path& lhs, const path& rhs) noexcept -{ - return lhs.compare(rhs) >= 0; -} - -GHC_INLINE path operator/(const path& lhs, const path& rhs) -{ - path result(lhs); - result /= rhs; - return result; -} - -#endif // GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.path.io] path inserter and extractor -template -inline std::basic_ostream& operator<<(std::basic_ostream& os, const path& p) -{ - os << "\""; - auto ps = p.string(); - for (auto c : ps) { - if (c == '"' || c == '\\') { - os << '\\'; - } - os << c; - } - os << "\""; - return os; -} - -template -inline std::basic_istream& operator>>(std::basic_istream& is, path& p) -{ - std::basic_string tmp; - charT c; - is >> c; - if (c == '"') { - auto sf = is.flags(); - is >> std::noskipws; - while (is) { - auto c2 = is.get(); - if (is) { - if (c2 == '\\') { - c2 = is.get(); - if (is) { - tmp += static_cast(c2); - } - } - else if (c2 == '"') { - break; - } - else { - tmp += static_cast(c2); - } - } - } - if ((sf & std::ios_base::skipws) == std::ios_base::skipws) { - is >> std::skipws; - } - p = path(tmp); - } - else { - is >> tmp; - p = path(static_cast(c) + tmp); - } - return is; -} - -#ifdef GHC_EXPAND_IMPL - -//----------------------------------------------------------------------------- -// [fs.class.filesystem_error] Class filesystem_error -GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, std::error_code ec) - : std::system_error(ec, what_arg) - , _what_arg(what_arg) - , _ec(ec) -{ -} - -GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, const path& p1, std::error_code ec) - : std::system_error(ec, what_arg) - , _what_arg(what_arg) - , _ec(ec) - , _p1(p1) -{ - if (!_p1.empty()) { - _what_arg += ": '" + _p1.string() + "'"; - } -} - -GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, const path& p1, const path& p2, std::error_code ec) - : std::system_error(ec, what_arg) - , _what_arg(what_arg) - , _ec(ec) - , _p1(p1) - , _p2(p2) -{ - if (!_p1.empty()) { - _what_arg += ": '" + _p1.string() + "'"; - } - if (!_p2.empty()) { - _what_arg += ", '" + _p2.string() + "'"; - } -} - -GHC_INLINE const path& filesystem_error::path1() const noexcept -{ - return _p1; -} - -GHC_INLINE const path& filesystem_error::path2() const noexcept -{ - return _p2; -} - -GHC_INLINE const char* filesystem_error::what() const noexcept -{ - return _what_arg.c_str(); -} - -//----------------------------------------------------------------------------- -// [fs.op.funcs] filesystem operations -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path absolute(const path& p) -{ - std::error_code ec; - path result = absolute(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path absolute(const path& p, std::error_code& ec) -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (p.empty()) { - return absolute(current_path(ec), ec) / ""; - } - ULONG size = ::GetFullPathNameW(GHC_NATIVEWP(p), 0, 0, 0); - if (size) { - std::vector buf(size, 0); - ULONG s2 = GetFullPathNameW(GHC_NATIVEWP(p), size, buf.data(), nullptr); - if (s2 && s2 < size) { - path result = path(std::wstring(buf.data(), s2)); - if (p.filename() == ".") { - result /= "."; - } - return result; - } - } - ec = detail::make_system_error(); - return path(); -#else - path base = current_path(ec); - if (!ec) { - if (p.empty()) { - return base / p; - } - if (p.has_root_name()) { - if (p.has_root_directory()) { - return p; - } - else { - return p.root_name() / base.root_directory() / base.relative_path() / p.relative_path(); - } - } - else { - if (p.has_root_directory()) { - return base.root_name() / p; - } - else { - return base / p; - } - } - } - ec = detail::make_system_error(); - return path(); -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path canonical(const path& p) -{ - std::error_code ec; - auto result = canonical(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path canonical(const path& p, std::error_code& ec) -{ - if (p.empty()) { - ec = detail::make_error_code(detail::portable_error::not_found); - return path(); - } - path work = p.is_absolute() ? p : absolute(p, ec); - path result; - - auto fs = status(work, ec); - if (ec) { - return path(); - } - if (fs.type() == file_type::not_found) { - ec = detail::make_error_code(detail::portable_error::not_found); - return path(); - } - bool redo; - do { - auto rootPathLen = work._prefixLength + work.root_name_length() + (work.has_root_directory() ? 1 : 0); - redo = false; - result.clear(); - for (auto pe : work) { - if (pe.empty() || pe == ".") { - continue; - } - else if (pe == "..") { - result = result.parent_path(); - continue; - } - else if ((result / pe).string().length() <= rootPathLen) { - result /= pe; - continue; - } - auto sls = symlink_status(result / pe, ec); - if (ec) { - return path(); - } - if (is_symlink(sls)) { - redo = true; - auto target = read_symlink(result / pe, ec); - if (ec) { - return path(); - } - if (target.is_absolute()) { - result = target; - continue; - } - else { - result /= target; - continue; - } - } - else { - result /= pe; - } - } - work = result; - } while (redo); - ec.clear(); - return result; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void copy(const path& from, const path& to) -{ - copy(from, to, copy_options::none); -} - -GHC_INLINE void copy(const path& from, const path& to, copy_options options) -{ - std::error_code ec; - copy(from, to, options, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); - } -} -#endif - -GHC_INLINE void copy(const path& from, const path& to, std::error_code& ec) noexcept -{ - copy(from, to, copy_options::none, ec); -} - -GHC_INLINE void copy(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept -{ - std::error_code tec; - file_status fs_from, fs_to; - ec.clear(); - if ((options & (copy_options::skip_symlinks | copy_options::copy_symlinks | copy_options::create_symlinks)) != copy_options::none) { - fs_from = symlink_status(from, ec); - } - else { - fs_from = status(from, ec); - } - if (!exists(fs_from)) { - if (!ec) { - ec = detail::make_error_code(detail::portable_error::not_found); - } - return; - } - if ((options & (copy_options::skip_symlinks | copy_options::create_symlinks)) != copy_options::none) { - fs_to = symlink_status(to, tec); - } - else { - fs_to = status(to, tec); - } - if (is_other(fs_from) || is_other(fs_to) || (is_directory(fs_from) && is_regular_file(fs_to)) || (exists(fs_to) && equivalent(from, to, ec))) { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - } - else if (is_symlink(fs_from)) { - if ((options & copy_options::skip_symlinks) == copy_options::none) { - if (!exists(fs_to) && (options & copy_options::copy_symlinks) != copy_options::none) { - copy_symlink(from, to, ec); - } - else { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - } - } - } - else if (is_regular_file(fs_from)) { - if ((options & copy_options::directories_only) == copy_options::none) { - if ((options & copy_options::create_symlinks) != copy_options::none) { - create_symlink(from.is_absolute() ? from : canonical(from, ec), to, ec); - } -#ifndef GHC_OS_WEB - else if ((options & copy_options::create_hard_links) != copy_options::none) { - create_hard_link(from, to, ec); - } -#endif - else if (is_directory(fs_to)) { - copy_file(from, to / from.filename(), options, ec); - } - else { - copy_file(from, to, options, ec); - } - } - } -#ifdef LWG_2682_BEHAVIOUR - else if (is_directory(fs_from) && (options & copy_options::create_symlinks) != copy_options::none) { - ec = detail::make_error_code(detail::portable_error::is_a_directory); - } -#endif - else if (is_directory(fs_from) && (options == copy_options::none || (options & copy_options::recursive) != copy_options::none)) { - if (!exists(fs_to)) { - create_directory(to, from, ec); - if (ec) { - return; - } - } - for (auto iter = directory_iterator(from, ec); iter != directory_iterator(); iter.increment(ec)) { - if (!ec) { - copy(iter->path(), to / iter->path().filename(), options | static_cast(0x8000), ec); - } - if (ec) { - return; - } - } - } - return; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool copy_file(const path& from, const path& to) -{ - return copy_file(from, to, copy_options::none); -} - -GHC_INLINE bool copy_file(const path& from, const path& to, copy_options option) -{ - std::error_code ec; - auto result = copy_file(from, to, option, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); - } - return result; -} -#endif - -GHC_INLINE bool copy_file(const path& from, const path& to, std::error_code& ec) noexcept -{ - return copy_file(from, to, copy_options::none, ec); -} - -GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept -{ - std::error_code tecf, tect; - auto sf = status(from, tecf); - auto st = status(to, tect); - bool overwrite = false; - ec.clear(); - if (!is_regular_file(sf)) { - ec = tecf; - return false; - } - if (exists(st)) { - if ((options & copy_options::skip_existing) == copy_options::skip_existing) { - return false; - } - if (!is_regular_file(st) || equivalent(from, to, ec) || (options & (copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none) { - ec = tect ? tect : detail::make_error_code(detail::portable_error::exists); - return false; - } - if ((options & copy_options::update_existing) == copy_options::update_existing) { - auto from_time = last_write_time(from, ec); - if (ec) { - ec = detail::make_system_error(); - return false; - } - auto to_time = last_write_time(to, ec); - if (ec) { - ec = detail::make_system_error(); - return false; - } - if (from_time <= to_time) { - return false; - } - } - overwrite = true; - } -#ifdef GHC_OS_WINDOWS - if (!::CopyFileW(GHC_NATIVEWP(from), GHC_NATIVEWP(to), !overwrite)) { - ec = detail::make_system_error(); - return false; - } - return true; -#else - std::vector buffer(16384, '\0'); - int in = -1, out = -1; - if ((in = ::open(from.c_str(), O_RDONLY)) < 0) { - ec = detail::make_system_error(); - return false; - } - int mode = O_CREAT | O_WRONLY | O_TRUNC; - if (!overwrite) { - mode |= O_EXCL; - } - if ((out = ::open(to.c_str(), mode, static_cast(sf.permissions() & perms::all))) < 0) { - ec = detail::make_system_error(); - ::close(in); - return false; - } - if (st.permissions() != sf.permissions()) { - if (::fchmod(out, static_cast(sf.permissions() & perms::all)) != 0) { - ec = detail::make_system_error(); - ::close(in); - ::close(out); - return false; - } - } - ssize_t br, bw; - while (true) { - do { br = ::read(in, buffer.data(), buffer.size()); } while(errno == EINTR && !br); - if(!br) { - break; - } - if(br < 0) { - ec = detail::make_system_error(); - ::close(in); - ::close(out); - return false; - } - ssize_t offset = 0; - do { - if ((bw = ::write(out, buffer.data() + offset, static_cast(br))) > 0) { - br -= bw; - offset += bw; - } - else if (bw < 0 && errno != EINTR) { - ec = detail::make_system_error(); - ::close(in); - ::close(out); - return false; - } - } while (br); - } - ::close(in); - ::close(out); - return true; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symlink) -{ - std::error_code ec; - copy_symlink(existing_symlink, new_symlink, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), existing_symlink, new_symlink, ec); - } -} -#endif - -GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symlink, std::error_code& ec) noexcept -{ - ec.clear(); - auto to = read_symlink(existing_symlink, ec); - if (!ec) { - if (exists(to, ec) && is_directory(to, ec)) { - create_directory_symlink(to, new_symlink, ec); - } - else { - create_symlink(to, new_symlink, ec); - } - } -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool create_directories(const path& p) -{ - std::error_code ec; - auto result = create_directories(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool create_directories(const path& p, std::error_code& ec) noexcept -{ - path current; - ec.clear(); - bool didCreate = false; - auto rootPathLen = p._prefixLength + p.root_name_length() + (p.has_root_directory() ? 1 : 0); - current = p.native().substr(0, rootPathLen); - path folders(p._path.substr(rootPathLen)); - for (path::string_type part : folders) { - current /= part; - std::error_code tec; - auto fs = status(current, tec); - if (tec && fs.type() != file_type::not_found) { - ec = tec; - return false; - } - if (!exists(fs)) { - create_directory(current, ec); - if (ec) { - std::error_code tmp_ec; - if (is_directory(current, tmp_ec)) { - ec.clear(); - } - else { - return false; - } - } - didCreate = true; - } -#ifndef LWG_2935_BEHAVIOUR - else if (!is_directory(fs)) { - ec = detail::make_error_code(detail::portable_error::exists); - return false; - } -#endif - } - return didCreate; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool create_directory(const path& p) -{ - std::error_code ec; - auto result = create_directory(p, path(), ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool create_directory(const path& p, std::error_code& ec) noexcept -{ - return create_directory(p, path(), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool create_directory(const path& p, const path& attributes) -{ - std::error_code ec; - auto result = create_directory(p, attributes, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool create_directory(const path& p, const path& attributes, std::error_code& ec) noexcept -{ - std::error_code tec; - ec.clear(); - auto fs = status(p, tec); -#ifdef LWG_2935_BEHAVIOUR - if (status_known(fs) && exists(fs)) { - return false; - } -#else - if (status_known(fs) && exists(fs) && is_directory(fs)) { - return false; - } -#endif -#ifdef GHC_OS_WINDOWS - if (!attributes.empty()) { - if (!::CreateDirectoryExW(GHC_NATIVEWP(attributes), GHC_NATIVEWP(p), NULL)) { - ec = detail::make_system_error(); - return false; - } - } - else if (!::CreateDirectoryW(GHC_NATIVEWP(p), NULL)) { - ec = detail::make_system_error(); - return false; - } -#else - ::mode_t attribs = static_cast(perms::all); - if (!attributes.empty()) { - struct ::stat fileStat; - if (::stat(attributes.c_str(), &fileStat) != 0) { - ec = detail::make_system_error(); - return false; - } - attribs = fileStat.st_mode; - } - if (::mkdir(p.c_str(), attribs) != 0) { - ec = detail::make_system_error(); - return false; - } -#endif - return true; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void create_directory_symlink(const path& to, const path& new_symlink) -{ - std::error_code ec; - create_directory_symlink(to, new_symlink, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), to, new_symlink, ec); - } -} -#endif - -GHC_INLINE void create_directory_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept -{ - detail::create_symlink(to, new_symlink, true, ec); -} - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void create_hard_link(const path& to, const path& new_hard_link) -{ - std::error_code ec; - create_hard_link(to, new_hard_link, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), to, new_hard_link, ec); - } -} -#endif - -GHC_INLINE void create_hard_link(const path& to, const path& new_hard_link, std::error_code& ec) noexcept -{ - detail::create_hardlink(to, new_hard_link, ec); -} -#endif - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void create_symlink(const path& to, const path& new_symlink) -{ - std::error_code ec; - create_symlink(to, new_symlink, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), to, new_symlink, ec); - } -} -#endif - -GHC_INLINE void create_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept -{ - detail::create_symlink(to, new_symlink, false, ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path current_path() -{ - std::error_code ec; - auto result = current_path(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), ec); - } - return result; -} -#endif - -GHC_INLINE path current_path(std::error_code& ec) -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - DWORD pathlen = ::GetCurrentDirectoryW(0, 0); - std::unique_ptr buffer(new wchar_t[size_t(pathlen) + 1]); - if (::GetCurrentDirectoryW(pathlen, buffer.get()) == 0) { - ec = detail::make_system_error(); - return path(); - } - return path(std::wstring(buffer.get()), path::native_format); -#elif defined(__GLIBC__) - std::unique_ptr buffer { ::getcwd(NULL, 0), std::free }; - if (buffer == nullptr) { - ec = detail::make_system_error(); - return path(); - } - return path(buffer.get()); -#else - size_t pathlen = static_cast(std::max(int(::pathconf(".", _PC_PATH_MAX)), int(PATH_MAX))); - std::unique_ptr buffer(new char[pathlen + 1]); - if (::getcwd(buffer.get(), pathlen) == nullptr) { - ec = detail::make_system_error(); - return path(); - } - return path(buffer.get()); -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void current_path(const path& p) -{ - std::error_code ec; - current_path(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void current_path(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (!::SetCurrentDirectoryW(GHC_NATIVEWP(p))) { - ec = detail::make_system_error(); - } -#else - if (::chdir(p.string().c_str()) == -1) { - ec = detail::make_system_error(); - } -#endif -} - -GHC_INLINE bool exists(file_status s) noexcept -{ - return status_known(s) && s.type() != file_type::not_found; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool exists(const path& p) -{ - return exists(status(p)); -} -#endif - -GHC_INLINE bool exists(const path& p, std::error_code& ec) noexcept -{ - file_status s = status(p, ec); - if (status_known(s)) { - ec.clear(); - } - return exists(s); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool equivalent(const path& p1, const path& p2) -{ - std::error_code ec; - bool result = equivalent(p1, p2, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p1, p2, ec); - } - return result; -} -#endif - -GHC_INLINE bool equivalent(const path& p1, const path& p2, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - detail::unique_handle file1(::CreateFileW(GHC_NATIVEWP(p1), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - auto e1 = ::GetLastError(); - detail::unique_handle file2(::CreateFileW(GHC_NATIVEWP(p2), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - if (!file1 || !file2) { -#ifdef LWG_2937_BEHAVIOUR - ec = detail::make_system_error(e1 ? e1 : ::GetLastError()); -#else - if (file1 == file2) { - ec = detail::make_system_error(e1 ? e1 : ::GetLastError()); - } -#endif - return false; - } - BY_HANDLE_FILE_INFORMATION inf1, inf2; - if (!::GetFileInformationByHandle(file1.get(), &inf1)) { - ec = detail::make_system_error(); - return false; - } - if (!::GetFileInformationByHandle(file2.get(), &inf2)) { - ec = detail::make_system_error(); - return false; - } - return inf1.ftLastWriteTime.dwLowDateTime == inf2.ftLastWriteTime.dwLowDateTime && inf1.ftLastWriteTime.dwHighDateTime == inf2.ftLastWriteTime.dwHighDateTime && inf1.nFileIndexHigh == inf2.nFileIndexHigh && inf1.nFileIndexLow == inf2.nFileIndexLow && - inf1.nFileSizeHigh == inf2.nFileSizeHigh && inf1.nFileSizeLow == inf2.nFileSizeLow && inf1.dwVolumeSerialNumber == inf2.dwVolumeSerialNumber; -#else - struct ::stat s1, s2; - auto rc1 = ::stat(p1.c_str(), &s1); - auto e1 = errno; - auto rc2 = ::stat(p2.c_str(), &s2); - if (rc1 || rc2) { -#ifdef LWG_2937_BEHAVIOUR - ec = detail::make_system_error(e1 ? e1 : errno); -#else - if (rc1 && rc2) { - ec = detail::make_system_error(e1 ? e1 : errno); - } -#endif - return false; - } - return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t file_size(const path& p) -{ - std::error_code ec; - auto result = file_size(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE uintmax_t file_size(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - WIN32_FILE_ATTRIBUTE_DATA attr; - if (!GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { - ec = detail::make_system_error(); - return static_cast(-1); - } - return static_cast(attr.nFileSizeHigh) << (sizeof(attr.nFileSizeHigh) * 8) | attr.nFileSizeLow; -#else - struct ::stat fileStat; - if (::stat(p.c_str(), &fileStat) == -1) { - ec = detail::make_system_error(); - return static_cast(-1); - } - return static_cast(fileStat.st_size); -#endif -} - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t hard_link_count(const path& p) -{ - std::error_code ec; - auto result = hard_link_count(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - uintmax_t result = static_cast(-1); - detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); - BY_HANDLE_FILE_INFORMATION inf; - if (!file) { - ec = detail::make_system_error(); - } - else { - if (!::GetFileInformationByHandle(file.get(), &inf)) { - ec = detail::make_system_error(); - } - else { - result = inf.nNumberOfLinks; - } - } - return result; -#else - uintmax_t result = 0; - file_status fs = detail::status_ex(p, ec, nullptr, nullptr, &result, nullptr); - if (fs.type() == file_type::not_found) { - ec = detail::make_error_code(detail::portable_error::not_found); - } - return ec ? static_cast(-1) : result; -#endif -} -#endif - -GHC_INLINE bool is_block_file(file_status s) noexcept -{ - return s.type() == file_type::block; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_block_file(const path& p) -{ - return is_block_file(status(p)); -} -#endif - -GHC_INLINE bool is_block_file(const path& p, std::error_code& ec) noexcept -{ - return is_block_file(status(p, ec)); -} - -GHC_INLINE bool is_character_file(file_status s) noexcept -{ - return s.type() == file_type::character; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_character_file(const path& p) -{ - return is_character_file(status(p)); -} -#endif - -GHC_INLINE bool is_character_file(const path& p, std::error_code& ec) noexcept -{ - return is_character_file(status(p, ec)); -} - -GHC_INLINE bool is_directory(file_status s) noexcept -{ - return s.type() == file_type::directory; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_directory(const path& p) -{ - return is_directory(status(p)); -} -#endif - -GHC_INLINE bool is_directory(const path& p, std::error_code& ec) noexcept -{ - return is_directory(status(p, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_empty(const path& p) -{ - if (is_directory(p)) { - return directory_iterator(p) == directory_iterator(); - } - else { - return file_size(p) == 0; - } -} -#endif - -GHC_INLINE bool is_empty(const path& p, std::error_code& ec) noexcept -{ - auto fs = status(p, ec); - if (ec) { - return false; - } - if (is_directory(fs)) { - directory_iterator iter(p, ec); - if (ec) { - return false; - } - return iter == directory_iterator(); - } - else { - auto sz = file_size(p, ec); - if (ec) { - return false; - } - return sz == 0; - } -} - -GHC_INLINE bool is_fifo(file_status s) noexcept -{ - return s.type() == file_type::fifo; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_fifo(const path& p) -{ - return is_fifo(status(p)); -} -#endif - -GHC_INLINE bool is_fifo(const path& p, std::error_code& ec) noexcept -{ - return is_fifo(status(p, ec)); -} - -GHC_INLINE bool is_other(file_status s) noexcept -{ - return exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_other(const path& p) -{ - return is_other(status(p)); -} -#endif - -GHC_INLINE bool is_other(const path& p, std::error_code& ec) noexcept -{ - return is_other(status(p, ec)); -} - -GHC_INLINE bool is_regular_file(file_status s) noexcept -{ - return s.type() == file_type::regular; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_regular_file(const path& p) -{ - return is_regular_file(status(p)); -} -#endif - -GHC_INLINE bool is_regular_file(const path& p, std::error_code& ec) noexcept -{ - return is_regular_file(status(p, ec)); -} - -GHC_INLINE bool is_socket(file_status s) noexcept -{ - return s.type() == file_type::socket; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_socket(const path& p) -{ - return is_socket(status(p)); -} -#endif - -GHC_INLINE bool is_socket(const path& p, std::error_code& ec) noexcept -{ - return is_socket(status(p, ec)); -} - -GHC_INLINE bool is_symlink(file_status s) noexcept -{ - return s.type() == file_type::symlink; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool is_symlink(const path& p) -{ - return is_symlink(symlink_status(p)); -} -#endif - -GHC_INLINE bool is_symlink(const path& p, std::error_code& ec) noexcept -{ - return is_symlink(symlink_status(p, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_time_type last_write_time(const path& p) -{ - std::error_code ec; - auto result = last_write_time(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE file_time_type last_write_time(const path& p, std::error_code& ec) noexcept -{ - time_t result = 0; - ec.clear(); - file_status fs = detail::status_ex(p, ec, nullptr, nullptr, nullptr, &result); - return ec ? (file_time_type::min)() : std::chrono::system_clock::from_time_t(result); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void last_write_time(const path& p, file_time_type new_time) -{ - std::error_code ec; - last_write_time(p, new_time, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::error_code& ec) noexcept -{ - ec.clear(); - auto d = new_time.time_since_epoch(); -#ifdef GHC_OS_WINDOWS - detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)); - FILETIME ft; - auto tt = std::chrono::duration_cast(d).count() * 10 + 116444736000000000; - ft.dwLowDateTime = static_cast(tt); - ft.dwHighDateTime = static_cast(tt >> 32); - if (!::SetFileTime(file.get(), 0, 0, &ft)) { - ec = detail::make_system_error(); - } -#elif defined(GHC_OS_APPLE) && \ - (__MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300 \ - || __IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < 110000 \ - || __TV_OS_VERSION_MIN_REQUIRED && __TVOS_VERSION_MIN_REQUIRED < 110000 \ - || __WATCH_OS_VERSION_MIN_REQUIRED && __WATCHOS_VERSION_MIN_REQUIRED < 40000) - struct ::stat fs; - if (::stat(p.c_str(), &fs) == 0) { - struct ::timeval tv[2]; - tv[0].tv_sec = fs.st_atimespec.tv_sec; - tv[0].tv_usec = static_cast(fs.st_atimespec.tv_nsec / 1000); - tv[1].tv_sec = std::chrono::duration_cast(d).count(); - tv[1].tv_usec = static_cast(std::chrono::duration_cast(d).count() % 1000000); - if (::utimes(p.c_str(), tv) == 0) { - return; - } - } - ec = detail::make_system_error(); - return; -#else -#ifndef UTIME_OMIT -#define UTIME_OMIT ((1l << 30) - 2l) -#endif - struct ::timespec times[2]; - times[0].tv_sec = 0; - times[0].tv_nsec = UTIME_OMIT; - times[1].tv_sec = static_cast(std::chrono::duration_cast(d).count()); - times[1].tv_nsec = static_cast(std::chrono::duration_cast(d).count() % 1000000000); -#if defined(__ANDROID_API__) && __ANDROID_API__ < 12 - if (syscall(__NR_utimensat, AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { -#else - if (::utimensat((int)AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { -#endif - ec = detail::make_system_error(); - } - return; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void permissions(const path& p, perms prms, perm_options opts) -{ - std::error_code ec; - permissions(p, prms, opts, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void permissions(const path& p, perms prms, std::error_code& ec) noexcept -{ - permissions(p, prms, perm_options::replace, ec); -} - -GHC_INLINE void permissions(const path& p, perms prms, perm_options opts, std::error_code& ec) noexcept -{ - if (static_cast(opts & (perm_options::replace | perm_options::add | perm_options::remove)) == 0) { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - return; - } - auto fs = symlink_status(p, ec); - if ((opts & perm_options::replace) != perm_options::replace) { - if ((opts & perm_options::add) == perm_options::add) { - prms = fs.permissions() | prms; - } - else { - prms = fs.permissions() & ~prms; - } - } -#ifdef GHC_OS_WINDOWS -#ifdef __GNUC__ - auto oldAttr = GetFileAttributesW(GHC_NATIVEWP(p)); - if (oldAttr != INVALID_FILE_ATTRIBUTES) { - DWORD newAttr = ((prms & perms::owner_write) == perms::owner_write) ? oldAttr & ~(static_cast(FILE_ATTRIBUTE_READONLY)) : oldAttr | FILE_ATTRIBUTE_READONLY; - if (oldAttr == newAttr || SetFileAttributesW(GHC_NATIVEWP(p), newAttr)) { - return; - } - } - ec = detail::make_system_error(); -#else - int mode = 0; - if ((prms & perms::owner_read) == perms::owner_read) { - mode |= _S_IREAD; - } - if ((prms & perms::owner_write) == perms::owner_write) { - mode |= _S_IWRITE; - } - if (::_wchmod(p.wstring().c_str(), mode) != 0) { - ec = detail::make_system_error(); - } -#endif -#else - if ((opts & perm_options::nofollow) != perm_options::nofollow) { - if (::chmod(p.c_str(), static_cast(prms)) != 0) { - ec = detail::make_system_error(); - } - } -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path proximate(const path& p, std::error_code& ec) -{ - auto cp = current_path(ec); - if (!ec) { - return proximate(p, cp, ec); - } - return path(); -} -#endif - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path proximate(const path& p, const path& base) -{ - return weakly_canonical(p).lexically_proximate(weakly_canonical(base)); -} -#endif - -GHC_INLINE path proximate(const path& p, const path& base, std::error_code& ec) -{ - return weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path read_symlink(const path& p) -{ - std::error_code ec; - auto result = read_symlink(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path read_symlink(const path& p, std::error_code& ec) -{ - file_status fs = symlink_status(p, ec); - if (fs.type() != file_type::symlink) { - ec = detail::make_error_code(detail::portable_error::invalid_argument); - return path(); - } - auto result = detail::resolveSymlink(p, ec); - return ec ? path() : result; -} - -GHC_INLINE path relative(const path& p, std::error_code& ec) -{ - return relative(p, current_path(ec), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path relative(const path& p, const path& base) -{ - return weakly_canonical(p).lexically_relative(weakly_canonical(base)); -} -#endif - -GHC_INLINE path relative(const path& p, const path& base, std::error_code& ec) -{ - return weakly_canonical(p, ec).lexically_relative(weakly_canonical(base, ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool remove(const path& p) -{ - std::error_code ec; - auto result = remove(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE bool remove(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS -#ifdef GHC_USE_WCHAR_T - auto cstr = p.c_str(); -#else - std::wstring np = detail::fromUtf8(p.u8string()); - auto cstr = np.c_str(); -#endif - DWORD attr = GetFileAttributesW(cstr); - if (attr == INVALID_FILE_ATTRIBUTES) { - auto error = ::GetLastError(); - if (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND) { - return false; - } - ec = detail::make_system_error(error); - } - else if (attr & FILE_ATTRIBUTE_READONLY) { - auto new_attr = attr & ~static_cast(FILE_ATTRIBUTE_READONLY); - if (!SetFileAttributesW(cstr, new_attr)) { - auto error = ::GetLastError(); - ec = detail::make_system_error(error); - } - } - if (!ec) { - if (attr & FILE_ATTRIBUTE_DIRECTORY) { - if (!RemoveDirectoryW(cstr)) { - ec = detail::make_system_error(); - } - } - else { - if (!DeleteFileW(cstr)) { - ec = detail::make_system_error(); - } - } - } -#else - if (::remove(p.c_str()) == -1) { - auto error = errno; - if (error == ENOENT) { - return false; - } - ec = detail::make_system_error(); - } -#endif - return ec ? false : true; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t remove_all(const path& p) -{ - std::error_code ec; - auto result = remove_all(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE uintmax_t remove_all(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); - uintmax_t count = 0; - if (p == "/") { - ec = detail::make_error_code(detail::portable_error::not_supported); - return static_cast(-1); - } - std::error_code tec; - auto fs = symlink_status(p, tec); - if (exists(fs) && is_directory(fs)) { - for (auto iter = directory_iterator(p, ec); iter != directory_iterator(); iter.increment(ec)) { - if (ec && !detail::is_not_found_error(ec)) { - break; - } - bool is_symlink_result = iter->is_symlink(ec); - if (ec) - return static_cast(-1); - if (!is_symlink_result && iter->is_directory(ec)) { - count += remove_all(iter->path(), ec); - if (ec) { - return static_cast(-1); - } - } - else { - if (!ec) { - remove(iter->path(), ec); - } - if (ec) { - return static_cast(-1); - } - ++count; - } - } - } - if (!ec) { - if (remove(p, ec)) { - ++count; - } - } - if (ec) { - return static_cast(-1); - } - return count; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void rename(const path& from, const path& to) -{ - std::error_code ec; - rename(from, to, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); - } -} -#endif - -GHC_INLINE void rename(const path& from, const path& to, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - if (from != to) { - if (!MoveFileExW(GHC_NATIVEWP(from), GHC_NATIVEWP(to), (DWORD)MOVEFILE_REPLACE_EXISTING)) { - ec = detail::make_system_error(); - } - } -#else - if (from != to) { - if (::rename(from.c_str(), to.c_str()) != 0) { - ec = detail::make_system_error(); - } - } -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void resize_file(const path& p, uintmax_t size) -{ - std::error_code ec; - resize_file(p, size, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } -} -#endif - -GHC_INLINE void resize_file(const path& p, uintmax_t size, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - LARGE_INTEGER lisize; - lisize.QuadPart = static_cast(size); - if (lisize.QuadPart < 0) { -#ifdef ERROR_FILE_TOO_LARGE - ec = detail::make_system_error(ERROR_FILE_TOO_LARGE); -#else - ec = detail::make_system_error(223); -#endif - return; - } - detail::unique_handle file(CreateFileW(GHC_NATIVEWP(p), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)); - if (!file) { - ec = detail::make_system_error(); - } - else if (SetFilePointerEx(file.get(), lisize, NULL, FILE_BEGIN) == 0 || SetEndOfFile(file.get()) == 0) { - ec = detail::make_system_error(); - } -#else - if (::truncate(p.c_str(), static_cast(size)) != 0) { - ec = detail::make_system_error(); - } -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE space_info space(const path& p) -{ - std::error_code ec; - auto result = space(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE space_info space(const path& p, std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - ULARGE_INTEGER freeBytesAvailableToCaller = {{ 0, 0 }}; - ULARGE_INTEGER totalNumberOfBytes = {{ 0, 0 }}; - ULARGE_INTEGER totalNumberOfFreeBytes = {{ 0, 0 }}; - if (!GetDiskFreeSpaceExW(GHC_NATIVEWP(p), &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes)) { - ec = detail::make_system_error(); - return {static_cast(-1), static_cast(-1), static_cast(-1)}; - } - return {static_cast(totalNumberOfBytes.QuadPart), static_cast(totalNumberOfFreeBytes.QuadPart), static_cast(freeBytesAvailableToCaller.QuadPart)}; -#else - struct ::statvfs sfs; - if (::statvfs(p.c_str(), &sfs) != 0) { - ec = detail::make_system_error(); - return {static_cast(-1), static_cast(-1), static_cast(-1)}; - } - return {static_cast(sfs.f_blocks) * static_cast(sfs.f_frsize), static_cast(sfs.f_bfree) * static_cast(sfs.f_frsize), static_cast(sfs.f_bavail) * static_cast(sfs.f_frsize)}; -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status status(const path& p) -{ - std::error_code ec; - auto result = status(p, ec); - if (result.type() == file_type::none) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE file_status status(const path& p, std::error_code& ec) noexcept -{ - return detail::status_ex(p, ec); -} - -GHC_INLINE bool status_known(file_status s) noexcept -{ - return s.type() != file_type::none; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status symlink_status(const path& p) -{ - std::error_code ec; - auto result = symlink_status(p, ec); - if (result.type() == file_type::none) { - throw filesystem_error(detail::systemErrorText(ec.value()), ec); - } - return result; -} -#endif - -GHC_INLINE file_status symlink_status(const path& p, std::error_code& ec) noexcept -{ - return detail::symlink_status_ex(p, ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path temp_directory_path() -{ - std::error_code ec; - path result = temp_directory_path(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), ec); - } - return result; -} -#endif - -GHC_INLINE path temp_directory_path(std::error_code& ec) noexcept -{ - ec.clear(); -#ifdef GHC_OS_WINDOWS - wchar_t buffer[512]; - auto rc = GetTempPathW(511, buffer); - if (!rc || rc > 511) { - ec = detail::make_system_error(); - return path(); - } - return path(std::wstring(buffer)); -#else - static const char* temp_vars[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR", nullptr}; - const char* temp_path = nullptr; - for (auto temp_name = temp_vars; *temp_name != nullptr; ++temp_name) { - temp_path = std::getenv(*temp_name); - if (temp_path) { - return path(temp_path); - } - } - return path("/tmp"); -#endif -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE path weakly_canonical(const path& p) -{ - std::error_code ec; - auto result = weakly_canonical(p, ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); - } - return result; -} -#endif - -GHC_INLINE path weakly_canonical(const path& p, std::error_code& ec) noexcept -{ - path result; - ec.clear(); - bool scan = true; - for (auto pe : p) { - if (scan) { - std::error_code tec; - if (exists(result / pe, tec)) { - result /= pe; - } - else { - if (ec) { - return path(); - } - scan = false; - if (!result.empty()) { - result = canonical(result, ec) / pe; - if (ec) { - break; - } - } - else { - result /= pe; - } - } - } - else { - result /= pe; - } - } - if (scan) { - if (!result.empty()) { - result = canonical(result, ec); - } - } - return ec ? path() : result.lexically_normal(); -} - -//----------------------------------------------------------------------------- -// [fs.class.file_status] class file_status -// [fs.file_status.cons] constructors and destructor -GHC_INLINE file_status::file_status() noexcept - : file_status(file_type::none) -{ -} - -GHC_INLINE file_status::file_status(file_type ft, perms prms) noexcept - : _type(ft) - , _perms(prms) -{ -} - -GHC_INLINE file_status::file_status(const file_status& other) noexcept - : _type(other._type) - , _perms(other._perms) -{ -} - -GHC_INLINE file_status::file_status(file_status&& other) noexcept - : _type(other._type) - , _perms(other._perms) -{ -} - -GHC_INLINE file_status::~file_status() {} - -// assignments: -GHC_INLINE file_status& file_status::operator=(const file_status& rhs) noexcept -{ - _type = rhs._type; - _perms = rhs._perms; - return *this; -} - -GHC_INLINE file_status& file_status::operator=(file_status&& rhs) noexcept -{ - _type = rhs._type; - _perms = rhs._perms; - return *this; -} - -// [fs.file_status.mods] modifiers -GHC_INLINE void file_status::type(file_type ft) noexcept -{ - _type = ft; -} - -GHC_INLINE void file_status::permissions(perms prms) noexcept -{ - _perms = prms; -} - -// [fs.file_status.obs] observers -GHC_INLINE file_type file_status::type() const noexcept -{ - return _type; -} - -GHC_INLINE perms file_status::permissions() const noexcept -{ - return _perms; -} - -//----------------------------------------------------------------------------- -// [fs.class.directory_entry] class directory_entry -// [fs.dir.entry.cons] constructors and destructor -// directory_entry::directory_entry() noexcept = default; -// directory_entry::directory_entry(const directory_entry&) = default; -// directory_entry::directory_entry(directory_entry&&) noexcept = default; -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE directory_entry::directory_entry(const filesystem::path& p) - : _path(p) - , _file_size(static_cast(-1)) -#ifndef GHC_OS_WINDOWS - , _hard_link_count(static_cast(-1)) -#endif - , _last_write_time(0) -{ - refresh(); -} -#endif - -GHC_INLINE directory_entry::directory_entry(const filesystem::path& p, std::error_code& ec) - : _path(p) - , _file_size(static_cast(-1)) -#ifndef GHC_OS_WINDOWS - , _hard_link_count(static_cast(-1)) -#endif - , _last_write_time(0) -{ - refresh(ec); -} - -GHC_INLINE directory_entry::~directory_entry() {} - -// assignments: -// directory_entry& directory_entry::operator=(const directory_entry&) = default; -// directory_entry& directory_entry::operator=(directory_entry&&) noexcept = default; - -// [fs.dir.entry.mods] directory_entry modifiers -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void directory_entry::assign(const filesystem::path& p) -{ - _path = p; - refresh(); -} -#endif - -GHC_INLINE void directory_entry::assign(const filesystem::path& p, std::error_code& ec) -{ - _path = p; - refresh(ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void directory_entry::replace_filename(const filesystem::path& p) -{ - _path.replace_filename(p); - refresh(); -} -#endif - -GHC_INLINE void directory_entry::replace_filename(const filesystem::path& p, std::error_code& ec) -{ - _path.replace_filename(p); - refresh(ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void directory_entry::refresh() -{ - std::error_code ec; - refresh(ec); - if (ec && (_status.type() == file_type::none || _symlink_status.type() != file_type::symlink)) { - throw filesystem_error(detail::systemErrorText(ec.value()), _path, ec); - } -} -#endif - -GHC_INLINE void directory_entry::refresh(std::error_code& ec) noexcept -{ -#ifdef GHC_OS_WINDOWS - _status = detail::status_ex(_path, ec, &_symlink_status, &_file_size, nullptr, &_last_write_time); -#else - _status = detail::status_ex(_path, ec, &_symlink_status, &_file_size, &_hard_link_count, &_last_write_time); -#endif -} - -// [fs.dir.entry.obs] directory_entry observers -GHC_INLINE const filesystem::path& directory_entry::path() const noexcept -{ - return _path; -} - -GHC_INLINE directory_entry::operator const filesystem::path&() const noexcept -{ - return _path; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_type directory_entry::status_file_type() const -{ - return _status.type() != file_type::none ? _status.type() : filesystem::status(path()).type(); -} -#endif - -GHC_INLINE file_type directory_entry::status_file_type(std::error_code& ec) const noexcept -{ - if (_status.type() != file_type::none) { - ec.clear(); - return _status.type(); - } - return filesystem::status(path(), ec).type(); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::exists() const -{ - return status_file_type() != file_type::not_found; -} -#endif - -GHC_INLINE bool directory_entry::exists(std::error_code& ec) const noexcept -{ - return status_file_type(ec) != file_type::not_found; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_block_file() const -{ - return status_file_type() == file_type::block; -} -#endif -GHC_INLINE bool directory_entry::is_block_file(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::block; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_character_file() const -{ - return status_file_type() == file_type::character; -} -#endif - -GHC_INLINE bool directory_entry::is_character_file(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::character; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_directory() const -{ - return status_file_type() == file_type::directory; -} -#endif - -GHC_INLINE bool directory_entry::is_directory(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::directory; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_fifo() const -{ - return status_file_type() == file_type::fifo; -} -#endif - -GHC_INLINE bool directory_entry::is_fifo(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::fifo; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_other() const -{ - auto ft = status_file_type(); - return ft != file_type::none && ft != file_type::not_found && ft != file_type::regular && ft != file_type::directory && !is_symlink(); -} -#endif - -GHC_INLINE bool directory_entry::is_other(std::error_code& ec) const noexcept -{ - auto ft = status_file_type(ec); - bool other = ft != file_type::none && ft != file_type::not_found && ft != file_type::regular && ft != file_type::directory && !is_symlink(ec); - return !ec && other; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_regular_file() const -{ - return status_file_type() == file_type::regular; -} -#endif - -GHC_INLINE bool directory_entry::is_regular_file(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::regular; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_socket() const -{ - return status_file_type() == file_type::socket; -} -#endif - -GHC_INLINE bool directory_entry::is_socket(std::error_code& ec) const noexcept -{ - return status_file_type(ec) == file_type::socket; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE bool directory_entry::is_symlink() const -{ - return _symlink_status.type() != file_type::none ? _symlink_status.type() == file_type::symlink : filesystem::is_symlink(symlink_status()); -} -#endif - -GHC_INLINE bool directory_entry::is_symlink(std::error_code& ec) const noexcept -{ - if (_symlink_status.type() != file_type::none) { - ec.clear(); - return _symlink_status.type() == file_type::symlink; - } - return filesystem::is_symlink(symlink_status(ec)); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t directory_entry::file_size() const -{ - if (_file_size != static_cast(-1)) { - return _file_size; - } - return filesystem::file_size(path()); -} -#endif - -GHC_INLINE uintmax_t directory_entry::file_size(std::error_code& ec) const noexcept -{ - if (_file_size != static_cast(-1)) { - ec.clear(); - return _file_size; - } - return filesystem::file_size(path(), ec); -} - -#ifndef GHC_OS_WEB -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE uintmax_t directory_entry::hard_link_count() const -{ -#ifndef GHC_OS_WINDOWS - if (_hard_link_count != static_cast(-1)) { - return _hard_link_count; - } -#endif - return filesystem::hard_link_count(path()); -} -#endif - -GHC_INLINE uintmax_t directory_entry::hard_link_count(std::error_code& ec) const noexcept -{ -#ifndef GHC_OS_WINDOWS - if (_hard_link_count != static_cast(-1)) { - ec.clear(); - return _hard_link_count; - } -#endif - return filesystem::hard_link_count(path(), ec); -} -#endif - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_time_type directory_entry::last_write_time() const -{ - if (_last_write_time != 0) { - return std::chrono::system_clock::from_time_t(_last_write_time); - } - return filesystem::last_write_time(path()); -} -#endif - -GHC_INLINE file_time_type directory_entry::last_write_time(std::error_code& ec) const noexcept -{ - if (_last_write_time != 0) { - ec.clear(); - return std::chrono::system_clock::from_time_t(_last_write_time); - } - return filesystem::last_write_time(path(), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status directory_entry::status() const -{ - if (_status.type() != file_type::none && _status.permissions() != perms::unknown) { - return _status; - } - return filesystem::status(path()); -} -#endif - -GHC_INLINE file_status directory_entry::status(std::error_code& ec) const noexcept -{ - if (_status.type() != file_type::none && _status.permissions() != perms::unknown) { - ec.clear(); - return _status; - } - return filesystem::status(path(), ec); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE file_status directory_entry::symlink_status() const -{ - if (_symlink_status.type() != file_type::none && _symlink_status.permissions() != perms::unknown) { - return _symlink_status; - } - return filesystem::symlink_status(path()); -} -#endif - -GHC_INLINE file_status directory_entry::symlink_status(std::error_code& ec) const noexcept -{ - if (_symlink_status.type() != file_type::none && _symlink_status.permissions() != perms::unknown) { - ec.clear(); - return _symlink_status; - } - return filesystem::symlink_status(path(), ec); -} - -#ifdef GHC_HAS_THREEWAY_COMP -GHC_INLINE std::strong_ordering directory_entry::operator<=>(const directory_entry& rhs) const noexcept -{ - return _path <=> rhs._path; -} -#endif - -GHC_INLINE bool directory_entry::operator<(const directory_entry& rhs) const noexcept -{ - return _path < rhs._path; -} - -GHC_INLINE bool directory_entry::operator==(const directory_entry& rhs) const noexcept -{ - return _path == rhs._path; -} - -GHC_INLINE bool directory_entry::operator!=(const directory_entry& rhs) const noexcept -{ - return _path != rhs._path; -} - -GHC_INLINE bool directory_entry::operator<=(const directory_entry& rhs) const noexcept -{ - return _path <= rhs._path; -} - -GHC_INLINE bool directory_entry::operator>(const directory_entry& rhs) const noexcept -{ - return _path > rhs._path; -} - -GHC_INLINE bool directory_entry::operator>=(const directory_entry& rhs) const noexcept -{ - return _path >= rhs._path; -} - -//----------------------------------------------------------------------------- -// [fs.class.directory_iterator] class directory_iterator - -#ifdef GHC_OS_WINDOWS -class directory_iterator::impl -{ -public: - impl(const path& p, directory_options options) - : _base(p) - , _options(options) - , _dirHandle(INVALID_HANDLE_VALUE) - { - if (!_base.empty()) { - ZeroMemory(&_findData, sizeof(WIN32_FIND_DATAW)); - if ((_dirHandle = FindFirstFileW(GHC_NATIVEWP((_base / "*")), &_findData)) != INVALID_HANDLE_VALUE) { - if (std::wstring(_findData.cFileName) == L"." || std::wstring(_findData.cFileName) == L"..") { - increment(_ec); - } - else { - _dir_entry._path = _base / std::wstring(_findData.cFileName); - copyToDirEntry(_ec); - } - } - else { - auto error = ::GetLastError(); - _base = filesystem::path(); - if (error != ERROR_ACCESS_DENIED || (options & directory_options::skip_permission_denied) == directory_options::none) { - _ec = detail::make_system_error(); - } - } - } - } - impl(const impl& other) = delete; - ~impl() - { - if (_dirHandle != INVALID_HANDLE_VALUE) { - FindClose(_dirHandle); - _dirHandle = INVALID_HANDLE_VALUE; - } - } - void increment(std::error_code& ec) - { - if (_dirHandle != INVALID_HANDLE_VALUE) { - do { - if (FindNextFileW(_dirHandle, &_findData)) { - _dir_entry._path = _base; -#ifdef GHC_USE_WCHAR_T - _dir_entry._path.append_name(_findData.cFileName); -#else -#ifdef GHC_RAISE_UNICODE_ERRORS - try { - _dir_entry._path.append_name(detail::toUtf8(_findData.cFileName).c_str()); - } - catch (filesystem_error& fe) { - ec = fe.code(); - return; - } -#else - _dir_entry._path.append_name(detail::toUtf8(_findData.cFileName).c_str()); -#endif -#endif - copyToDirEntry(ec); - } - else { - auto err = ::GetLastError(); - if (err != ERROR_NO_MORE_FILES) { - _ec = ec = detail::make_system_error(err); - } - FindClose(_dirHandle); - _dirHandle = INVALID_HANDLE_VALUE; - _dir_entry._path.clear(); - break; - } - } while (std::wstring(_findData.cFileName) == L"." || std::wstring(_findData.cFileName) == L".."); - } - else { - ec = _ec; - } - } - void copyToDirEntry(std::error_code& ec) - { - if (_findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - _dir_entry._status = detail::status_ex(_dir_entry._path, ec, &_dir_entry._symlink_status, &_dir_entry._file_size, nullptr, &_dir_entry._last_write_time); - } - else { - _dir_entry._status = detail::status_from_INFO(_dir_entry._path, &_findData, ec, &_dir_entry._file_size, &_dir_entry._last_write_time); - _dir_entry._symlink_status = _dir_entry._status; - } - if (ec) { - if (_dir_entry._status.type() != file_type::none && _dir_entry._symlink_status.type() != file_type::none) { - ec.clear(); - } - else { - _dir_entry._file_size = static_cast(-1); - _dir_entry._last_write_time = 0; - } - } - } - path _base; - directory_options _options; - WIN32_FIND_DATAW _findData; - HANDLE _dirHandle; - directory_entry _dir_entry; - std::error_code _ec; -}; -#else -// POSIX implementation -class directory_iterator::impl -{ -public: - impl(const path& path, directory_options options) - : _base(path) - , _options(options) - , _dir(nullptr) - , _entry(nullptr) - { - if (!path.empty()) { - do { _dir = ::opendir(path.native().c_str()); } while(errno == EINTR && !_dir); - if (!_dir) { - auto error = errno; - _base = filesystem::path(); - if ((error != EACCES && error != EPERM) || (options & directory_options::skip_permission_denied) == directory_options::none) { - _ec = detail::make_system_error(); - } - } - else { - increment(_ec); - } - } - } - impl(const impl& other) = delete; - ~impl() - { - if (_dir) { - ::closedir(_dir); - } - } - void increment(std::error_code& ec) - { - if (_dir) { - bool skip; - do { - skip = false; - errno = 0; - do { _entry = ::readdir(_dir); } while(errno == EINTR && !_entry); - if (_entry) { - _dir_entry._path = _base; - _dir_entry._path.append_name(_entry->d_name); - copyToDirEntry(); - if (ec && (ec.value() == EACCES || ec.value() == EPERM) && (_options & directory_options::skip_permission_denied) == directory_options::skip_permission_denied) { - ec.clear(); - skip = true; - } - } - else { - ::closedir(_dir); - _dir = nullptr; - _dir_entry._path.clear(); - if (errno && errno != EINTR) { - ec = detail::make_system_error(); - } - break; - } - } while (skip || std::strcmp(_entry->d_name, ".") == 0 || std::strcmp(_entry->d_name, "..") == 0); - } - } - - void copyToDirEntry() - { - _dir_entry._symlink_status.permissions(perms::unknown); - auto ft = detail::file_type_from_dirent(*_entry); - _dir_entry._symlink_status.type(ft); - if (ft != file_type::symlink) { - _dir_entry._status = _dir_entry._symlink_status; - } - else { - _dir_entry._status.type(file_type::none); - _dir_entry._status.permissions(perms::unknown); - } - _dir_entry._file_size = static_cast(-1); - _dir_entry._hard_link_count = static_cast(-1); - _dir_entry._last_write_time = 0; - } - path _base; - directory_options _options; - DIR* _dir; - struct ::dirent* _entry; - directory_entry _dir_entry; - std::error_code _ec; -}; -#endif - -// [fs.dir.itr.members] member functions -GHC_INLINE directory_iterator::directory_iterator() noexcept - : _impl(new impl(path(), directory_options::none)) -{ -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE directory_iterator::directory_iterator(const path& p) - : _impl(new impl(p, directory_options::none)) -{ - if (_impl->_ec) { - throw filesystem_error(detail::systemErrorText(_impl->_ec.value()), p, _impl->_ec); - } - _impl->_ec.clear(); -} - -GHC_INLINE directory_iterator::directory_iterator(const path& p, directory_options options) - : _impl(new impl(p, options)) -{ - if (_impl->_ec) { - throw filesystem_error(detail::systemErrorText(_impl->_ec.value()), p, _impl->_ec); - } -} -#endif - -GHC_INLINE directory_iterator::directory_iterator(const path& p, std::error_code& ec) noexcept - : _impl(new impl(p, directory_options::none)) -{ - if (_impl->_ec) { - ec = _impl->_ec; - } -} - -GHC_INLINE directory_iterator::directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept - : _impl(new impl(p, options)) -{ - if (_impl->_ec) { - ec = _impl->_ec; - } -} - -GHC_INLINE directory_iterator::directory_iterator(const directory_iterator& rhs) - : _impl(rhs._impl) -{ -} - -GHC_INLINE directory_iterator::directory_iterator(directory_iterator&& rhs) noexcept - : _impl(std::move(rhs._impl)) -{ -} - -GHC_INLINE directory_iterator::~directory_iterator() {} - -GHC_INLINE directory_iterator& directory_iterator::operator=(const directory_iterator& rhs) -{ - _impl = rhs._impl; - return *this; -} - -GHC_INLINE directory_iterator& directory_iterator::operator=(directory_iterator&& rhs) noexcept -{ - _impl = std::move(rhs._impl); - return *this; -} - -GHC_INLINE const directory_entry& directory_iterator::operator*() const -{ - return _impl->_dir_entry; -} - -GHC_INLINE const directory_entry* directory_iterator::operator->() const -{ - return &_impl->_dir_entry; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE directory_iterator& directory_iterator::operator++() -{ - std::error_code ec; - _impl->increment(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_entry._path, ec); - } - return *this; -} -#endif - -GHC_INLINE directory_iterator& directory_iterator::increment(std::error_code& ec) noexcept -{ - _impl->increment(ec); - return *this; -} - -GHC_INLINE bool directory_iterator::operator==(const directory_iterator& rhs) const -{ - return _impl->_dir_entry._path == rhs._impl->_dir_entry._path; -} - -GHC_INLINE bool directory_iterator::operator!=(const directory_iterator& rhs) const -{ - return _impl->_dir_entry._path != rhs._impl->_dir_entry._path; -} - -// [fs.dir.itr.nonmembers] directory_iterator non-member functions - -GHC_INLINE directory_iterator begin(directory_iterator iter) noexcept -{ - return iter; -} - -GHC_INLINE directory_iterator end(const directory_iterator&) noexcept -{ - return directory_iterator(); -} - -//----------------------------------------------------------------------------- -// [fs.class.rec.dir.itr] class recursive_directory_iterator - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator() noexcept - : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator()); -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p) - : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p)); -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, directory_options options) - : _impl(new recursive_directory_iterator_impl(options, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p, options)); -} -#endif - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept - : _impl(new recursive_directory_iterator_impl(options, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p, options, ec)); -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, std::error_code& ec) noexcept - : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) -{ - _impl->_dir_iter_stack.push(directory_iterator(p, ec)); -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const recursive_directory_iterator& rhs) - : _impl(rhs._impl) -{ -} - -GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept - : _impl(std::move(rhs._impl)) -{ -} - -GHC_INLINE recursive_directory_iterator::~recursive_directory_iterator() {} - -// [fs.rec.dir.itr.members] observers -GHC_INLINE directory_options recursive_directory_iterator::options() const -{ - return _impl->_options; -} - -GHC_INLINE int recursive_directory_iterator::depth() const -{ - return static_cast(_impl->_dir_iter_stack.size() - 1); -} - -GHC_INLINE bool recursive_directory_iterator::recursion_pending() const -{ - return _impl->_recursion_pending; -} - -GHC_INLINE const directory_entry& recursive_directory_iterator::operator*() const -{ - return *(_impl->_dir_iter_stack.top()); -} - -GHC_INLINE const directory_entry* recursive_directory_iterator::operator->() const -{ - return &(*(_impl->_dir_iter_stack.top())); -} - -// [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=(const recursive_directory_iterator& rhs) -{ - _impl = rhs._impl; - return *this; -} - -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=(recursive_directory_iterator&& rhs) noexcept -{ - _impl = std::move(rhs._impl); - return *this; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator++() -{ - std::error_code ec; - increment(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_iter_stack.empty() ? path() : _impl->_dir_iter_stack.top()->path(), ec); - } - return *this; -} -#endif - -GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::increment(std::error_code& ec) noexcept -{ - bool isSymLink = (*this)->is_symlink(ec); - bool isDir = !ec && (*this)->is_directory(ec); - if (isSymLink && detail::is_not_found_error(ec)) { - ec.clear(); - } - if (!ec) { - if (recursion_pending() && isDir && (!isSymLink || (options() & directory_options::follow_directory_symlink) != directory_options::none)) { - _impl->_dir_iter_stack.push(directory_iterator((*this)->path(), _impl->_options, ec)); - } - else { - _impl->_dir_iter_stack.top().increment(ec); - } - if (!ec) { - while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()) { - _impl->_dir_iter_stack.pop(); - _impl->_dir_iter_stack.top().increment(ec); - } - } - else if (!_impl->_dir_iter_stack.empty()) { - _impl->_dir_iter_stack.pop(); - } - _impl->_recursion_pending = true; - } - return *this; -} - -#ifdef GHC_WITH_EXCEPTIONS -GHC_INLINE void recursive_directory_iterator::pop() -{ - std::error_code ec; - pop(ec); - if (ec) { - throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_iter_stack.empty() ? path() : _impl->_dir_iter_stack.top()->path(), ec); - } -} -#endif - -GHC_INLINE void recursive_directory_iterator::pop(std::error_code& ec) -{ - if (depth() == 0) { - *this = recursive_directory_iterator(); - } - else { - do { - _impl->_dir_iter_stack.pop(); - _impl->_dir_iter_stack.top().increment(ec); - } while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()); - } -} - -GHC_INLINE void recursive_directory_iterator::disable_recursion_pending() -{ - _impl->_recursion_pending = false; -} - -// other members as required by [input.iterators] -GHC_INLINE bool recursive_directory_iterator::operator==(const recursive_directory_iterator& rhs) const -{ - return _impl->_dir_iter_stack.top() == rhs._impl->_dir_iter_stack.top(); -} - -GHC_INLINE bool recursive_directory_iterator::operator!=(const recursive_directory_iterator& rhs) const -{ - return _impl->_dir_iter_stack.top() != rhs._impl->_dir_iter_stack.top(); -} - -// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions -GHC_INLINE recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept -{ - return iter; -} - -GHC_INLINE recursive_directory_iterator end(const recursive_directory_iterator&) noexcept -{ - return recursive_directory_iterator(); -} - -#endif // GHC_EXPAND_IMPL - -} // namespace filesystem -} // namespace ghc - -// cleanup some macros -#undef GHC_INLINE -#undef GHC_EXPAND_IMPL - -#endif // GHC_FILESYSTEM_H diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index 8f73bad3..0b435b5e 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -41,7 +41,6 @@ #include "fuse_fgetattr.hpp" #include "fuse_flock.hpp" #include "fuse_flush.hpp" -#include "fuse_free_hide.hpp" #include "fuse_fsync.hpp" #include "fuse_fsyncdir.hpp" #include "fuse_ftruncate.hpp" @@ -58,7 +57,6 @@ #include "fuse_open.hpp" #include "fuse_opendir.hpp" #include "fuse_poll.hpp" -#include "fuse_prepare_hide.hpp" #include "fuse_read.hpp" #include "fuse_readdir.hpp" #include "fuse_readdir_plus.hpp" @@ -110,7 +108,6 @@ namespace l ops_.fgetattr = FUSE::fgetattr; ops_.flock = FUSE::flock; ops_.flush = FUSE::flush; - ops_.free_hide = FUSE::free_hide; ops_.fsync = FUSE::fsync; ops_.fsyncdir = FUSE::fsyncdir; ops_.ftruncate = FUSE::ftruncate; @@ -127,7 +124,6 @@ namespace l ops_.open = FUSE::open; ops_.opendir = FUSE::opendir; ops_.poll = FUSE::poll;; - ops_.prepare_hide = FUSE::prepare_hide; ops_.read = (nullrw_ ? FUSE::read_null : FUSE::read); ops_.readdir = FUSE::readdir; ops_.readdir_plus = FUSE::readdir_plus; diff --git a/src/nonstd/expected.hpp b/src/nonstd/expected.hpp deleted file mode 100644 index eb9e2ba7..00000000 --- a/src/nonstd/expected.hpp +++ /dev/null @@ -1,2537 +0,0 @@ -// This version targets C++11 and later. -// -// Copyright (C) 2016-2020 Martin Moene. -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// expected lite is based on: -// A proposal to add a utility class to represent expected monad -// by Vicente J. Botet Escriba and Pierre Talbot. http:://wg21.link/p0323 - -#ifndef NONSTD_EXPECTED_LITE_HPP -#define NONSTD_EXPECTED_LITE_HPP - -#define expected_lite_MAJOR 0 -#define expected_lite_MINOR 6 -#define expected_lite_PATCH 2 - -#define expected_lite_VERSION expected_STRINGIFY(expected_lite_MAJOR) "." expected_STRINGIFY(expected_lite_MINOR) "." expected_STRINGIFY(expected_lite_PATCH) - -#define expected_STRINGIFY( x ) expected_STRINGIFY_( x ) -#define expected_STRINGIFY_( x ) #x - -// expected-lite configuration: - -#define nsel_EXPECTED_DEFAULT 0 -#define nsel_EXPECTED_NONSTD 1 -#define nsel_EXPECTED_STD 2 - -// tweak header support: - -#ifdef __has_include -# if __has_include() -# include -# endif -#define expected_HAVE_TWEAK_HEADER 1 -#else -#define expected_HAVE_TWEAK_HEADER 0 -//# pragma message("expected.hpp: Note: Tweak header not supported.") -#endif - -// expected selection and configuration: - -#if !defined( nsel_CONFIG_SELECT_EXPECTED ) -# define nsel_CONFIG_SELECT_EXPECTED ( nsel_HAVE_STD_EXPECTED ? nsel_EXPECTED_STD : nsel_EXPECTED_NONSTD ) -#endif - -// Proposal revisions: -// -// DXXXXR0: -- -// N4015 : -2 (2014-05-26) -// N4109 : -1 (2014-06-29) -// P0323R0: 0 (2016-05-28) -// P0323R1: 1 (2016-10-12) -// -------: -// P0323R2: 2 (2017-06-15) -// P0323R3: 3 (2017-10-15) -// P0323R4: 4 (2017-11-26) -// P0323R5: 5 (2018-02-08) -// P0323R6: 6 (2018-04-02) -// P0323R7: 7 (2018-06-22) * -// -// expected-lite uses 2 and higher - -#ifndef nsel_P0323R -# define nsel_P0323R 7 -#endif - -// Control presence of C++ exception handling (try and auto discover): - -#ifndef nsel_CONFIG_NO_EXCEPTIONS -# if defined(_MSC_VER) -# include // for _HAS_EXCEPTIONS -# endif -# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) -# define nsel_CONFIG_NO_EXCEPTIONS 0 -# else -# define nsel_CONFIG_NO_EXCEPTIONS 1 -# endif -#endif - -// at default use SEH with MSVC for no C++ exceptions - -#ifndef nsel_CONFIG_NO_EXCEPTIONS_SEH -# define nsel_CONFIG_NO_EXCEPTIONS_SEH ( nsel_CONFIG_NO_EXCEPTIONS && _MSC_VER ) -#endif - -// C++ language version detection (C++23 is speculative): -// Note: VC14.0/1900 (VS2015) lacks too much from C++14. - -#ifndef nsel_CPLUSPLUS -# if defined(_MSVC_LANG ) && !defined(__clang__) -# define nsel_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) -# else -# define nsel_CPLUSPLUS __cplusplus -# endif -#endif - -#define nsel_CPP98_OR_GREATER ( nsel_CPLUSPLUS >= 199711L ) -#define nsel_CPP11_OR_GREATER ( nsel_CPLUSPLUS >= 201103L ) -#define nsel_CPP14_OR_GREATER ( nsel_CPLUSPLUS >= 201402L ) -#define nsel_CPP17_OR_GREATER ( nsel_CPLUSPLUS >= 201703L ) -#define nsel_CPP20_OR_GREATER ( nsel_CPLUSPLUS >= 202002L ) -#define nsel_CPP23_OR_GREATER ( nsel_CPLUSPLUS >= 202300L ) - -// Use C++23 std::expected if available and requested: - -#if nsel_CPP23_OR_GREATER && defined(__has_include ) -# if __has_include( ) -# define nsel_HAVE_STD_EXPECTED 1 -# else -# define nsel_HAVE_STD_EXPECTED 0 -# endif -#else -# define nsel_HAVE_STD_EXPECTED 0 -#endif - -#define nsel_USES_STD_EXPECTED ( (nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_STD) || ((nsel_CONFIG_SELECT_EXPECTED == nsel_EXPECTED_DEFAULT) && nsel_HAVE_STD_EXPECTED) ) - -// -// in_place: code duplicated in any-lite, expected-lite, expected-lite, value-ptr-lite, variant-lite: -// - -#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES -#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 - -// C++17 std::in_place in : - -#if nsel_CPP17_OR_GREATER - -#include - -namespace nonstd { - -using std::in_place; -using std::in_place_type; -using std::in_place_index; -using std::in_place_t; -using std::in_place_type_t; -using std::in_place_index_t; - -#define nonstd_lite_in_place_t( T) std::in_place_t -#define nonstd_lite_in_place_type_t( T) std::in_place_type_t -#define nonstd_lite_in_place_index_t(K) std::in_place_index_t - -#define nonstd_lite_in_place( T) std::in_place_t{} -#define nonstd_lite_in_place_type( T) std::in_place_type_t{} -#define nonstd_lite_in_place_index(K) std::in_place_index_t{} - -} // namespace nonstd - -#else // nsel_CPP17_OR_GREATER - -#include - -namespace nonstd { -namespace detail { - -template< class T > -struct in_place_type_tag {}; - -template< std::size_t K > -struct in_place_index_tag {}; - -} // namespace detail - -struct in_place_t {}; - -template< class T > -inline in_place_t in_place( detail::in_place_type_tag = detail::in_place_type_tag() ) -{ - return in_place_t(); -} - -template< std::size_t K > -inline in_place_t in_place( detail::in_place_index_tag = detail::in_place_index_tag() ) -{ - return in_place_t(); -} - -template< class T > -inline in_place_t in_place_type( detail::in_place_type_tag = detail::in_place_type_tag() ) -{ - return in_place_t(); -} - -template< std::size_t K > -inline in_place_t in_place_index( detail::in_place_index_tag = detail::in_place_index_tag() ) -{ - return in_place_t(); -} - -// mimic templated typedef: - -#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) -#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) -#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) - -#define nonstd_lite_in_place( T) nonstd::in_place_type -#define nonstd_lite_in_place_type( T) nonstd::in_place_type -#define nonstd_lite_in_place_index(K) nonstd::in_place_index - -} // namespace nonstd - -#endif // nsel_CPP17_OR_GREATER -#endif // nonstd_lite_HAVE_IN_PLACE_TYPES - -// -// Using std::expected: -// - -#if nsel_USES_STD_EXPECTED - -#include - -namespace nonstd { - - using std::expected; -// ... -} - -#else // nsel_USES_STD_EXPECTED - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// additional includes: - -#if nsel_CONFIG_NO_EXCEPTIONS -# if nsel_CONFIG_NO_EXCEPTIONS_SEH -# include // for ExceptionCodes -# else -// already included: -# endif -#else -# include -#endif - -// C++ feature usage: - -#if nsel_CPP11_OR_GREATER -# define nsel_constexpr constexpr -#else -# define nsel_constexpr /*constexpr*/ -#endif - -#if nsel_CPP14_OR_GREATER -# define nsel_constexpr14 constexpr -#else -# define nsel_constexpr14 /*constexpr*/ -#endif - -#if nsel_CPP17_OR_GREATER -# define nsel_inline17 inline -#else -# define nsel_inline17 /*inline*/ -#endif - -// Compiler versions: -// -// MSVC++ 6.0 _MSC_VER == 1200 nsel_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) -// MSVC++ 7.0 _MSC_VER == 1300 nsel_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) -// MSVC++ 7.1 _MSC_VER == 1310 nsel_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) -// MSVC++ 8.0 _MSC_VER == 1400 nsel_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) -// MSVC++ 9.0 _MSC_VER == 1500 nsel_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) -// MSVC++ 10.0 _MSC_VER == 1600 nsel_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) -// MSVC++ 11.0 _MSC_VER == 1700 nsel_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) -// MSVC++ 12.0 _MSC_VER == 1800 nsel_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) -// MSVC++ 14.0 _MSC_VER == 1900 nsel_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) -// MSVC++ 14.1 _MSC_VER >= 1910 nsel_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) -// MSVC++ 14.2 _MSC_VER >= 1920 nsel_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) - -#if defined(_MSC_VER) && !defined(__clang__) -# define nsel_COMPILER_MSVC_VER (_MSC_VER ) -# define nsel_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) ) -#else -# define nsel_COMPILER_MSVC_VER 0 -# define nsel_COMPILER_MSVC_VERSION 0 -#endif - -#define nsel_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) - -#if defined(__clang__) -# define nsel_COMPILER_CLANG_VERSION nsel_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) -#else -# define nsel_COMPILER_CLANG_VERSION 0 -#endif - -#if defined(__GNUC__) && !defined(__clang__) -# define nsel_COMPILER_GNUC_VERSION nsel_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#else -# define nsel_COMPILER_GNUC_VERSION 0 -#endif - -// half-open range [lo..hi): -//#define nsel_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) - -// Method enabling - -#define nsel_REQUIRES_0(...) \ - template< bool B = (__VA_ARGS__), typename std::enable_if::type = 0 > - -#define nsel_REQUIRES_T(...) \ - , typename std::enable_if< (__VA_ARGS__), int >::type = 0 - -#define nsel_REQUIRES_R(R, ...) \ - typename std::enable_if< (__VA_ARGS__), R>::type - -#define nsel_REQUIRES_A(...) \ - , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr - -// Presence of language and library features: - -#ifdef _HAS_CPP0X -# define nsel_HAS_CPP0X _HAS_CPP0X -#else -# define nsel_HAS_CPP0X 0 -#endif - -//#define nsel_CPP11_140 (nsel_CPP11_OR_GREATER || nsel_COMPILER_MSVC_VER >= 1900) - -// Clang, GNUC, MSVC warning suppression macros: - -#ifdef __clang__ -# pragma clang diagnostic push -#elif defined __GNUC__ -# pragma GCC diagnostic push -#endif // __clang__ - -#if nsel_COMPILER_MSVC_VERSION >= 140 -# pragma warning( push ) -# define nsel_DISABLE_MSVC_WARNINGS(codes) __pragma( warning(disable: codes) ) -#else -# define nsel_DISABLE_MSVC_WARNINGS(codes) -#endif - -#ifdef __clang__ -# define nsel_RESTORE_WARNINGS() _Pragma("clang diagnostic pop") -#elif defined __GNUC__ -# define nsel_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop") -#elif nsel_COMPILER_MSVC_VERSION >= 140 -# define nsel_RESTORE_WARNINGS() __pragma( warning( pop ) ) -#else -# define nsel_RESTORE_WARNINGS() -#endif - -// Suppress the following MSVC (GSL) warnings: -// - C26409: Avoid calling new and delete explicitly, use std::make_unique instead (r.11) - -nsel_DISABLE_MSVC_WARNINGS( 26409 ) - -// -// expected: -// - -namespace nonstd { namespace expected_lite { - -// type traits C++17: - -namespace std17 { - -#if nsel_CPP17_OR_GREATER - -using std::conjunction; -using std::is_swappable; -using std::is_nothrow_swappable; - -#else // nsel_CPP17_OR_GREATER - -namespace detail { - -using std::swap; - -struct is_swappable -{ - template< typename T, typename = decltype( swap( std::declval(), std::declval() ) ) > - static std::true_type test( int /* unused */); - - template< typename > - static std::false_type test(...); -}; - -struct is_nothrow_swappable -{ - // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015): - - template< typename T > - static constexpr bool satisfies() - { - return noexcept( swap( std::declval(), std::declval() ) ); - } - - template< typename T > - static auto test( int ) -> std::integral_constant()>{} - - template< typename > - static auto test(...) -> std::false_type; -}; -} // namespace detail - -// is [nothow] swappable: - -template< typename T > -struct is_swappable : decltype( detail::is_swappable::test(0) ){}; - -template< typename T > -struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test(0) ){}; - -// conjunction: - -template< typename... > struct conjunction : std::true_type{}; -template< typename B1 > struct conjunction : B1{}; - -template< typename B1, typename... Bn > -struct conjunction : std::conditional, B1>::type{}; - -#endif // nsel_CPP17_OR_GREATER - -} // namespace std17 - -// type traits C++20: - -namespace std20 { - -#if defined(__cpp_lib_remove_cvref) - -using std::remove_cvref; - -#else - -template< typename T > -struct remove_cvref -{ - typedef typename std::remove_cv< typename std::remove_reference::type >::type type; -}; - -#endif - -} // namespace std20 - -// forward declaration: - -template< typename T, typename E > -class expected; - -namespace detail { - -/// discriminated union to hold value or 'error'. - -template< typename T, typename E > -class storage_t_impl -{ - template< typename, typename > friend class nonstd::expected_lite::expected; - -public: - using value_type = T; - using error_type = E; - - // no-op construction - storage_t_impl() {} - ~storage_t_impl() {} - - explicit storage_t_impl( bool has_value ) - : m_has_value( has_value ) - {} - - void construct_value( value_type const & e ) - { - new( &m_value ) value_type( e ); - } - - void construct_value( value_type && e ) - { - new( &m_value ) value_type( std::move( e ) ); - } - - template< class... Args > - void emplace_value( Args&&... args ) - { - new( &m_value ) value_type( std::forward(args)...); - } - - template< class U, class... Args > - void emplace_value( std::initializer_list il, Args&&... args ) - { - new( &m_value ) value_type( il, std::forward(args)... ); - } - - void destruct_value() - { - m_value.~value_type(); - } - - void construct_error( error_type const & e ) - { - new( &m_error ) error_type( e ); - } - - void construct_error( error_type && e ) - { - new( &m_error ) error_type( std::move( e ) ); - } - - template< class... Args > - void emplace_error( Args&&... args ) - { - new( &m_error ) error_type( std::forward(args)...); - } - - template< class U, class... Args > - void emplace_error( std::initializer_list il, Args&&... args ) - { - new( &m_error ) error_type( il, std::forward(args)... ); - } - - void destruct_error() - { - m_error.~error_type(); - } - - constexpr value_type const & value() const & - { - return m_value; - } - - value_type & value() & - { - return m_value; - } - - constexpr value_type const && value() const && - { - return std::move( m_value ); - } - - nsel_constexpr14 value_type && value() && - { - return std::move( m_value ); - } - - value_type const * value_ptr() const - { - return &m_value; - } - - value_type * value_ptr() - { - return &m_value; - } - - error_type const & error() const & - { - return m_error; - } - - error_type & error() & - { - return m_error; - } - - constexpr error_type const && error() const && - { - return std::move( m_error ); - } - - nsel_constexpr14 error_type && error() && - { - return std::move( m_error ); - } - - bool has_value() const - { - return m_has_value; - } - - void set_has_value( bool v ) - { - m_has_value = v; - } - -private: - union - { - value_type m_value; - error_type m_error; - }; - - bool m_has_value = false; -}; - -/// discriminated union to hold only 'error'. - -template< typename E > -struct storage_t_impl -{ - template< typename, typename > friend class nonstd::expected_lite::expected; - -public: - using value_type = void; - using error_type = E; - - // no-op construction - storage_t_impl() {} - ~storage_t_impl() {} - - explicit storage_t_impl( bool has_value ) - : m_has_value( has_value ) - {} - - void construct_error( error_type const & e ) - { - new( &m_error ) error_type( e ); - } - - void construct_error( error_type && e ) - { - new( &m_error ) error_type( std::move( e ) ); - } - - template< class... Args > - void emplace_error( Args&&... args ) - { - new( &m_error ) error_type( std::forward(args)...); - } - - template< class U, class... Args > - void emplace_error( std::initializer_list il, Args&&... args ) - { - new( &m_error ) error_type( il, std::forward(args)... ); - } - - void destruct_error() - { - m_error.~error_type(); - } - - error_type const & error() const & - { - return m_error; - } - - error_type & error() & - { - return m_error; - } - - constexpr error_type const && error() const && - { - return std::move( m_error ); - } - - nsel_constexpr14 error_type && error() && - { - return std::move( m_error ); - } - - bool has_value() const - { - return m_has_value; - } - - void set_has_value( bool v ) - { - m_has_value = v; - } - -private: - union - { - char m_dummy; - error_type m_error; - }; - - bool m_has_value = false; -}; - -template< typename T, typename E, bool isConstructable, bool isMoveable > -class storage_t -{ -public: - storage_t() = default; - ~storage_t() = default; - - explicit storage_t( bool has_value ) - : storage_t_impl( has_value ) - {} - - storage_t( storage_t const & other ) = delete; - storage_t( storage_t && other ) = delete; -}; - -template< typename T, typename E > -class storage_t : public storage_t_impl -{ -public: - storage_t() = default; - ~storage_t() = default; - - explicit storage_t( bool has_value ) - : storage_t_impl( has_value ) - {} - - storage_t( storage_t const & other ) - : storage_t_impl( other.has_value() ) - { - if ( this->has_value() ) this->construct_value( other.value() ); - else this->construct_error( other.error() ); - } - - storage_t(storage_t && other ) - : storage_t_impl( other.has_value() ) - { - if ( this->has_value() ) this->construct_value( std::move( other.value() ) ); - else this->construct_error( std::move( other.error() ) ); - } -}; - -template< typename E > -class storage_t : public storage_t_impl -{ -public: - storage_t() = default; - ~storage_t() = default; - - explicit storage_t( bool has_value ) - : storage_t_impl( has_value ) - {} - - storage_t( storage_t const & other ) - : storage_t_impl( other.has_value() ) - { - if ( this->has_value() ) ; - else this->construct_error( other.error() ); - } - - storage_t(storage_t && other ) - : storage_t_impl( other.has_value() ) - { - if ( this->has_value() ) ; - else this->construct_error( std::move( other.error() ) ); - } -}; - -template< typename T, typename E > -class storage_t : public storage_t_impl -{ -public: - storage_t() = default; - ~storage_t() = default; - - explicit storage_t( bool has_value ) - : storage_t_impl( has_value ) - {} - - storage_t( storage_t const & other ) - : storage_t_impl(other.has_value()) - { - if ( this->has_value() ) this->construct_value( other.value() ); - else this->construct_error( other.error() ); - } - - storage_t( storage_t && other ) = delete; -}; - -template< typename E > -class storage_t : public storage_t_impl -{ -public: - storage_t() = default; - ~storage_t() = default; - - explicit storage_t( bool has_value ) - : storage_t_impl( has_value ) - {} - - storage_t( storage_t const & other ) - : storage_t_impl(other.has_value()) - { - if ( this->has_value() ) ; - else this->construct_error( other.error() ); - } - - storage_t( storage_t && other ) = delete; -}; - -template< typename T, typename E > -class storage_t : public storage_t_impl -{ -public: - storage_t() = default; - ~storage_t() = default; - - explicit storage_t( bool has_value ) - : storage_t_impl( has_value ) - {} - - storage_t( storage_t const & other ) = delete; - - storage_t( storage_t && other ) - : storage_t_impl( other.has_value() ) - { - if ( this->has_value() ) this->construct_value( std::move( other.value() ) ); - else this->construct_error( std::move( other.error() ) ); - } -}; - -template< typename E > -class storage_t : public storage_t_impl -{ -public: - storage_t() = default; - ~storage_t() = default; - - explicit storage_t( bool has_value ) - : storage_t_impl( has_value ) - {} - - storage_t( storage_t const & other ) = delete; - - storage_t( storage_t && other ) - : storage_t_impl( other.has_value() ) - { - if ( this->has_value() ) ; - else this->construct_error( std::move( other.error() ) ); - } -}; - -} // namespace detail - -/// x.x.5 Unexpected object type; unexpected_type; C++17 and later can also use aliased type unexpected. - -#if nsel_P0323R <= 2 -template< typename E = std::exception_ptr > -class unexpected_type -#else -template< typename E > -class unexpected_type -#endif // nsel_P0323R -{ -public: - using error_type = E; - - // x.x.5.2.1 Constructors - -// unexpected_type() = delete; - - constexpr unexpected_type( unexpected_type const & ) = default; - constexpr unexpected_type( unexpected_type && ) = default; - - template< typename... Args - nsel_REQUIRES_T( - std::is_constructible::value - ) - > - constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), Args &&... args ) - : m_error( std::forward( args )...) - {} - - template< typename U, typename... Args - nsel_REQUIRES_T( - std::is_constructible, Args&&...>::value - ) - > - constexpr explicit unexpected_type( nonstd_lite_in_place_t(E), std::initializer_list il, Args &&... args ) - : m_error( il, std::forward( args )...) - {} - - template< typename E2 - nsel_REQUIRES_T( - std::is_constructible::value - && !std::is_same< typename std20::remove_cvref::type, nonstd_lite_in_place_t(E2) >::value - && !std::is_same< typename std20::remove_cvref::type, unexpected_type >::value - ) - > - constexpr explicit unexpected_type( E2 && error ) - : m_error( std::forward( error ) ) - {} - - template< typename E2 - nsel_REQUIRES_T( - std::is_constructible< E, E2>::value - && !std::is_constructible & >::value - && !std::is_constructible >::value - && !std::is_constructible const & >::value - && !std::is_constructible const >::value - && !std::is_convertible< unexpected_type &, E>::value - && !std::is_convertible< unexpected_type , E>::value - && !std::is_convertible< unexpected_type const &, E>::value - && !std::is_convertible< unexpected_type const , E>::value - && !std::is_convertible< E2 const &, E>::value /*=> explicit */ - ) - > - constexpr explicit unexpected_type( unexpected_type const & error ) - : m_error( E{ error.value() } ) - {} - - template< typename E2 - nsel_REQUIRES_T( - std::is_constructible< E, E2>::value - && !std::is_constructible & >::value - && !std::is_constructible >::value - && !std::is_constructible const & >::value - && !std::is_constructible const >::value - && !std::is_convertible< unexpected_type &, E>::value - && !std::is_convertible< unexpected_type , E>::value - && !std::is_convertible< unexpected_type const &, E>::value - && !std::is_convertible< unexpected_type const , E>::value - && std::is_convertible< E2 const &, E>::value /*=> explicit */ - ) - > - constexpr /*non-explicit*/ unexpected_type( unexpected_type const & error ) - : m_error( error.value() ) - {} - - template< typename E2 - nsel_REQUIRES_T( - std::is_constructible< E, E2>::value - && !std::is_constructible & >::value - && !std::is_constructible >::value - && !std::is_constructible const & >::value - && !std::is_constructible const >::value - && !std::is_convertible< unexpected_type &, E>::value - && !std::is_convertible< unexpected_type , E>::value - && !std::is_convertible< unexpected_type const &, E>::value - && !std::is_convertible< unexpected_type const , E>::value - && !std::is_convertible< E2 const &, E>::value /*=> explicit */ - ) - > - constexpr explicit unexpected_type( unexpected_type && error ) - : m_error( E{ std::move( error.value() ) } ) - {} - - template< typename E2 - nsel_REQUIRES_T( - std::is_constructible< E, E2>::value - && !std::is_constructible & >::value - && !std::is_constructible >::value - && !std::is_constructible const & >::value - && !std::is_constructible const >::value - && !std::is_convertible< unexpected_type &, E>::value - && !std::is_convertible< unexpected_type , E>::value - && !std::is_convertible< unexpected_type const &, E>::value - && !std::is_convertible< unexpected_type const , E>::value - && std::is_convertible< E2 const &, E>::value /*=> non-explicit */ - ) - > - constexpr /*non-explicit*/ unexpected_type( unexpected_type && error ) - : m_error( std::move( error.value() ) ) - {} - - // x.x.5.2.2 Assignment - - nsel_constexpr14 unexpected_type& operator=( unexpected_type const & ) = default; - nsel_constexpr14 unexpected_type& operator=( unexpected_type && ) = default; - - template< typename E2 = E > - nsel_constexpr14 unexpected_type & operator=( unexpected_type const & other ) - { - unexpected_type{ other.value() }.swap( *this ); - return *this; - } - - template< typename E2 = E > - nsel_constexpr14 unexpected_type & operator=( unexpected_type && other ) - { - unexpected_type{ std::move( other.value() ) }.swap( *this ); - return *this; - } - - // x.x.5.2.3 Observers - - nsel_constexpr14 E & value() & noexcept - { - return m_error; - } - - constexpr E const & value() const & noexcept - { - return m_error; - } - -#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 - - nsel_constexpr14 E && value() && noexcept - { - return std::move( m_error ); - } - - constexpr E const && value() const && noexcept - { - return std::move( m_error ); - } - -#endif - - // x.x.5.2.4 Swap - - template< typename U=E > - nsel_REQUIRES_R( void, - std17::is_swappable::value - ) - swap( unexpected_type & other ) noexcept ( - std17::is_nothrow_swappable::value - ) - { - using std::swap; - swap( m_error, other.m_error ); - } - - // TODO: ??? unexpected_type: in-class friend operator==, != - -private: - error_type m_error; -}; - -#if nsel_CPP17_OR_GREATER - -/// template deduction guide: - -template< typename E > -unexpected_type( E ) -> unexpected_type< E >; - -#endif - -/// class unexpected_type, std::exception_ptr specialization (P0323R2) - -#if !nsel_CONFIG_NO_EXCEPTIONS -#if nsel_P0323R <= 2 - -// TODO: Should expected be specialized for particular E types such as exception_ptr and how? -// See p0323r7 2.1. Ergonomics, http://wg21.link/p0323 -template<> -class unexpected_type< std::exception_ptr > -{ -public: - using error_type = std::exception_ptr; - - unexpected_type() = delete; - - ~unexpected_type(){} - - explicit unexpected_type( std::exception_ptr const & error ) - : m_error( error ) - {} - - explicit unexpected_type(std::exception_ptr && error ) - : m_error( std::move( error ) ) - {} - - template< typename E > - explicit unexpected_type( E error ) - : m_error( std::make_exception_ptr( error ) ) - {} - - std::exception_ptr const & value() const - { - return m_error; - } - - std::exception_ptr & value() - { - return m_error; - } - -private: - std::exception_ptr m_error; -}; - -#endif // nsel_P0323R -#endif // !nsel_CONFIG_NO_EXCEPTIONS - -/// x.x.4, Unexpected equality operators - -template< typename E1, typename E2 > -constexpr bool operator==( unexpected_type const & x, unexpected_type const & y ) -{ - return x.value() == y.value(); -} - -template< typename E1, typename E2 > -constexpr bool operator!=( unexpected_type const & x, unexpected_type const & y ) -{ - return ! ( x == y ); -} - -#if nsel_P0323R <= 2 - -template< typename E > -constexpr bool operator<( unexpected_type const & x, unexpected_type const & y ) -{ - return x.value() < y.value(); -} - -template< typename E > -constexpr bool operator>( unexpected_type const & x, unexpected_type const & y ) -{ - return ( y < x ); -} - -template< typename E > -constexpr bool operator<=( unexpected_type const & x, unexpected_type const & y ) -{ - return ! ( y < x ); -} - -template< typename E > -constexpr bool operator>=( unexpected_type const & x, unexpected_type const & y ) -{ - return ! ( x < y ); -} - -#endif // nsel_P0323R - -/// x.x.5 Specialized algorithms - -template< typename E - nsel_REQUIRES_T( - std17::is_swappable::value - ) -> -void swap( unexpected_type & x, unexpected_type & y) noexcept ( noexcept ( x.swap(y) ) ) -{ - x.swap( y ); -} - -#if nsel_P0323R <= 2 - -// unexpected: relational operators for std::exception_ptr: - -inline constexpr bool operator<( unexpected_type const & /*x*/, unexpected_type const & /*y*/ ) -{ - return false; -} - -inline constexpr bool operator>( unexpected_type const & /*x*/, unexpected_type const & /*y*/ ) -{ - return false; -} - -inline constexpr bool operator<=( unexpected_type const & x, unexpected_type const & y ) -{ - return ( x == y ); -} - -inline constexpr bool operator>=( unexpected_type const & x, unexpected_type const & y ) -{ - return ( x == y ); -} - -#endif // nsel_P0323R - -// unexpected: traits - -#if nsel_P0323R <= 3 - -template< typename E> -struct is_unexpected : std::false_type {}; - -template< typename E> -struct is_unexpected< unexpected_type > : std::true_type {}; - -#endif // nsel_P0323R - -// unexpected: factory - -// keep make_unexpected() removed in p0323r2 for pre-C++17: - -template< typename E> -nsel_constexpr14 auto -make_unexpected( E && value ) -> unexpected_type< typename std::decay::type > -{ - return unexpected_type< typename std::decay::type >( std::forward(value) ); -} - -#if nsel_P0323R <= 3 - -/*nsel_constexpr14*/ auto inline -make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr > -{ - return unexpected_type< std::exception_ptr >( std::current_exception() ); -} - -#endif // nsel_P0323R - -/// x.x.6, x.x.7 expected access error - -template< typename E > -class bad_expected_access; - -/// x.x.7 bad_expected_access: expected access error - -template <> -class bad_expected_access< void > : public std::exception -{ -public: - explicit bad_expected_access() - : std::exception() - {} -}; - -/// x.x.6 bad_expected_access: expected access error - -#if !nsel_CONFIG_NO_EXCEPTIONS - -template< typename E > -class bad_expected_access : public bad_expected_access< void > -{ -public: - using error_type = E; - - explicit bad_expected_access( error_type error ) - : m_error( error ) - {} - - virtual char const * what() const noexcept override - { - return "bad_expected_access"; - } - - nsel_constexpr14 error_type & error() & - { - return m_error; - } - - constexpr error_type const & error() const & - { - return m_error; - } - -#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 - - nsel_constexpr14 error_type && error() && - { - return std::move( m_error ); - } - - constexpr error_type const && error() const && - { - return std::move( m_error ); - } - -#endif - -private: - error_type m_error; -}; - -#endif // nsel_CONFIG_NO_EXCEPTIONS - -/// x.x.8 unexpect tag, in_place_unexpected tag: construct an error - -struct unexpect_t{}; -using in_place_unexpected_t = unexpect_t; - -nsel_inline17 constexpr unexpect_t unexpect{}; -nsel_inline17 constexpr unexpect_t in_place_unexpected{}; - -/// class error_traits - -#if nsel_CONFIG_NO_EXCEPTIONS - -namespace detail { - inline bool text( char const * /*text*/ ) { return true; } -} - -template< typename Error > -struct error_traits -{ - static void rethrow( Error const & /*e*/ ) - { -#if nsel_CONFIG_NO_EXCEPTIONS_SEH - RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL ); -#else - assert( false && detail::text("throw bad_expected_access{ e };") ); -#endif - } -}; - -template<> -struct error_traits< std::exception_ptr > -{ - static void rethrow( std::exception_ptr const & /*e*/ ) - { -#if nsel_CONFIG_NO_EXCEPTIONS_SEH - RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL ); -#else - assert( false && detail::text("throw bad_expected_access{ e };") ); -#endif - } -}; - -template<> -struct error_traits< std::error_code > -{ - static void rethrow( std::error_code const & /*e*/ ) - { -#if nsel_CONFIG_NO_EXCEPTIONS_SEH - RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL ); -#else - assert( false && detail::text("throw std::system_error( e );") ); -#endif - } -}; - -#else // nsel_CONFIG_NO_EXCEPTIONS - -template< typename Error > -struct error_traits -{ - static void rethrow( Error const & e ) - { - throw bad_expected_access{ e }; - } -}; - -template<> -struct error_traits< std::exception_ptr > -{ - static void rethrow( std::exception_ptr const & e ) - { - std::rethrow_exception( e ); - } -}; - -template<> -struct error_traits< std::error_code > -{ - static void rethrow( std::error_code const & e ) - { - throw std::system_error( e ); - } -}; - -#endif // nsel_CONFIG_NO_EXCEPTIONS - -} // namespace expected_lite - -// provide nonstd::unexpected_type: - -using expected_lite::unexpected_type; - -namespace expected_lite { - -/// class expected - -#if nsel_P0323R <= 2 -template< typename T, typename E = std::exception_ptr > -class expected -#else -template< typename T, typename E > -class expected -#endif // nsel_P0323R -{ -private: - template< typename, typename > friend class expected; - -public: - using value_type = T; - using error_type = E; - using unexpected_type = nonstd::unexpected_type; - - template< typename U > - struct rebind - { - using type = expected; - }; - - // x.x.4.1 constructors - - nsel_REQUIRES_0( - std::is_default_constructible::value - ) - nsel_constexpr14 expected() - : contained( true ) - { - contained.construct_value( value_type() ); - } - - nsel_constexpr14 expected( expected const & ) = default; - nsel_constexpr14 expected( expected && ) = default; - - template< typename U, typename G - nsel_REQUIRES_T( - std::is_constructible< T, U const &>::value - && std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< expected & , T>::value - && !std::is_convertible< expected &&, T>::value - && !std::is_convertible< expected const & , T>::value - && !std::is_convertible< expected const &&, T>::value - && (!std::is_convertible::value || !std::is_convertible::value ) /*=> explicit */ - ) - > - nsel_constexpr14 explicit expected( expected const & other ) - : contained( other.has_value() ) - { - if ( has_value() ) contained.construct_value( T{ other.contained.value() } ); - else contained.construct_error( E{ other.contained.error() } ); - } - - template< typename U, typename G - nsel_REQUIRES_T( - std::is_constructible< T, U const &>::value - && std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< expected & , T>::value - && !std::is_convertible< expected &&, T>::value - && !std::is_convertible< expected const &, T>::value - && !std::is_convertible< expected const &&, T>::value - && !(!std::is_convertible::value || !std::is_convertible::value ) /*=> non-explicit */ - ) - > - nsel_constexpr14 /*non-explicit*/ expected( expected const & other ) - : contained( other.has_value() ) - { - if ( has_value() ) contained.construct_value( other.contained.value() ); - else contained.construct_error( other.contained.error() ); - } - - template< typename U, typename G - nsel_REQUIRES_T( - std::is_constructible< T, U>::value - && std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< expected & , T>::value - && !std::is_convertible< expected &&, T>::value - && !std::is_convertible< expected const & , T>::value - && !std::is_convertible< expected const &&, T>::value - && (!std::is_convertible::value || !std::is_convertible::value ) /*=> explicit */ - ) - > - nsel_constexpr14 explicit expected( expected && other ) - : contained( other.has_value() ) - { - if ( has_value() ) contained.construct_value( T{ std::move( other.contained.value() ) } ); - else contained.construct_error( E{ std::move( other.contained.error() ) } ); - } - - template< typename U, typename G - nsel_REQUIRES_T( - std::is_constructible< T, U>::value - && std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< expected & , T>::value - && !std::is_convertible< expected &&, T>::value - && !std::is_convertible< expected const & , T>::value - && !std::is_convertible< expected const &&, T>::value - && !(!std::is_convertible::value || !std::is_convertible::value ) /*=> non-explicit */ - ) - > - nsel_constexpr14 /*non-explicit*/ expected( expected && other ) - : contained( other.has_value() ) - { - if ( has_value() ) contained.construct_value( std::move( other.contained.value() ) ); - else contained.construct_error( std::move( other.contained.error() ) ); - } - - template< typename U = T - nsel_REQUIRES_T( - std::is_copy_constructible::value - ) - > - nsel_constexpr14 expected( value_type const & value ) - : contained( true ) - { - contained.construct_value( value ); - } - - template< typename U = T - nsel_REQUIRES_T( - std::is_constructible::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same< expected , typename std20::remove_cvref::type>::value - && !std::is_same, typename std20::remove_cvref::type>::value - && !std::is_convertible::value /*=> explicit */ - ) - > - nsel_constexpr14 explicit expected( U && value ) noexcept - ( - std::is_nothrow_move_constructible::value && - std::is_nothrow_move_constructible::value - ) - : contained( true ) - { - contained.construct_value( T{ std::forward( value ) } ); - } - - template< typename U = T - nsel_REQUIRES_T( - std::is_constructible::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same< expected , typename std20::remove_cvref::type>::value - && !std::is_same, typename std20::remove_cvref::type>::value - && std::is_convertible::value /*=> non-explicit */ - ) - > - nsel_constexpr14 /*non-explicit*/ expected( U && value ) noexcept - ( - std::is_nothrow_move_constructible::value && - std::is_nothrow_move_constructible::value - ) - : contained( true ) - { - contained.construct_value( std::forward( value ) ); - } - - // construct error: - - template< typename G = E - nsel_REQUIRES_T( - std::is_constructible::value - && !std::is_convertible< G const &, E>::value /*=> explicit */ - ) - > - nsel_constexpr14 explicit expected( nonstd::unexpected_type const & error ) - : contained( false ) - { - contained.construct_error( E{ error.value() } ); - } - - template< typename G = E - nsel_REQUIRES_T( - std::is_constructible::value - && std::is_convertible< G const &, E>::value /*=> non-explicit */ - ) - > - nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type const & error ) - : contained( false ) - { - contained.construct_error( error.value() ); - } - - template< typename G = E - nsel_REQUIRES_T( - std::is_constructible::value - && !std::is_convertible< G&&, E>::value /*=> explicit */ - ) - > - nsel_constexpr14 explicit expected( nonstd::unexpected_type && error ) - : contained( false ) - { - contained.construct_error( E{ std::move( error.value() ) } ); - } - - template< typename G = E - nsel_REQUIRES_T( - std::is_constructible::value - && std::is_convertible< G&&, E>::value /*=> non-explicit */ - ) - > - nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type && error ) - : contained( false ) - { - contained.construct_error( std::move( error.value() ) ); - } - - // in-place construction, value - - template< typename... Args - nsel_REQUIRES_T( - std::is_constructible::value - ) - > - nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), Args&&... args ) - : contained( true ) - { - contained.emplace_value( std::forward( args )... ); - } - - template< typename U, typename... Args - nsel_REQUIRES_T( - std::is_constructible, Args&&...>::value - ) - > - nsel_constexpr14 explicit expected( nonstd_lite_in_place_t(T), std::initializer_list il, Args&&... args ) - : contained( true ) - { - contained.emplace_value( il, std::forward( args )... ); - } - - // in-place construction, error - - template< typename... Args - nsel_REQUIRES_T( - std::is_constructible::value - ) - > - nsel_constexpr14 explicit expected( unexpect_t, Args&&... args ) - : contained( false ) - { - contained.emplace_error( std::forward( args )... ); - } - - template< typename U, typename... Args - nsel_REQUIRES_T( - std::is_constructible, Args&&...>::value - ) - > - nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list il, Args&&... args ) - : contained( false ) - { - contained.emplace_error( il, std::forward( args )... ); - } - - // x.x.4.2 destructor - - // TODO: ~expected: triviality - // Effects: If T is not cv void and is_trivially_destructible_v is false and bool(*this), calls val.~T(). If is_trivially_destructible_v is false and !bool(*this), calls unexpect.~unexpected(). - // Remarks: If either T is cv void or is_trivially_destructible_v is true, and is_trivially_destructible_v is true, then this destructor shall be a trivial destructor. - - ~expected() - { - if ( has_value() ) contained.destruct_value(); - else contained.destruct_error(); - } - - // x.x.4.3 assignment - - expected & operator=( expected const & other ) - { - expected( other ).swap( *this ); - return *this; - } - - expected & operator=( expected && other ) noexcept - ( - std::is_nothrow_move_constructible< T>::value - && std::is_nothrow_move_assignable< T>::value - && std::is_nothrow_move_constructible::value // added for missing - && std::is_nothrow_move_assignable< E>::value ) // nothrow above - { - expected( std::move( other ) ).swap( *this ); - return *this; - } - - template< typename U - nsel_REQUIRES_T( - !std::is_same, typename std20::remove_cvref::type>::value - && std17::conjunction, std::is_same> >::value - && std::is_constructible::value - && std::is_assignable< T&,U>::value - && std::is_nothrow_move_constructible::value ) - > - expected & operator=( U && value ) - { - expected( std::forward( value ) ).swap( *this ); - return *this; - } - - template< typename G = E - nsel_REQUIRES_T( - std::is_constructible::value && - std::is_copy_constructible::value // TODO: std::is_nothrow_copy_constructible - && std::is_copy_assignable::value - ) - > - expected & operator=( nonstd::unexpected_type const & error ) - { - expected( unexpect, error.value() ).swap( *this ); - return *this; - } - - template< typename G = E - nsel_REQUIRES_T( - std::is_constructible::value && - std::is_move_constructible::value // TODO: std::is_nothrow_move_constructible - && std::is_move_assignable::value - ) - > - expected & operator=( nonstd::unexpected_type && error ) - { - expected( unexpect, std::move( error.value() ) ).swap( *this ); - return *this; - } - - template< typename... Args - nsel_REQUIRES_T( - std::is_nothrow_constructible::value - ) - > - value_type & emplace( Args &&... args ) - { - expected( nonstd_lite_in_place(T), std::forward(args)... ).swap( *this ); - return value(); - } - - template< typename U, typename... Args - nsel_REQUIRES_T( - std::is_nothrow_constructible&, Args&&...>::value - ) - > - value_type & emplace( std::initializer_list il, Args &&... args ) - { - expected( nonstd_lite_in_place(T), il, std::forward(args)... ).swap( *this ); - return value(); - } - - // x.x.4.4 swap - - template< typename U=T, typename G=E > - nsel_REQUIRES_R( void, - std17::is_swappable< U>::value - && std17::is_swappable::value - && ( std::is_move_constructible::value || std::is_move_constructible::value ) - ) - swap( expected & other ) noexcept - ( - std::is_nothrow_move_constructible::value && std17::is_nothrow_swappable::value && - std::is_nothrow_move_constructible::value && std17::is_nothrow_swappable::value - ) - { - using std::swap; - - if ( bool(*this) && bool(other) ) { swap( contained.value(), other.contained.value() ); } - else if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); } - else if ( bool(*this) && ! bool(other) ) { error_type t( std::move( other.error() ) ); - other.contained.destruct_error(); - other.contained.construct_value( std::move( contained.value() ) ); - contained.destruct_value(); - contained.construct_error( std::move( t ) ); - bool has_value = contained.has_value(); - bool other_has_value = other.has_value(); - other.contained.set_has_value(has_value); - contained.set_has_value(other_has_value); - } - else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); } - } - - // x.x.4.5 observers - - constexpr value_type const * operator ->() const - { - return assert( has_value() ), contained.value_ptr(); - } - - value_type * operator ->() - { - return assert( has_value() ), contained.value_ptr(); - } - - constexpr value_type const & operator *() const & - { - return assert( has_value() ), contained.value(); - } - - value_type & operator *() & - { - return assert( has_value() ), contained.value(); - } - -#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 - - constexpr value_type const && operator *() const && - { - return std::move( ( assert( has_value() ), contained.value() ) ); - } - - nsel_constexpr14 value_type && operator *() && - { - return std::move( ( assert( has_value() ), contained.value() ) ); - } - -#endif - - constexpr explicit operator bool() const noexcept - { - return has_value(); - } - - constexpr bool has_value() const noexcept - { - return contained.has_value(); - } - - constexpr value_type const & value() const & - { - return has_value() - ? ( contained.value() ) - : ( error_traits::rethrow( contained.error() ), contained.value() ); - } - - value_type & value() & - { - return has_value() - ? ( contained.value() ) - : ( error_traits::rethrow( contained.error() ), contained.value() ); - } - -#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 - - constexpr value_type const && value() const && - { - return std::move( has_value() - ? ( contained.value() ) - : ( error_traits::rethrow( contained.error() ), contained.value() ) ); - } - - nsel_constexpr14 value_type && value() && - { - return std::move( has_value() - ? ( contained.value() ) - : ( error_traits::rethrow( contained.error() ), contained.value() ) ); - } - -#endif - - constexpr error_type const & error() const & - { - return assert( ! has_value() ), contained.error(); - } - - error_type & error() & - { - return assert( ! has_value() ), contained.error(); - } - -#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 - - constexpr error_type const && error() const && - { - return std::move( ( assert( ! has_value() ), contained.error() ) ); - } - - error_type && error() && - { - return std::move( ( assert( ! has_value() ), contained.error() ) ); - } - -#endif - - constexpr unexpected_type get_unexpected() const - { - return make_unexpected( contained.error() ); - } - - template< typename Ex > - bool has_exception() const - { - using ContainedEx = typename std::remove_reference< decltype( get_unexpected().value() ) >::type; - return ! has_value() && std::is_base_of< Ex, ContainedEx>::value; - } - - template< typename U - nsel_REQUIRES_T( - std::is_copy_constructible< T>::value - && std::is_convertible::value - ) - > - value_type value_or( U && v ) const & - { - return has_value() - ? contained.value() - : static_cast( std::forward( v ) ); - } - - template< typename U - nsel_REQUIRES_T( - std::is_move_constructible< T>::value - && std::is_convertible::value - ) - > - value_type value_or( U && v ) && - { - return has_value() - ? std::move( contained.value() ) - : static_cast( std::forward( v ) ); - } - - // unwrap() - -// template -// constexpr expected expected,E>::unwrap() const&; - -// template -// constexpr expected expected::unwrap() const&; - -// template -// expected expected, E>::unwrap() &&; - -// template -// template expected expected::unwrap() &&; - - // factories - -// template< typename Ex, typename F> -// expected catch_exception(F&& f); - -// template< typename F> -// expected())),E> map(F&& func) ; - -// template< typename F> -// 'see below' bind(F&& func); - -// template< typename F> -// expected catch_error(F&& f); - -// template< typename F> -// 'see below' then(F&& func); - -private: - detail::storage_t - < - T - ,E - , std::is_copy_constructible::value && std::is_copy_constructible::value - , std::is_move_constructible::value && std::is_move_constructible::value - > - contained; -}; - -/// class expected, void specialization - -template< typename E > -class expected -{ -private: - template< typename, typename > friend class expected; - -public: - using value_type = void; - using error_type = E; - using unexpected_type = nonstd::unexpected_type; - - // x.x.4.1 constructors - - constexpr expected() noexcept - : contained( true ) - {} - - nsel_constexpr14 expected( expected const & other ) = default; - nsel_constexpr14 expected( expected && other ) = default; - - constexpr explicit expected( nonstd_lite_in_place_t(void) ) - : contained( true ) - {} - - template< typename G = E - nsel_REQUIRES_T( - !std::is_convertible::value /*=> explicit */ - ) - > - nsel_constexpr14 explicit expected( nonstd::unexpected_type const & error ) - : contained( false ) - { - contained.construct_error( E{ error.value() } ); - } - - template< typename G = E - nsel_REQUIRES_T( - std::is_convertible::value /*=> non-explicit */ - ) - > - nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type const & error ) - : contained( false ) - { - contained.construct_error( error.value() ); - } - - template< typename G = E - nsel_REQUIRES_T( - !std::is_convertible::value /*=> explicit */ - ) - > - nsel_constexpr14 explicit expected( nonstd::unexpected_type && error ) - : contained( false ) - { - contained.construct_error( E{ std::move( error.value() ) } ); - } - - template< typename G = E - nsel_REQUIRES_T( - std::is_convertible::value /*=> non-explicit */ - ) - > - nsel_constexpr14 /*non-explicit*/ expected( nonstd::unexpected_type && error ) - : contained( false ) - { - contained.construct_error( std::move( error.value() ) ); - } - - template< typename... Args - nsel_REQUIRES_T( - std::is_constructible::value - ) - > - nsel_constexpr14 explicit expected( unexpect_t, Args&&... args ) - : contained( false ) - { - contained.emplace_error( std::forward( args )... ); - } - - template< typename U, typename... Args - nsel_REQUIRES_T( - std::is_constructible, Args&&...>::value - ) - > - nsel_constexpr14 explicit expected( unexpect_t, std::initializer_list il, Args&&... args ) - : contained( false ) - { - contained.emplace_error( il, std::forward( args )... ); - } - - // destructor - - ~expected() - { - if ( ! has_value() ) - { - contained.destruct_error(); - } - } - - // x.x.4.3 assignment - - expected & operator=( expected const & other ) - { - expected( other ).swap( *this ); - return *this; - } - - expected & operator=( expected && other ) noexcept - ( - std::is_nothrow_move_assignable::value && - std::is_nothrow_move_constructible::value ) - { - expected( std::move( other ) ).swap( *this ); - return *this; - } - - void emplace() - { - expected().swap( *this ); - } - - // x.x.4.4 swap - - template< typename G = E > - nsel_REQUIRES_R( void, - std17::is_swappable::value - && std::is_move_constructible::value - ) - swap( expected & other ) noexcept - ( - std::is_nothrow_move_constructible::value && std17::is_nothrow_swappable::value - ) - { - using std::swap; - - if ( ! bool(*this) && ! bool(other) ) { swap( contained.error(), other.contained.error() ); } - else if ( bool(*this) && ! bool(other) ) { contained.construct_error( std::move( other.error() ) ); - bool has_value = contained.has_value(); - bool other_has_value = other.has_value(); - other.contained.set_has_value(has_value); - contained.set_has_value(other_has_value); - } - else if ( ! bool(*this) && bool(other) ) { other.swap( *this ); } - } - - // x.x.4.5 observers - - constexpr explicit operator bool() const noexcept - { - return has_value(); - } - - constexpr bool has_value() const noexcept - { - return contained.has_value(); - } - - void value() const - { - if ( ! has_value() ) - { - error_traits::rethrow( contained.error() ); - } - } - - constexpr error_type const & error() const & - { - return assert( ! has_value() ), contained.error(); - } - - error_type & error() & - { - return assert( ! has_value() ), contained.error(); - } - -#if !nsel_COMPILER_GNUC_VERSION || nsel_COMPILER_GNUC_VERSION >= 490 - - constexpr error_type const && error() const && - { - return std::move( ( assert( ! has_value() ), contained.error() ) ); - } - - error_type && error() && - { - return std::move( ( assert( ! has_value() ), contained.error() ) ); - } - -#endif - - constexpr unexpected_type get_unexpected() const - { - return make_unexpected( contained.error() ); - } - - template< typename Ex > - bool has_exception() const - { - using ContainedEx = typename std::remove_reference< decltype( get_unexpected().value() ) >::type; - return ! has_value() && std::is_base_of< Ex, ContainedEx>::value; - } - -// template constexpr 'see below' unwrap() const&; -// -// template 'see below' unwrap() &&; - - // factories - -// template< typename Ex, typename F> -// expected catch_exception(F&& f); -// -// template< typename F> -// expected map(F&& func) ; -// -// template< typename F> -// 'see below' bind(F&& func) ; -// -// template< typename F> -// expected catch_error(F&& f); -// -// template< typename F> -// 'see below' then(F&& func); - -private: - detail::storage_t - < - void - , E - , std::is_copy_constructible::value - , std::is_move_constructible::value - > - contained; -}; - -// x.x.4.6 expected<>: comparison operators - -template< typename T1, typename E1, typename T2, typename E2 - nsel_REQUIRES_T( - !std::is_void::value && !std::is_void::value - ) -> -constexpr bool operator==( expected const & x, expected const & y ) -{ - return bool(x) != bool(y) ? false : bool(x) ? *x == *y : x.error() == y.error(); -} - -template< typename T1, typename E1, typename T2, typename E2 - nsel_REQUIRES_T( - std::is_void::value && std::is_void::value - ) -> -constexpr bool operator==( expected const & x, expected const & y ) -{ - return bool(x) != bool(y) ? false : bool(x) || static_cast( x.error() == y.error() ); -} - -template< typename T1, typename E1, typename T2, typename E2 > -constexpr bool operator!=( expected const & x, expected const & y ) -{ - return !(x == y); -} - -#if nsel_P0323R <= 2 - -template< typename T, typename E > -constexpr bool operator<( expected const & x, expected const & y ) -{ - return (!y) ? false : (!x) ? true : *x < *y; -} - -template< typename T, typename E > -constexpr bool operator>( expected const & x, expected const & y ) -{ - return (y < x); -} - -template< typename T, typename E > -constexpr bool operator<=( expected const & x, expected const & y ) -{ - return !(y < x); -} - -template< typename T, typename E > -constexpr bool operator>=( expected const & x, expected const & y ) -{ - return !(x < y); -} - -#endif - -// x.x.4.7 expected: comparison with T - -template< typename T1, typename E1, typename T2 - nsel_REQUIRES_T( - !std::is_void::value - ) -> -constexpr bool operator==( expected const & x, T2 const & v ) -{ - return bool(x) ? *x == v : false; -} - -template< typename T1, typename E1, typename T2 - nsel_REQUIRES_T( - !std::is_void::value - ) -> -constexpr bool operator==(T2 const & v, expected const & x ) -{ - return bool(x) ? v == *x : false; -} - -template< typename T1, typename E1, typename T2 > -constexpr bool operator!=( expected const & x, T2 const & v ) -{ - return bool(x) ? *x != v : true; -} - -template< typename T1, typename E1, typename T2 > -constexpr bool operator!=( T2 const & v, expected const & x ) -{ - return bool(x) ? v != *x : true; -} - -#if nsel_P0323R <= 2 - -template< typename T, typename E > -constexpr bool operator<( expected const & x, T const & v ) -{ - return bool(x) ? *x < v : true; -} - -template< typename T, typename E > -constexpr bool operator<( T const & v, expected const & x ) -{ - return bool(x) ? v < *x : false; -} - -template< typename T, typename E > -constexpr bool operator>( T const & v, expected const & x ) -{ - return bool(x) ? *x < v : false; -} - -template< typename T, typename E > -constexpr bool operator>( expected const & x, T const & v ) -{ - return bool(x) ? v < *x : false; -} - -template< typename T, typename E > -constexpr bool operator<=( T const & v, expected const & x ) -{ - return bool(x) ? ! ( *x < v ) : false; -} - -template< typename T, typename E > -constexpr bool operator<=( expected const & x, T const & v ) -{ - return bool(x) ? ! ( v < *x ) : true; -} - -template< typename T, typename E > -constexpr bool operator>=( expected const & x, T const & v ) -{ - return bool(x) ? ! ( *x < v ) : false; -} - -template< typename T, typename E > -constexpr bool operator>=( T const & v, expected const & x ) -{ - return bool(x) ? ! ( v < *x ) : true; -} - -#endif // nsel_P0323R - -// x.x.4.8 expected: comparison with unexpected_type - -template< typename T1, typename E1 , typename E2 > -constexpr bool operator==( expected const & x, unexpected_type const & u ) -{ - return (!x) ? x.get_unexpected() == u : false; -} - -template< typename T1, typename E1 , typename E2 > -constexpr bool operator==( unexpected_type const & u, expected const & x ) -{ - return ( x == u ); -} - -template< typename T1, typename E1 , typename E2 > -constexpr bool operator!=( expected const & x, unexpected_type const & u ) -{ - return ! ( x == u ); -} - -template< typename T1, typename E1 , typename E2 > -constexpr bool operator!=( unexpected_type const & u, expected const & x ) -{ - return ! ( x == u ); -} - -#if nsel_P0323R <= 2 - -template< typename T, typename E > -constexpr bool operator<( expected const & x, unexpected_type const & u ) -{ - return (!x) ? ( x.get_unexpected() < u ) : false; -} - -template< typename T, typename E > -constexpr bool operator<( unexpected_type const & u, expected const & x ) -{ - return (!x) ? ( u < x.get_unexpected() ) : true ; -} - -template< typename T, typename E > -constexpr bool operator>( expected const & x, unexpected_type const & u ) -{ - return ( u < x ); -} - -template< typename T, typename E > -constexpr bool operator>( unexpected_type const & u, expected const & x ) -{ - return ( x < u ); -} - -template< typename T, typename E > -constexpr bool operator<=( expected const & x, unexpected_type const & u ) -{ - return ! ( u < x ); -} - -template< typename T, typename E > -constexpr bool operator<=( unexpected_type const & u, expected const & x) -{ - return ! ( x < u ); -} - -template< typename T, typename E > -constexpr bool operator>=( expected const & x, unexpected_type const & u ) -{ - return ! ( u > x ); -} - -template< typename T, typename E > -constexpr bool operator>=( unexpected_type const & u, expected const & x ) -{ - return ! ( x > u ); -} - -#endif // nsel_P0323R - -/// x.x.x Specialized algorithms - -template< typename T, typename E - nsel_REQUIRES_T( - ( std::is_void::value || std::is_move_constructible::value ) - && std::is_move_constructible::value - && std17::is_swappable::value - && std17::is_swappable::value ) -> -void swap( expected & x, expected & y ) noexcept ( noexcept ( x.swap(y) ) ) -{ - x.swap( y ); -} - -#if nsel_P0323R <= 3 - -template< typename T > -constexpr auto make_expected( T && v ) -> expected< typename std::decay::type > -{ - return expected< typename std::decay::type >( std::forward( v ) ); -} - -// expected specialization: - -auto inline make_expected() -> expected -{ - return expected( in_place ); -} - -template< typename T > -constexpr auto make_expected_from_current_exception() -> expected -{ - return expected( make_unexpected_from_current_exception() ); -} - -template< typename T > -auto make_expected_from_exception( std::exception_ptr v ) -> expected -{ - return expected( unexpected_type( std::forward( v ) ) ); -} - -template< typename T, typename E > -constexpr auto make_expected_from_error( E e ) -> expected::type> -{ - return expected::type>( make_unexpected( e ) ); -} - -template< typename F - nsel_REQUIRES_T( ! std::is_same::type, void>::value ) -> -/*nsel_constexpr14*/ -auto make_expected_from_call( F f ) -> expected< typename std::result_of::type > -{ - try - { - return make_expected( f() ); - } - catch (...) - { - return make_unexpected_from_current_exception(); - } -} - -template< typename F - nsel_REQUIRES_T( std::is_same::type, void>::value ) -> -/*nsel_constexpr14*/ -auto make_expected_from_call( F f ) -> expected -{ - try - { - f(); - return make_expected(); - } - catch (...) - { - return make_unexpected_from_current_exception(); - } -} - -#endif // nsel_P0323R - -} // namespace expected_lite - -using namespace expected_lite; - -// using expected_lite::expected; -// using ... - -} // namespace nonstd - -namespace std { - -// expected: hash support - -template< typename T, typename E > -struct hash< nonstd::expected > -{ - using result_type = std::size_t; - using argument_type = nonstd::expected; - - constexpr result_type operator()(argument_type const & arg) const - { - return arg ? std::hash{}(*arg) : result_type{}; - } -}; - -// TBD - ?? remove? see spec. -template< typename T, typename E > -struct hash< nonstd::expected > -{ - using result_type = std::size_t; - using argument_type = nonstd::expected; - - constexpr result_type operator()(argument_type const & arg) const - { - return arg ? std::hash{}(*arg) : result_type{}; - } -}; - -// TBD - implement -// bool(e), hash>()(e) shall evaluate to the hashing true; -// otherwise it evaluates to an unspecified value if E is exception_ptr or -// a combination of hashing false and hash()(e.error()). - -template< typename E > -struct hash< nonstd::expected > -{ -}; - -} // namespace std - -namespace nonstd { - -// void unexpected() is deprecated && removed in C++17 - -#if nsel_CPP17_OR_GREATER || nsel_COMPILER_MSVC_VERSION > 141 -template< typename E > -using unexpected = unexpected_type; -#endif - -} // namespace nonstd - -#undef nsel_REQUIRES -#undef nsel_REQUIRES_0 -#undef nsel_REQUIRES_T - -nsel_RESTORE_WARNINGS() - -#endif // nsel_USES_STD_EXPECTED - -#endif // NONSTD_EXPECTED_LITE_HPP diff --git a/src/nonstd/string_view.hpp b/src/nonstd/string_view.hpp deleted file mode 100644 index 6ccb08ae..00000000 --- a/src/nonstd/string_view.hpp +++ /dev/null @@ -1,1709 +0,0 @@ -// Copyright 2017-2020 by Martin Moene -// -// string-view lite, a C++17-like string_view for C++98 and later. -// For more information see https://github.com/martinmoene/string-view-lite -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#pragma once - -#ifndef NONSTD_SV_LITE_H_INCLUDED -#define NONSTD_SV_LITE_H_INCLUDED - -#define string_view_lite_MAJOR 1 -#define string_view_lite_MINOR 8 -#define string_view_lite_PATCH 0 - -#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH) - -#define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x ) -#define nssv_STRINGIFY_( x ) #x - -// string-view lite configuration: - -#define nssv_STRING_VIEW_DEFAULT 0 -#define nssv_STRING_VIEW_NONSTD 1 -#define nssv_STRING_VIEW_STD 2 - -// tweak header support: - -#ifdef __has_include -# if __has_include() -# include -# endif -#define nssv_HAVE_TWEAK_HEADER 1 -#else -#define nssv_HAVE_TWEAK_HEADER 0 -//# pragma message("string_view.hpp: Note: Tweak header not supported.") -#endif - -// string_view selection and configuration: - -#if !defined( nssv_CONFIG_SELECT_STRING_VIEW ) -# define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD ) -#endif - -#ifndef nssv_CONFIG_STD_SV_OPERATOR -# define nssv_CONFIG_STD_SV_OPERATOR 0 -#endif - -#ifndef nssv_CONFIG_USR_SV_OPERATOR -# define nssv_CONFIG_USR_SV_OPERATOR 1 -#endif - -#ifdef nssv_CONFIG_CONVERSION_STD_STRING -# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING -# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING -#endif - -#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS -# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1 -#endif - -#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS -# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1 -#endif - -#ifndef nssv_CONFIG_NO_STREAM_INSERTION -# define nssv_CONFIG_NO_STREAM_INSERTION 0 -#endif - -#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH -# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1 -#endif - -// Control presence of exception handling (try and auto discover): - -#ifndef nssv_CONFIG_NO_EXCEPTIONS -# if defined(_MSC_VER) -# include // for _HAS_EXCEPTIONS -# endif -# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) -# define nssv_CONFIG_NO_EXCEPTIONS 0 -# else -# define nssv_CONFIG_NO_EXCEPTIONS 1 -# endif -#endif - -// C++ language version detection (C++23 is speculative): -// Note: VC14.0/1900 (VS2015) lacks too much from C++14. - -#ifndef nssv_CPLUSPLUS -# if defined(_MSVC_LANG ) && !defined(__clang__) -# define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) -# else -# define nssv_CPLUSPLUS __cplusplus -# endif -#endif - -#define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L ) -#define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L ) -#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L ) -#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L ) -#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L ) -#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202002L ) -#define nssv_CPP23_OR_GREATER ( nssv_CPLUSPLUS >= 202300L ) - -// use C++17 std::string_view if available and requested: - -#if nssv_CPP17_OR_GREATER && defined(__has_include ) -# if __has_include( ) -# define nssv_HAVE_STD_STRING_VIEW 1 -# else -# define nssv_HAVE_STD_STRING_VIEW 0 -# endif -#else -# define nssv_HAVE_STD_STRING_VIEW 0 -#endif - -#define nssv_USES_STD_STRING_VIEW ( (nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW) ) - -#define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW ) -#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH - -// -// Use C++17 std::string_view: -// - -#if nssv_USES_STD_STRING_VIEW - -#include - -// Extensions for std::string: - -#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -#include - -namespace nonstd { - -template< class CharT, class Traits, class Allocator = std::allocator > -std::basic_string -to_string( std::basic_string_view v, Allocator const & a = Allocator() ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -template< class CharT, class Traits, class Allocator > -std::basic_string_view -to_string_view( std::basic_string const & s ) -{ - return std::basic_string_view( s.data(), s.size() ); -} - -// Literal operators sv and _sv: - -#if nssv_CONFIG_STD_SV_OPERATOR - -using namespace std::literals::string_view_literals; - -#endif - -#if nssv_CONFIG_USR_SV_OPERATOR - -inline namespace literals { -inline namespace string_view_literals { - - -constexpr std::string_view operator""_sv( const char* str, size_t len ) noexcept // (1) -{ - return std::string_view{ str, len }; -} - -constexpr std::u16string_view operator""_sv( const char16_t* str, size_t len ) noexcept // (2) -{ - return std::u16string_view{ str, len }; -} - -constexpr std::u32string_view operator""_sv( const char32_t* str, size_t len ) noexcept // (3) -{ - return std::u32string_view{ str, len }; -} - -constexpr std::wstring_view operator""_sv( const wchar_t* str, size_t len ) noexcept // (4) -{ - return std::wstring_view{ str, len }; -} - -}} // namespace literals::string_view_literals - -#endif // nssv_CONFIG_USR_SV_OPERATOR - -} // namespace nonstd - -#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -namespace nonstd { - -using std::string_view; -using std::wstring_view; -using std::u16string_view; -using std::u32string_view; -using std::basic_string_view; - -// literal "sv" and "_sv", see above - -using std::operator==; -using std::operator!=; -using std::operator<; -using std::operator<=; -using std::operator>; -using std::operator>=; - -using std::operator<<; - -} // namespace nonstd - -#else // nssv_HAVE_STD_STRING_VIEW - -// -// Before C++17: use string_view lite: -// - -// Compiler versions: -// -// MSVC++ 6.0 _MSC_VER == 1200 nssv_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) -// MSVC++ 7.0 _MSC_VER == 1300 nssv_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) -// MSVC++ 7.1 _MSC_VER == 1310 nssv_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) -// MSVC++ 8.0 _MSC_VER == 1400 nssv_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) -// MSVC++ 9.0 _MSC_VER == 1500 nssv_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) -// MSVC++ 10.0 _MSC_VER == 1600 nssv_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) -// MSVC++ 11.0 _MSC_VER == 1700 nssv_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) -// MSVC++ 12.0 _MSC_VER == 1800 nssv_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) -// MSVC++ 14.0 _MSC_VER == 1900 nssv_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) -// MSVC++ 14.1 _MSC_VER >= 1910 nssv_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) -// MSVC++ 14.2 _MSC_VER >= 1920 nssv_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) - -#if defined(_MSC_VER ) && !defined(__clang__) -# define nssv_COMPILER_MSVC_VER (_MSC_VER ) -# define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) -#else -# define nssv_COMPILER_MSVC_VER 0 -# define nssv_COMPILER_MSVC_VERSION 0 -#endif - -#define nssv_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) ) - -#if defined( __apple_build_version__ ) -# define nssv_COMPILER_APPLECLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) -# define nssv_COMPILER_CLANG_VERSION 0 -#elif defined( __clang__ ) -# define nssv_COMPILER_APPLECLANG_VERSION 0 -# define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) -#else -# define nssv_COMPILER_APPLECLANG_VERSION 0 -# define nssv_COMPILER_CLANG_VERSION 0 -#endif - -#if defined(__GNUC__) && !defined(__clang__) -# define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#else -# define nssv_COMPILER_GNUC_VERSION 0 -#endif - -// half-open range [lo..hi): -#define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) - -// Presence of language and library features: - -#ifdef _HAS_CPP0X -# define nssv_HAS_CPP0X _HAS_CPP0X -#else -# define nssv_HAS_CPP0X 0 -#endif - -// Unless defined otherwise below, consider VC14 as C++11 for string-view-lite: - -#if nssv_COMPILER_MSVC_VER >= 1900 -# undef nssv_CPP11_OR_GREATER -# define nssv_CPP11_OR_GREATER 1 -#endif - -#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500) -#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600) -#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700) -#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800) -#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900) -#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910) - -#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER) -#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER) - -// Presence of C++11 language features: - -#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140 -#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140 -#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140 -#define nssv_HAVE_IS_DEFAULT nssv_CPP11_140 -#define nssv_HAVE_IS_DELETE nssv_CPP11_140 -#define nssv_HAVE_NOEXCEPT nssv_CPP11_140 -#define nssv_HAVE_NULLPTR nssv_CPP11_100 -#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140 -#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140 -#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140 -#define nssv_HAVE_WCHAR16_T nssv_CPP11_100 -#define nssv_HAVE_WCHAR32_T nssv_CPP11_100 - -#if ! ( ( nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) ) -# define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140 -#else -# define nssv_HAVE_STD_DEFINED_LITERALS 0 -#endif - -// Presence of C++14 language features: - -#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000 - -// Presence of C++17 language features: - -#define nssv_HAVE_NODISCARD nssv_CPP17_000 - -// Presence of C++ library features: - -#define nssv_HAVE_STD_HASH nssv_CPP11_120 - -// Presence of compiler intrinsics: - -// Providing char-type specializations for compare() and length() that -// use compiler intrinsics can improve compile- and run-time performance. -// -// The challenge is in using the right combinations of builtin availability -// and its constexpr-ness. -// -// | compiler | __builtin_memcmp (constexpr) | memcmp (constexpr) | -// |----------|------------------------------|---------------------| -// | clang | 4.0 (>= 4.0 ) | any (? ) | -// | clang-a | 9.0 (>= 9.0 ) | any (? ) | -// | gcc | any (constexpr) | any (? ) | -// | msvc | >= 14.2 C++17 (>= 14.2 ) | any (? ) | - -#define nssv_HAVE_BUILTIN_VER ( (nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || nssv_COMPILER_APPLECLANG_VERSION >= 900 ) -#define nssv_HAVE_BUILTIN_CE ( nssv_HAVE_BUILTIN_VER ) - -#define nssv_HAVE_BUILTIN_MEMCMP ( (nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14 ) -#define nssv_HAVE_BUILTIN_STRLEN ( (nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11 ) - -#ifdef __has_builtin -# define nssv_HAVE_BUILTIN( x ) __has_builtin( x ) -#else -# define nssv_HAVE_BUILTIN( x ) 0 -#endif - -#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER -# define nssv_BUILTIN_MEMCMP __builtin_memcmp -#else -# define nssv_BUILTIN_MEMCMP memcmp -#endif - -#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER -# define nssv_BUILTIN_STRLEN __builtin_strlen -#else -# define nssv_BUILTIN_STRLEN strlen -#endif - -// C++ feature usage: - -#if nssv_HAVE_CONSTEXPR_11 -# define nssv_constexpr constexpr -#else -# define nssv_constexpr /*constexpr*/ -#endif - -#if nssv_HAVE_CONSTEXPR_14 -# define nssv_constexpr14 constexpr -#else -# define nssv_constexpr14 /*constexpr*/ -#endif - -#if nssv_HAVE_EXPLICIT_CONVERSION -# define nssv_explicit explicit -#else -# define nssv_explicit /*explicit*/ -#endif - -#if nssv_HAVE_INLINE_NAMESPACE -# define nssv_inline_ns inline -#else -# define nssv_inline_ns /*inline*/ -#endif - -#if nssv_HAVE_NOEXCEPT -# define nssv_noexcept noexcept -#else -# define nssv_noexcept /*noexcept*/ -#endif - -//#if nssv_HAVE_REF_QUALIFIER -//# define nssv_ref_qual & -//# define nssv_refref_qual && -//#else -//# define nssv_ref_qual /*&*/ -//# define nssv_refref_qual /*&&*/ -//#endif - -#if nssv_HAVE_NULLPTR -# define nssv_nullptr nullptr -#else -# define nssv_nullptr NULL -#endif - -#if nssv_HAVE_NODISCARD -# define nssv_nodiscard [[nodiscard]] -#else -# define nssv_nodiscard /*[[nodiscard]]*/ -#endif - -// Additional includes: - -#include -#include -#include -#include -#include // std::char_traits<> - -#if ! nssv_CONFIG_NO_STREAM_INSERTION -# include -#endif - -#if ! nssv_CONFIG_NO_EXCEPTIONS -# include -#endif - -#if nssv_CPP11_OR_GREATER -# include -#endif - -// Clang, GNUC, MSVC warning suppression macros: - -#if defined(__clang__) -# pragma clang diagnostic ignored "-Wreserved-user-defined-literal" -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wuser-defined-literals" -#elif nssv_COMPILER_GNUC_VERSION >= 480 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wliteral-suffix" -#endif // __clang__ - -#if nssv_COMPILER_MSVC_VERSION >= 140 -# define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]] -# define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) ) -# define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes)) -#else -# define nssv_SUPPRESS_MSGSL_WARNING(expr) -# define nssv_SUPPRESS_MSVC_WARNING(code, descr) -# define nssv_DISABLE_MSVC_WARNINGS(codes) -#endif - -#if defined(__clang__) -# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop") -#elif nssv_COMPILER_GNUC_VERSION >= 480 -# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop") -#elif nssv_COMPILER_MSVC_VERSION >= 140 -# define nssv_RESTORE_WARNINGS() __pragma(warning(pop )) -#else -# define nssv_RESTORE_WARNINGS() -#endif - -// Suppress the following MSVC (GSL) warnings: -// - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not -// start with an underscore are reserved -// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions; -// use brace initialization, gsl::narrow_cast or gsl::narow -// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead - -nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 ) -//nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" ) -//nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix ) - -namespace nonstd { namespace sv_lite { - -// -// basic_string_view declaration: -// - -template -< - class CharT, - class Traits = std::char_traits -> -class basic_string_view; - -namespace detail { - -// support constexpr comparison in C++14; -// for C++17 and later, use provided traits: - -template< typename CharT > -inline nssv_constexpr14 int compare( CharT const * s1, CharT const * s2, std::size_t count ) -{ - while ( count-- != 0 ) - { - if ( *s1 < *s2 ) return -1; - if ( *s1 > *s2 ) return +1; - ++s1; ++s2; - } - return 0; -} - -#if nssv_HAVE_BUILTIN_MEMCMP - -// specialization of compare() for char, see also generic compare() above: - -inline nssv_constexpr14 int compare( char const * s1, char const * s2, std::size_t count ) -{ - return nssv_BUILTIN_MEMCMP( s1, s2, count ); -} - -#endif - -#if nssv_HAVE_BUILTIN_STRLEN - -// specialization of length() for char, see also generic length() further below: - -inline nssv_constexpr std::size_t length( char const * s ) -{ - return nssv_BUILTIN_STRLEN( s ); -} - -#endif - -#if defined(__OPTIMIZE__) - -// gcc, clang provide __OPTIMIZE__ -// Expect tail call optimization to make length() non-recursive: - -template< typename CharT > -inline nssv_constexpr std::size_t length( CharT * s, std::size_t result = 0 ) -{ - return *s == '\0' ? result : length( s + 1, result + 1 ); -} - -#else // OPTIMIZE - -// non-recursive: - -template< typename CharT > -inline nssv_constexpr14 std::size_t length( CharT * s ) -{ - std::size_t result = 0; - while ( *s++ != '\0' ) - { - ++result; - } - return result; -} - -#endif // OPTIMIZE - -#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER -#if defined(__OPTIMIZE__) - -// gcc, clang provide __OPTIMIZE__ -// Expect tail call optimization to make search() non-recursive: - -template< class CharT, class Traits = std::char_traits > -constexpr const CharT* search( basic_string_view haystack, basic_string_view needle ) -{ - return haystack.starts_with( needle ) ? haystack.begin() : - haystack.empty() ? haystack.end() : search( haystack.substr(1), needle ); -} - -#else // OPTIMIZE - -// non-recursive: - -#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH - -template< class CharT, class Traits = std::char_traits > -constexpr const CharT* search( basic_string_view haystack, basic_string_view needle ) -{ - return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() ); -} - -#else // nssv_CONFIG_CONSTEXPR11_STD_SEARCH - -template< class CharT, class Traits = std::char_traits > -nssv_constexpr14 const CharT* search( basic_string_view haystack, basic_string_view needle ) -{ - while ( needle.size() <= haystack.size() ) - { - if ( haystack.starts_with(needle) ) - { - return haystack.cbegin(); - } - haystack = basic_string_view{ haystack.begin() + 1, haystack.size() - 1U }; - } - return haystack.cend(); -} -#endif // nssv_CONFIG_CONSTEXPR11_STD_SEARCH - -#endif // OPTIMIZE -#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER - -} // namespace detail - -// -// basic_string_view: -// - -template -< - class CharT, - class Traits /* = std::char_traits */ -> -class basic_string_view -{ -public: - // Member types: - - typedef Traits traits_type; - typedef CharT value_type; - - typedef CharT * pointer; - typedef CharT const * const_pointer; - typedef CharT & reference; - typedef CharT const & const_reference; - - typedef const_pointer iterator; - typedef const_pointer const_iterator; - typedef std::reverse_iterator< const_iterator > reverse_iterator; - typedef std::reverse_iterator< const_iterator > const_reverse_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - // 24.4.2.1 Construction and assignment: - - nssv_constexpr basic_string_view() nssv_noexcept - : data_( nssv_nullptr ) - , size_( 0 ) - {} - -#if nssv_CPP11_OR_GREATER - nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default; -#else - nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept - : data_( other.data_) - , size_( other.size_) - {} -#endif - - nssv_constexpr basic_string_view( CharT const * s, size_type count ) nssv_noexcept // non-standard noexcept - : data_( s ) - , size_( count ) - {} - - nssv_constexpr basic_string_view( CharT const * s) nssv_noexcept // non-standard noexcept - : data_( s ) -#if nssv_CPP17_OR_GREATER - , size_( Traits::length(s) ) -#elif nssv_CPP11_OR_GREATER - , size_( detail::length(s) ) -#else - , size_( Traits::length(s) ) -#endif - {} - -#if nssv_HAVE_NULLPTR -# if nssv_HAVE_IS_DELETE - nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept = delete; -# else - private: nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept; public: -# endif -#endif - - // Assignment: - -#if nssv_CPP11_OR_GREATER - nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default; -#else - nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept - { - data_ = other.data_; - size_ = other.size_; - return *this; - } -#endif - - // 24.4.2.2 Iterator support: - - nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; } - nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; } - - nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); } - nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); } - - nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); } - nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); } - - nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); } - nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); } - - // 24.4.2.3 Capacity: - - nssv_constexpr size_type size() const nssv_noexcept { return size_; } - nssv_constexpr size_type length() const nssv_noexcept { return size_; } - nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); } - - // since C++20 - nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept - { - return 0 == size_; - } - - // 24.4.2.4 Element access: - - nssv_constexpr const_reference operator[]( size_type pos ) const - { - return data_at( pos ); - } - - nssv_constexpr14 const_reference at( size_type pos ) const - { -#if nssv_CONFIG_NO_EXCEPTIONS - assert( pos < size() ); -#else - if ( pos >= size() ) - { - throw std::out_of_range("nonstd::string_view::at()"); - } -#endif - return data_at( pos ); - } - - nssv_constexpr const_reference front() const { return data_at( 0 ); } - nssv_constexpr const_reference back() const { return data_at( size() - 1 ); } - - nssv_constexpr const_pointer data() const nssv_noexcept { return data_; } - - // 24.4.2.5 Modifiers: - - nssv_constexpr14 void remove_prefix( size_type n ) - { - assert( n <= size() ); - data_ += n; - size_ -= n; - } - - nssv_constexpr14 void remove_suffix( size_type n ) - { - assert( n <= size() ); - size_ -= n; - } - - nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept - { - const basic_string_view tmp(other); - other = *this; - *this = tmp; - } - - // 24.4.2.6 String operations: - - size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const - { -#if nssv_CONFIG_NO_EXCEPTIONS - assert( pos <= size() ); -#else - if ( pos > size() ) - { - throw std::out_of_range("nonstd::string_view::copy()"); - } -#endif - const size_type rlen = (std::min)( n, size() - pos ); - - (void) Traits::copy( dest, data() + pos, rlen ); - - return rlen; - } - - nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const - { -#if nssv_CONFIG_NO_EXCEPTIONS - assert( pos <= size() ); -#else - if ( pos > size() ) - { - throw std::out_of_range("nonstd::string_view::substr()"); - } -#endif - return basic_string_view( data() + pos, (std::min)( n, size() - pos ) ); - } - - // compare(), 6x: - - nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1) - { -#if nssv_CPP17_OR_GREATER - if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) ) -#else - if ( const int result = detail::compare( data(), other.data(), (std::min)( size(), other.size() ) ) ) -#endif - { - return result; - } - - return size() == other.size() ? 0 : size() < other.size() ? -1 : 1; - } - - nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2) - { - return substr( pos1, n1 ).compare( other ); - } - - nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3) - { - return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) ); - } - - nssv_constexpr int compare( CharT const * s ) const // (4) - { - return compare( basic_string_view( s ) ); - } - - nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5) - { - return substr( pos1, n1 ).compare( basic_string_view( s ) ); - } - - nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6) - { - return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) ); - } - - // 24.4.2.7 Searching: - - // starts_with(), 3x, since C++20: - - nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1) - { - return size() >= v.size() && compare( 0, v.size(), v ) == 0; - } - - nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2) - { - return starts_with( basic_string_view( &c, 1 ) ); - } - - nssv_constexpr bool starts_with( CharT const * s ) const // (3) - { - return starts_with( basic_string_view( s ) ); - } - - // ends_with(), 3x, since C++20: - - nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1) - { - return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0; - } - - nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2) - { - return ends_with( basic_string_view( &c, 1 ) ); - } - - nssv_constexpr bool ends_with( CharT const * s ) const // (3) - { - return ends_with( basic_string_view( s ) ); - } - - // find(), 4x: - - nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) - { - return assert( v.size() == 0 || v.data() != nssv_nullptr ) - , pos >= size() - ? npos : to_pos( -#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER - detail::search( substr(pos), v ) -#else - std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) -#endif - ); - } - - nssv_constexpr size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) - { - return find( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find( CharT const * s, size_type pos, size_type n ) const // (3) - { - return find( basic_string_view( s, n ), pos ); - } - - nssv_constexpr size_type find( CharT const * s, size_type pos = 0 ) const // (4) - { - return find( basic_string_view( s ), pos ); - } - - // rfind(), 4x: - - nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) - { - if ( size() < v.size() ) - { - return npos; - } - - if ( v.empty() ) - { - return (std::min)( size(), pos ); - } - - const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size(); - const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq ); - - return result != last ? size_type( result - cbegin() ) : npos; - } - - nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2) - { - return rfind( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3) - { - return rfind( basic_string_view( s, n ), pos ); - } - - nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4) - { - return rfind( basic_string_view( s ), pos ); - } - - // find_first_of(), 4x: - - nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) - { - return pos >= size() - ? npos - : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) ); - } - - nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) - { - return find_first_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3) - { - return find_first_of( basic_string_view( s, n ), pos ); - } - - nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4) - { - return find_first_of( basic_string_view( s ), pos ); - } - - // find_last_of(), 4x: - - nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) - { - return empty() - ? npos - : pos >= size() - ? find_last_of( v, size() - 1 ) - : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) ); - } - - nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) - { - return find_last_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3) - { - return find_last_of( basic_string_view( s, count ), pos ); - } - - nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4) - { - return find_last_of( basic_string_view( s ), pos ); - } - - // find_first_not_of(), 4x: - - nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) - { - return pos >= size() - ? npos - : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) ); - } - - nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) - { - return find_first_not_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3) - { - return find_first_not_of( basic_string_view( s, count ), pos ); - } - - nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4) - { - return find_first_not_of( basic_string_view( s ), pos ); - } - - // find_last_not_of(), 4x: - - nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) - { - return empty() - ? npos - : pos >= size() - ? find_last_not_of( v, size() - 1 ) - : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) ); - } - - nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) - { - return find_last_not_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3) - { - return find_last_not_of( basic_string_view( s, count ), pos ); - } - - nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4) - { - return find_last_not_of( basic_string_view( s ), pos ); - } - - // Constants: - -#if nssv_CPP17_OR_GREATER - static nssv_constexpr size_type npos = size_type(-1); -#elif nssv_CPP11_OR_GREATER - enum : size_type { npos = size_type(-1) }; -#else - enum { npos = size_type(-1) }; -#endif - -private: - struct not_in_view - { - const basic_string_view v; - - nssv_constexpr explicit not_in_view( basic_string_view v_ ) : v( v_ ) {} - - nssv_constexpr bool operator()( CharT c ) const - { - return npos == v.find_first_of( c ); - } - }; - - nssv_constexpr size_type to_pos( const_iterator it ) const - { - return it == cend() ? npos : size_type( it - cbegin() ); - } - - nssv_constexpr size_type to_pos( const_reverse_iterator it ) const - { - return it == crend() ? npos : size_type( crend() - it - 1 ); - } - - nssv_constexpr const_reference data_at( size_type pos ) const - { -#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 ) - return data_[pos]; -#else - return assert( pos < size() ), data_[pos]; -#endif - } - -private: - const_pointer data_; - size_type size_; - -public: -#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS - - template< class Allocator > - basic_string_view( std::basic_string const & s ) nssv_noexcept - : data_( s.data() ) - , size_( s.size() ) - {} - -#if nssv_HAVE_EXPLICIT_CONVERSION - - template< class Allocator > - explicit operator std::basic_string() const - { - return to_string( Allocator() ); - } - -#endif // nssv_HAVE_EXPLICIT_CONVERSION - -#if nssv_CPP11_OR_GREATER - - template< class Allocator = std::allocator > - std::basic_string - to_string( Allocator const & a = Allocator() ) const - { - return std::basic_string( begin(), end(), a ); - } - -#else - - std::basic_string - to_string() const - { - return std::basic_string( begin(), end() ); - } - - template< class Allocator > - std::basic_string - to_string( Allocator const & a ) const - { - return std::basic_string( begin(), end(), a ); - } - -#endif // nssv_CPP11_OR_GREATER - -#endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS -}; - -// -// Non-member functions: -// - -// 24.4.3 Non-member comparison functions: -// lexicographically compare two string views (function template): - -template< class CharT, class Traits > -nssv_constexpr bool operator== ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator!= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits > -nssv_constexpr bool operator< ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator<= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator> ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator>= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0; } - -// Let S be basic_string_view, and sv be an instance of S. -// Implementations shall provide sufficient additional overloads marked -// constexpr and noexcept so that an object t with an implicit conversion -// to S can be compared according to Table 67. - -#if ! nssv_CPP11_OR_GREATER || nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 ) - -// accommodate for older compilers: - -// == - -template< class CharT, class Traits> -nssv_constexpr bool operator==( - basic_string_view lhs, - CharT const * rhs ) nssv_noexcept -{ return lhs.size() == detail::length( rhs ) && lhs.compare( rhs ) == 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator==( - CharT const * lhs, - basic_string_view rhs ) nssv_noexcept -{ return detail::length( lhs ) == rhs.size() && rhs.compare( lhs ) == 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator==( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator==( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -// != - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - basic_string_view lhs, - CharT const * rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - CharT const * lhs, - basic_string_view rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -// < - -template< class CharT, class Traits> -nssv_constexpr bool operator<( - basic_string_view lhs, - CharT const * rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<( - CharT const * lhs, - basic_string_view rhs ) nssv_noexcept -{ return rhs.compare( lhs ) > 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return rhs.compare( lhs ) > 0; } - -// <= - -template< class CharT, class Traits> -nssv_constexpr bool operator<=( - basic_string_view lhs, - CharT const * rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<=( - CharT const * lhs, - basic_string_view rhs ) nssv_noexcept -{ return rhs.compare( lhs ) >= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<=( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<=( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return rhs.compare( lhs ) >= 0; } - -// > - -template< class CharT, class Traits> -nssv_constexpr bool operator>( - basic_string_view lhs, - CharT const * rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>( - CharT const * lhs, - basic_string_view rhs ) nssv_noexcept -{ return rhs.compare( lhs ) < 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return rhs.compare( lhs ) < 0; } - -// >= - -template< class CharT, class Traits> -nssv_constexpr bool operator>=( - basic_string_view lhs, - CharT const * rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>=( - CharT const * lhs, - basic_string_view rhs ) nssv_noexcept -{ return rhs.compare( lhs ) <= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>=( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>=( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return rhs.compare( lhs ) <= 0; } - -#else // newer compilers: - -#define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view >::type - -#if defined(_MSC_VER) // issue 40 -# define nssv_MSVC_ORDER(x) , int=x -#else -# define nssv_MSVC_ORDER(x) /*, int=x*/ -#endif - -// == - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator==( - basic_string_view lhs, - nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator==( - nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -// != - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator!= ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator!= ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -// < - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator< ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator< ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0; } - -// <= - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator<= ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator<= ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0; } - -// > - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator> ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator> ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0; } - -// >= - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator>= ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator>= ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0; } - -#undef nssv_MSVC_ORDER -#undef nssv_BASIC_STRING_VIEW_I - -#endif // compiler-dependent approach to comparisons - -// 24.4.4 Inserters and extractors: - -#if ! nssv_CONFIG_NO_STREAM_INSERTION - -namespace detail { - -template< class Stream > -void write_padding( Stream & os, std::streamsize n ) -{ - for ( std::streamsize i = 0; i < n; ++i ) - os.rdbuf()->sputc( os.fill() ); -} - -template< class Stream, class View > -Stream & write_to_stream( Stream & os, View const & sv ) -{ - typename Stream::sentry sentry( os ); - - if ( !sentry ) - return os; - - const std::streamsize length = static_cast( sv.length() ); - - // Whether, and how, to pad: - const bool pad = ( length < os.width() ); - const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right; - - if ( left_pad ) - write_padding( os, os.width() - length ); - - // Write span characters: - os.rdbuf()->sputn( sv.begin(), length ); - - if ( pad && !left_pad ) - write_padding( os, os.width() - length ); - - // Reset output stream width: - os.width( 0 ); - - return os; -} - -} // namespace detail - -template< class CharT, class Traits > -std::basic_ostream & -operator<<( - std::basic_ostream& os, - basic_string_view sv ) -{ - return detail::write_to_stream( os, sv ); -} - -#endif // nssv_CONFIG_NO_STREAM_INSERTION - -// Several typedefs for common character types are provided: - -typedef basic_string_view string_view; -typedef basic_string_view wstring_view; -#if nssv_HAVE_WCHAR16_T -typedef basic_string_view u16string_view; -typedef basic_string_view u32string_view; -#endif - -}} // namespace nonstd::sv_lite - -// -// 24.4.6 Suffix for basic_string_view literals: -// - -#if nssv_HAVE_USER_DEFINED_LITERALS - -namespace nonstd { -nssv_inline_ns namespace literals { -nssv_inline_ns namespace string_view_literals { - -#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS - -nssv_constexpr nonstd::sv_lite::string_view operator""sv( const char* str, size_t len ) nssv_noexcept // (1) -{ - return nonstd::sv_lite::string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u16string_view operator""sv( const char16_t* str, size_t len ) nssv_noexcept // (2) -{ - return nonstd::sv_lite::u16string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u32string_view operator""sv( const char32_t* str, size_t len ) nssv_noexcept // (3) -{ - return nonstd::sv_lite::u32string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::wstring_view operator""sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) -{ - return nonstd::sv_lite::wstring_view{ str, len }; -} - -#endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS - -#if nssv_CONFIG_USR_SV_OPERATOR - -nssv_constexpr nonstd::sv_lite::string_view operator""_sv( const char* str, size_t len ) nssv_noexcept // (1) -{ - return nonstd::sv_lite::string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u16string_view operator""_sv( const char16_t* str, size_t len ) nssv_noexcept // (2) -{ - return nonstd::sv_lite::u16string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u32string_view operator""_sv( const char32_t* str, size_t len ) nssv_noexcept // (3) -{ - return nonstd::sv_lite::u32string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::wstring_view operator""_sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) -{ - return nonstd::sv_lite::wstring_view{ str, len }; -} - -#endif // nssv_CONFIG_USR_SV_OPERATOR - -}}} // namespace nonstd::literals::string_view_literals - -#endif - -// -// Extensions for std::string: -// - -#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -namespace nonstd { -namespace sv_lite { - -// Exclude MSVC 14 (19.00): it yields ambiguous to_string(): - -#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140 - -template< class CharT, class Traits, class Allocator = std::allocator > -std::basic_string -to_string( basic_string_view v, Allocator const & a = Allocator() ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -#else - -template< class CharT, class Traits > -std::basic_string -to_string( basic_string_view v ) -{ - return std::basic_string( v.begin(), v.end() ); -} - -template< class CharT, class Traits, class Allocator > -std::basic_string -to_string( basic_string_view v, Allocator const & a ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -#endif // nssv_CPP11_OR_GREATER - -template< class CharT, class Traits, class Allocator > -basic_string_view -to_string_view( std::basic_string const & s ) -{ - return basic_string_view( s.data(), s.size() ); -} - -}} // namespace nonstd::sv_lite - -#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -// -// make types and algorithms available in namespace nonstd: -// - -namespace nonstd { - -using sv_lite::basic_string_view; -using sv_lite::string_view; -using sv_lite::wstring_view; - -#if nssv_HAVE_WCHAR16_T -using sv_lite::u16string_view; -#endif -#if nssv_HAVE_WCHAR32_T -using sv_lite::u32string_view; -#endif - -// literal "sv" - -using sv_lite::operator==; -using sv_lite::operator!=; -using sv_lite::operator<; -using sv_lite::operator<=; -using sv_lite::operator>; -using sv_lite::operator>=; - -#if ! nssv_CONFIG_NO_STREAM_INSERTION -using sv_lite::operator<<; -#endif - -#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS -using sv_lite::to_string; -using sv_lite::to_string_view; -#endif - -} // namespace nonstd - -// 24.4.5 Hash support (C++11): - -// Note: The hash value of a string view object is equal to the hash value of -// the corresponding string object. - -#if nssv_HAVE_STD_HASH - -#include - -namespace std { - -template<> -struct hash< nonstd::string_view > -{ -public: - std::size_t operator()( nonstd::string_view v ) const nssv_noexcept - { - return std::hash()( std::string( v.data(), v.size() ) ); - } -}; - -template<> -struct hash< nonstd::wstring_view > -{ -public: - std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept - { - return std::hash()( std::wstring( v.data(), v.size() ) ); - } -}; - -template<> -struct hash< nonstd::u16string_view > -{ -public: - std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept - { - return std::hash()( std::u16string( v.data(), v.size() ) ); - } -}; - -template<> -struct hash< nonstd::u32string_view > -{ -public: - std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept - { - return std::hash()( std::u32string( v.data(), v.size() ) ); - } -}; - -} // namespace std - -#endif // nssv_HAVE_STD_HASH - -nssv_RESTORE_WARNINGS() - -#endif // nssv_HAVE_STD_STRING_VIEW -#endif // NONSTD_SV_LITE_H_INCLUDED diff --git a/src/option_parser.cpp b/src/option_parser.cpp index b1de2bb9..70743385 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -32,14 +32,14 @@ #include "fuse.h" #include "fuse_config.hpp" -#include "nonstd/string_view.hpp" - +#include +#include #include #include #include #include +#include #include -#include #include #include @@ -133,7 +133,7 @@ static bool should_ignore(const std::string &key_) { - constexpr const std::array ignored_keys = + constexpr const std::array ignored_keys = { "atomic_o_trunc", "big_writes", @@ -437,7 +437,7 @@ check_for_mount_loop(Config::Write &cfg_, branches = cfg_->branches->to_paths(); for(const auto &branch : branches) { - if(ghc::filesystem::equivalent(branch,mount,ec)) + if(std::filesystem::equivalent(branch,mount,ec)) { std::string errstr; diff --git a/src/state.cpp b/src/state.cpp new file mode 100644 index 00000000..d4040f4b --- /dev/null +++ b/src/state.cpp @@ -0,0 +1,3 @@ +#include "state.hpp" + +State state; diff --git a/src/state.hpp b/src/state.hpp new file mode 100644 index 00000000..5028f76d --- /dev/null +++ b/src/state.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "boost/unordered/concurrent_flat_map.hpp" + +#include "fileinfo.hpp" + + +constexpr int INVALID_BACKING_ID = -1; + +class State +{ +public: + struct OpenFile + { + OpenFile() + : ref_count(0), + backing_id(INVALID_BACKING_ID), + fi(nullptr) + { + } + + int ref_count; + int backing_id; + FileInfo *fi; + }; + + +public: + using OpenFileMap = boost::concurrent_flat_map; + +public: + int proc_self_fd_fd = -1; + OpenFileMap open_files; +}; + +extern State state;