From aea6b5c416c0a0c6813b359ab8ee914cd5c0a568 Mon Sep 17 00:00:00 2001 From: VelocityRa Date: Fri, 24 Aug 2018 22:25:20 +0300 Subject: [PATCH] Initial commit --- Jamroot | 340 + LICENSE_1_0.txt | 23 + README.md | 24 + b2.exe | Bin 0 -> 387072 bytes bcp.exe | Bin 0 -> 473088 bytes bjam.exe | Bin 0 -> 387072 bytes boost-build.jam | 17 + boost.png | Bin 0 -> 6308 bytes boost/algorithm/cxx11/all_of.hpp | 83 + boost/algorithm/string/classification.hpp | 312 + boost/algorithm/string/compare.hpp | 199 + boost/algorithm/string/concept.hpp | 83 + boost/algorithm/string/config.hpp | 28 + boost/algorithm/string/constants.hpp | 36 + .../string/detail/classification.hpp | 353 + .../algorithm/string/detail/find_iterator.hpp | 87 + boost/algorithm/string/detail/finder.hpp | 639 + boost/algorithm/string/detail/trim.hpp | 95 + boost/algorithm/string/detail/util.hpp | 107 + boost/algorithm/string/find_iterator.hpp | 388 + boost/algorithm/string/finder.hpp | 270 + boost/algorithm/string/iter_find.hpp | 193 + boost/algorithm/string/predicate_facade.hpp | 42 + boost/algorithm/string/split.hpp | 163 + boost/algorithm/string/trim.hpp | 398 + boost/aligned_storage.hpp | 18 + boost/any.hpp | 337 + boost/array.hpp | 457 + boost/assert.hpp | 85 + boost/atomic.hpp | 18 + boost/atomic/atomic.hpp | 104 + boost/atomic/atomic_flag.hpp | 33 + boost/atomic/capabilities.hpp | 210 + boost/atomic/detail/addressof.hpp | 58 + boost/atomic/detail/atomic_flag.hpp | 71 + boost/atomic/detail/atomic_template.hpp | 1248 + boost/atomic/detail/bitwise_cast.hpp | 68 + boost/atomic/detail/bitwise_fp_cast.hpp | 86 + boost/atomic/detail/caps_gcc_alpha.hpp | 34 + boost/atomic/detail/caps_gcc_arm.hpp | 39 + boost/atomic/detail/caps_gcc_atomic.hpp | 133 + boost/atomic/detail/caps_gcc_ppc.hpp | 37 + boost/atomic/detail/caps_gcc_sparc.hpp | 34 + boost/atomic/detail/caps_gcc_sync.hpp | 61 + boost/atomic/detail/caps_gcc_x86.hpp | 40 + boost/atomic/detail/caps_linux_arm.hpp | 35 + boost/atomic/detail/caps_msvc_arm.hpp | 34 + boost/atomic/detail/caps_msvc_x86.hpp | 55 + boost/atomic/detail/caps_windows.hpp | 33 + boost/atomic/detail/config.hpp | 150 + boost/atomic/detail/extra_fp_operations.hpp | 28 + .../atomic/detail/extra_fp_operations_fwd.hpp | 35 + boost/atomic/detail/extra_fp_ops_emulated.hpp | 107 + boost/atomic/detail/extra_fp_ops_generic.hpp | 189 + boost/atomic/detail/extra_operations.hpp | 28 + boost/atomic/detail/extra_operations_fwd.hpp | 35 + boost/atomic/detail/extra_ops_emulated.hpp | 238 + boost/atomic/detail/extra_ops_gcc_arm.hpp | 1111 + boost/atomic/detail/extra_ops_gcc_ppc.hpp | 840 + boost/atomic/detail/extra_ops_gcc_x86.hpp | 1656 ++ boost/atomic/detail/extra_ops_generic.hpp | 402 + boost/atomic/detail/extra_ops_msvc_arm.hpp | 106 + boost/atomic/detail/extra_ops_msvc_x86.hpp | 1301 + boost/atomic/detail/float_sizes.hpp | 142 + boost/atomic/detail/fp_operations.hpp | 28 + boost/atomic/detail/fp_operations_fwd.hpp | 35 + boost/atomic/detail/fp_ops_emulated.hpp | 72 + boost/atomic/detail/fp_ops_generic.hpp | 83 + boost/atomic/detail/hwcaps_gcc_arm.hpp | 67 + boost/atomic/detail/hwcaps_gcc_ppc.hpp | 42 + boost/atomic/detail/hwcaps_gcc_x86.hpp | 58 + boost/atomic/detail/int_sizes.hpp | 140 + boost/atomic/detail/integral_extend.hpp | 105 + boost/atomic/detail/interlocked.hpp | 522 + boost/atomic/detail/link.hpp | 58 + boost/atomic/detail/lockpool.hpp | 51 + boost/atomic/detail/operations.hpp | 24 + boost/atomic/detail/operations_fwd.hpp | 35 + boost/atomic/detail/operations_lockfree.hpp | 30 + boost/atomic/detail/ops_cas_based.hpp | 107 + boost/atomic/detail/ops_emulated.hpp | 162 + .../atomic/detail/ops_extending_cas_based.hpp | 69 + boost/atomic/detail/ops_gcc_alpha.hpp | 876 + boost/atomic/detail/ops_gcc_arm.hpp | 1397 + boost/atomic/detail/ops_gcc_arm_common.hpp | 134 + boost/atomic/detail/ops_gcc_atomic.hpp | 392 + boost/atomic/detail/ops_gcc_ppc.hpp | 1232 + boost/atomic/detail/ops_gcc_ppc_common.hpp | 70 + boost/atomic/detail/ops_gcc_sparc.hpp | 240 + boost/atomic/detail/ops_gcc_sync.hpp | 240 + boost/atomic/detail/ops_gcc_x86.hpp | 563 + boost/atomic/detail/ops_gcc_x86_dcas.hpp | 555 + boost/atomic/detail/ops_linux_arm.hpp | 180 + boost/atomic/detail/ops_msvc_arm.hpp | 824 + boost/atomic/detail/ops_msvc_common.hpp | 38 + boost/atomic/detail/ops_msvc_x86.hpp | 908 + boost/atomic/detail/ops_windows.hpp | 218 + boost/atomic/detail/pause.hpp | 43 + boost/atomic/detail/platform.hpp | 163 + boost/atomic/detail/storage_type.hpp | 207 + boost/atomic/detail/string_ops.hpp | 61 + .../atomic/detail/type_traits/conditional.hpp | 42 + .../detail/type_traits/integral_constant.hpp | 46 + .../detail/type_traits/is_floating_point.hpp | 42 + .../atomic/detail/type_traits/is_function.hpp | 42 + boost/atomic/detail/type_traits/is_iec559.hpp | 47 + .../atomic/detail/type_traits/is_integral.hpp | 43 + boost/atomic/detail/type_traits/is_signed.hpp | 43 + .../is_trivially_default_constructible.hpp | 46 + .../atomic/detail/type_traits/make_signed.hpp | 43 + .../detail/type_traits/make_unsigned.hpp | 43 + boost/atomic/fences.hpp | 67 + boost/bind.hpp | 41 + boost/bind/arg.hpp | 69 + boost/bind/bind.hpp | 2365 ++ boost/bind/bind_cc.hpp | 117 + boost/bind/bind_mf2_cc.hpp | 228 + boost/bind/bind_mf_cc.hpp | 441 + boost/bind/bind_template.hpp | 345 + boost/bind/mem_fn.hpp | 389 + boost/bind/mem_fn_cc.hpp | 103 + boost/bind/mem_fn_template.hpp | 1047 + boost/bind/mem_fn_vw.hpp | 130 + boost/bind/placeholders.hpp | 62 + boost/bind/storage.hpp | 475 + boost/call_traits.hpp | 20 + boost/cerrno.hpp | 331 + boost/checked_delete.hpp | 17 + boost/chrono.hpp | 20 + boost/chrono/ceil.hpp | 36 + boost/chrono/chrono.hpp | 15 + boost/chrono/chrono_io.hpp | 34 + boost/chrono/clock_string.hpp | 25 + boost/chrono/config.hpp | 216 + boost/chrono/detail/inlined/chrono.hpp | 46 + boost/chrono/detail/inlined/mac/chrono.hpp | 242 + .../detail/inlined/mac/process_cpu_clocks.hpp | 356 + .../detail/inlined/mac/thread_clock.hpp | 92 + boost/chrono/detail/inlined/posix/chrono.hpp | 121 + .../inlined/posix/process_cpu_clocks.hpp | 354 + .../detail/inlined/posix/thread_clock.hpp | 92 + .../detail/inlined/process_cpu_clocks.hpp | 46 + boost/chrono/detail/inlined/thread_clock.hpp | 46 + boost/chrono/detail/inlined/win/chrono.hpp | 150 + .../detail/inlined/win/process_cpu_clocks.hpp | 281 + .../detail/inlined/win/thread_clock.hpp | 103 + .../chrono/detail/is_evenly_divisible_by.hpp | 31 + .../detail/no_warning/signed_unsigned_cmp.hpp | 54 + boost/chrono/detail/scan_keyword.hpp | 163 + boost/chrono/detail/static_assert.hpp | 30 + boost/chrono/detail/system.hpp | 19 + boost/chrono/duration.hpp | 798 + boost/chrono/floor.hpp | 36 + boost/chrono/include.hpp | 23 + boost/chrono/io/duration_get.hpp | 591 + boost/chrono/io/duration_io.hpp | 295 + boost/chrono/io/duration_put.hpp | 317 + boost/chrono/io/duration_style.hpp | 35 + boost/chrono/io/duration_units.hpp | 1003 + boost/chrono/io/ios_base_state.hpp | 152 + boost/chrono/io/time_point_get.hpp | 330 + boost/chrono/io/time_point_io.hpp | 1249 + boost/chrono/io/time_point_put.hpp | 261 + boost/chrono/io/time_point_units.hpp | 260 + boost/chrono/io/timezone.hpp | 30 + .../chrono/io/utility/ios_base_state_ptr.hpp | 437 + boost/chrono/io/utility/manip_base.hpp | 101 + boost/chrono/io/utility/to_string.hpp | 50 + boost/chrono/io_v1/chrono_io.hpp | 635 + boost/chrono/process_cpu_clocks.hpp | 525 + boost/chrono/round.hpp | 59 + boost/chrono/system_clocks.hpp | 233 + boost/chrono/thread_clock.hpp | 75 + boost/chrono/time_point.hpp | 379 + boost/concept/assert.hpp | 45 + .../concept/detail/backward_compatibility.hpp | 16 + boost/concept/detail/borland.hpp | 30 + boost/concept/detail/concept_def.hpp | 34 + boost/concept/detail/concept_undef.hpp | 5 + boost/concept/detail/general.hpp | 77 + boost/concept/detail/has_constraints.hpp | 50 + boost/concept/detail/msvc.hpp | 123 + boost/concept/usage.hpp | 36 + boost/concept_check.hpp | 1082 + boost/config.hpp | 67 + boost/config/abi/borland_prefix.hpp | 27 + boost/config/abi/borland_suffix.hpp | 12 + boost/config/abi/msvc_prefix.hpp | 22 + boost/config/abi/msvc_suffix.hpp | 8 + boost/config/abi_prefix.hpp | 25 + boost/config/abi_suffix.hpp | 27 + boost/config/auto_link.hpp | 466 + boost/config/compiler/borland.hpp | 332 + boost/config/compiler/clang.hpp | 336 + boost/config/compiler/codegear.hpp | 235 + boost/config/compiler/comeau.hpp | 59 + boost/config/compiler/common_edg.hpp | 156 + boost/config/compiler/compaq_cxx.hpp | 19 + boost/config/compiler/cray.hpp | 124 + boost/config/compiler/diab.hpp | 26 + boost/config/compiler/digitalmars.hpp | 137 + boost/config/compiler/gcc.hpp | 356 + boost/config/compiler/gcc_xml.hpp | 108 + boost/config/compiler/greenhills.hpp | 28 + boost/config/compiler/hp_acc.hpp | 147 + boost/config/compiler/intel.hpp | 564 + boost/config/compiler/kai.hpp | 33 + boost/config/compiler/metrowerks.hpp | 192 + boost/config/compiler/mpw.hpp | 134 + boost/config/compiler/nvcc.hpp | 58 + boost/config/compiler/pathscale.hpp | 132 + boost/config/compiler/pgi.hpp | 23 + boost/config/compiler/sgi_mipspro.hpp | 29 + boost/config/compiler/sunpro_cc.hpp | 210 + boost/config/compiler/vacpp.hpp | 180 + boost/config/compiler/visualc.hpp | 354 + boost/config/compiler/xlcpp.hpp | 281 + boost/config/compiler/xlcpp_zos.hpp | 169 + boost/config/detail/posix_features.hpp | 95 + .../config/detail/select_compiler_config.hpp | 158 + .../config/detail/select_platform_config.hpp | 142 + boost/config/detail/select_stdlib_config.hpp | 110 + boost/config/detail/suffix.hpp | 1036 + boost/config/header_deprecated.hpp | 26 + boost/config/helper_macros.hpp | 37 + boost/config/no_tr1/cmath.hpp | 28 + boost/config/no_tr1/complex.hpp | 28 + boost/config/no_tr1/functional.hpp | 28 + boost/config/no_tr1/memory.hpp | 28 + boost/config/no_tr1/utility.hpp | 28 + boost/config/platform/aix.hpp | 33 + boost/config/platform/amigaos.hpp | 15 + boost/config/platform/beos.hpp | 26 + boost/config/platform/bsd.hpp | 86 + boost/config/platform/cloudabi.hpp | 18 + boost/config/platform/cray.hpp | 18 + boost/config/platform/cygwin.hpp | 68 + boost/config/platform/haiku.hpp | 31 + boost/config/platform/hpux.hpp | 87 + boost/config/platform/irix.hpp | 31 + boost/config/platform/linux.hpp | 106 + boost/config/platform/macos.hpp | 87 + boost/config/platform/qnxnto.hpp | 31 + boost/config/platform/solaris.hpp | 31 + boost/config/platform/symbian.hpp | 97 + boost/config/platform/vms.hpp | 25 + boost/config/platform/vxworks.hpp | 433 + boost/config/platform/win32.hpp | 90 + boost/config/platform/zos.hpp | 32 + boost/config/pragma_message.hpp | 31 + boost/config/requires_threads.hpp | 92 + boost/config/stdlib/dinkumware.hpp | 258 + boost/config/stdlib/libcomo.hpp | 92 + boost/config/stdlib/libcpp.hpp | 133 + boost/config/stdlib/libstdcpp3.hpp | 349 + boost/config/stdlib/modena.hpp | 78 + boost/config/stdlib/msl.hpp | 97 + boost/config/stdlib/roguewave.hpp | 207 + boost/config/stdlib/sgi.hpp | 167 + boost/config/stdlib/stlport.hpp | 257 + boost/config/stdlib/vacpp.hpp | 73 + boost/config/stdlib/xlcpp_zos.hpp | 60 + boost/config/user.hpp | 133 + boost/config/warning_disable.hpp | 47 + boost/config/workaround.hpp | 279 + boost/container/allocator_traits.hpp | 477 + boost/container/container_fwd.hpp | 296 + boost/container/detail/addressof.hpp | 41 + .../container/detail/advanced_insert_int.hpp | 477 + boost/container/detail/algorithm.hpp | 157 + boost/container/detail/alloc_helpers.hpp | 60 + boost/container/detail/allocation_type.hpp | 58 + boost/container/detail/config_begin.hpp | 53 + boost/container/detail/config_end.hpp | 13 + boost/container/detail/construct_in_place.hpp | 96 + boost/container/detail/copy_move_algo.hpp | 1144 + boost/container/detail/destroyers.hpp | 378 + .../detail/dispatch_uses_allocator.hpp | 461 + boost/container/detail/iterator.hpp | 70 + boost/container/detail/iterators.hpp | 875 + boost/container/detail/min_max.hpp | 37 + boost/container/detail/mpl.hpp | 86 + boost/container/detail/next_capacity.hpp | 77 + boost/container/detail/pair.hpp | 559 + boost/container/detail/placement_new.hpp | 30 + boost/container/detail/std_fwd.hpp | 56 + boost/container/detail/type_traits.hpp | 70 + boost/container/detail/value_functors.hpp | 36 + boost/container/detail/value_init.hpp | 51 + .../detail/variadic_templates_tools.hpp | 163 + boost/container/detail/version_type.hpp | 110 + boost/container/detail/workaround.hpp | 111 + boost/container/new_allocator.hpp | 179 + boost/container/options.hpp | 245 + boost/container/scoped_allocator.hpp | 907 + boost/container/scoped_allocator_fwd.hpp | 71 + boost/container/throw_exception.hpp | 181 + boost/container/uses_allocator.hpp | 169 + boost/container/uses_allocator_fwd.hpp | 73 + boost/container/vector.hpp | 3377 +++ .../container_hash/detail/float_functions.hpp | 336 + boost/container_hash/detail/hash_float.hpp | 271 + boost/container_hash/detail/limits.hpp | 62 + boost/container_hash/extensions.hpp | 414 + boost/container_hash/hash.hpp | 761 + boost/container_hash/hash_fwd.hpp | 36 + boost/core/addressof.hpp | 274 + boost/core/checked_delete.hpp | 69 + boost/core/demangle.hpp | 126 + boost/core/enable_if.hpp | 128 + boost/core/explicit_operator_bool.hpp | 154 + boost/core/ignore_unused.hpp | 70 + boost/core/is_same.hpp | 40 + boost/core/lightweight_test.hpp | 465 + boost/core/no_exceptions_support.hpp | 44 + boost/core/noncopyable.hpp | 48 + boost/core/ref.hpp | 301 + boost/core/scoped_enum.hpp | 194 + boost/core/swap.hpp | 60 + boost/core/typeinfo.hpp | 151 + boost/cregex.hpp | 39 + boost/cstdint.hpp | 556 + boost/cstdlib.hpp | 41 + boost/current_function.hpp | 75 + boost/date_time/adjust_functors.hpp | 164 + boost/date_time/c_time.hpp | 123 + boost/date_time/compiler_config.hpp | 169 + boost/date_time/constrained_value.hpp | 121 + boost/date_time/date.hpp | 209 + boost/date_time/date_clock_device.hpp | 77 + boost/date_time/date_defs.hpp | 26 + boost/date_time/date_duration.hpp | 151 + boost/date_time/date_duration_types.hpp | 270 + boost/date_time/date_format_simple.hpp | 159 + boost/date_time/date_formatting.hpp | 137 + boost/date_time/date_formatting_limited.hpp | 121 + boost/date_time/date_formatting_locales.hpp | 234 + boost/date_time/date_generators.hpp | 509 + boost/date_time/date_iterator.hpp | 101 + boost/date_time/date_names_put.hpp | 321 + boost/date_time/date_parsing.hpp | 316 + boost/date_time/dst_rules.hpp | 391 + boost/date_time/filetime_functions.hpp | 84 + boost/date_time/gregorian/conversion.hpp | 68 + boost/date_time/gregorian/formatters.hpp | 162 + .../gregorian/formatters_limited.hpp | 81 + boost/date_time/gregorian/greg_calendar.hpp | 49 + boost/date_time/gregorian/greg_date.hpp | 137 + boost/date_time/gregorian/greg_day.hpp | 58 + .../date_time/gregorian/greg_day_of_year.hpp | 39 + boost/date_time/gregorian/greg_duration.hpp | 135 + .../gregorian/greg_duration_types.hpp | 44 + boost/date_time/gregorian/greg_facet.hpp | 374 + boost/date_time/gregorian/greg_month.hpp | 105 + boost/date_time/gregorian/greg_weekday.hpp | 66 + boost/date_time/gregorian/greg_year.hpp | 52 + boost/date_time/gregorian/greg_ymd.hpp | 33 + boost/date_time/gregorian/gregorian_types.hpp | 109 + boost/date_time/gregorian/parsers.hpp | 91 + boost/date_time/gregorian_calendar.hpp | 71 + boost/date_time/gregorian_calendar.ipp | 219 + boost/date_time/int_adapter.hpp | 496 + boost/date_time/iso_format.hpp | 303 + boost/date_time/locale_config.hpp | 33 + boost/date_time/microsec_time_clock.hpp | 158 + boost/date_time/parse_format_base.hpp | 29 + boost/date_time/period.hpp | 378 + boost/date_time/posix_time/conversion.hpp | 100 + .../posix_time/date_duration_operators.hpp | 114 + .../posix_time/posix_time_config.hpp | 178 + .../posix_time/posix_time_duration.hpp | 91 + .../posix_time/posix_time_system.hpp | 68 + .../date_time/posix_time/posix_time_types.hpp | 55 + boost/date_time/posix_time/ptime.hpp | 66 + boost/date_time/posix_time/time_period.hpp | 29 + boost/date_time/special_defs.hpp | 25 + boost/date_time/time.hpp | 193 + boost/date_time/time_clock.hpp | 83 + boost/date_time/time_defs.hpp | 43 + boost/date_time/time_duration.hpp | 298 + boost/date_time/time_iterator.hpp | 52 + boost/date_time/time_resolution_traits.hpp | 167 + boost/date_time/time_system_counted.hpp | 254 + boost/date_time/time_system_split.hpp | 213 + boost/date_time/wrapping_int.hpp | 169 + boost/date_time/year_month_day.hpp | 47 + boost/detail/basic_pointerbuf.hpp | 139 + boost/detail/bitmask.hpp | 58 + boost/detail/call_traits.hpp | 172 + boost/detail/container_fwd.hpp | 157 + boost/detail/endian.hpp | 11 + boost/detail/fenv.hpp | 101 + boost/detail/indirect_traits.hpp | 204 + boost/detail/interlocked.hpp | 201 + boost/detail/is_incrementable.hpp | 125 + boost/detail/iterator.hpp | 39 + boost/detail/lcast_precision.hpp | 185 + boost/detail/lightweight_main.hpp | 36 + boost/detail/lightweight_test.hpp | 17 + boost/detail/lightweight_test_report.hpp | 56 + boost/detail/no_exceptions_support.hpp | 17 + boost/detail/reference_content.hpp | 120 + boost/detail/scoped_enum_emulation.hpp | 17 + boost/detail/sp_typeinfo.hpp | 36 + boost/detail/utf8_codecvt_facet.hpp | 219 + boost/detail/utf8_codecvt_facet.ipp | 289 + .../winapi/detail/deprecated_namespace.hpp | 28 + boost/detail/winapi/get_current_process.hpp | 20 + boost/detail/winapi/get_current_thread.hpp | 20 + boost/detail/winapi/get_last_error.hpp | 20 + boost/detail/winapi/get_process_times.hpp | 20 + boost/detail/winapi/get_thread_times.hpp | 20 + boost/detail/winapi/time.hpp | 20 + boost/detail/winapi/timers.hpp | 20 + boost/detail/workaround.hpp | 10 + boost/enable_shared_from_this.hpp | 18 + boost/exception/current_exception_cast.hpp | 43 + .../detail/clone_current_exception.hpp | 56 + boost/exception/detail/error_info_impl.hpp | 102 + boost/exception/detail/exception_ptr.hpp | 514 + .../exception/detail/is_output_streamable.hpp | 61 + boost/exception/detail/object_hex_dump.hpp | 51 + boost/exception/detail/shared_ptr.hpp | 17 + boost/exception/detail/type_info.hpp | 82 + boost/exception/diagnostic_information.hpp | 204 + boost/exception/exception.hpp | 521 + boost/exception/get_error_info.hpp | 133 + boost/exception/info.hpp | 277 + boost/exception/to_string.hpp | 89 + boost/exception/to_string_stub.hpp | 118 + boost/exception_ptr.hpp | 11 + boost/filesystem.hpp | 21 + boost/filesystem/config.hpp | 110 + boost/filesystem/convenience.hpp | 58 + boost/filesystem/detail/macro_value.hpp | 44 + .../filesystem/detail/utf8_codecvt_facet.hpp | 24 + boost/filesystem/exception.hpp | 9 + boost/filesystem/fstream.hpp | 182 + boost/filesystem/operations.hpp | 1357 + boost/filesystem/path.hpp | 1015 + boost/filesystem/path_traits.hpp | 352 + boost/filesystem/string_file.hpp | 43 + boost/function.hpp | 74 + boost/function/detail/function_iterate.hpp | 16 + boost/function/detail/gen_maybe_include.pl | 39 + boost/function/detail/maybe_include.hpp | 369 + boost/function/detail/prologue.hpp | 26 + boost/function/function0.hpp | 12 + boost/function/function1.hpp | 12 + boost/function/function10.hpp | 12 + boost/function/function2.hpp | 12 + boost/function/function3.hpp | 12 + boost/function/function4.hpp | 12 + boost/function/function5.hpp | 12 + boost/function/function6.hpp | 12 + boost/function/function7.hpp | 12 + boost/function/function8.hpp | 12 + boost/function/function9.hpp | 12 + boost/function/function_base.hpp | 886 + boost/function/function_fwd.hpp | 69 + boost/function/function_template.hpp | 1187 + boost/function_equal.hpp | 28 + boost/functional/hash.hpp | 6 + boost/functional/hash_fwd.hpp | 6 + boost/get_pointer.hpp | 76 + boost/indirect_reference.hpp | 43 + boost/integer.hpp | 262 + boost/integer/common_factor_rt.hpp | 578 + boost/integer/static_log2.hpp | 127 + boost/integer_fwd.hpp | 190 + boost/integer_traits.hpp | 256 + boost/intrusive/detail/algorithm.hpp | 90 + boost/intrusive/detail/config_begin.hpp | 43 + boost/intrusive/detail/config_end.hpp | 15 + .../has_member_function_callable_with.hpp | 366 + boost/intrusive/detail/iterator.hpp | 262 + .../intrusive/detail/minimal_pair_header.hpp | 30 + boost/intrusive/detail/mpl.hpp | 216 + boost/intrusive/detail/reverse_iterator.hpp | 165 + boost/intrusive/detail/std_fwd.hpp | 43 + boost/intrusive/detail/workaround.hpp | 53 + boost/intrusive/pack_options.hpp | 374 + boost/intrusive/pointer_rebind.hpp | 188 + boost/intrusive/pointer_traits.hpp | 318 + boost/intrusive_ptr.hpp | 18 + boost/io/detail/quoted_manip.hpp | 190 + boost/io/ios_state.hpp | 439 + boost/io_fwd.hpp | 67 + boost/is_placeholder.hpp | 31 + boost/iterator/advance.hpp | 84 + boost/iterator/detail/config_def.hpp | 128 + boost/iterator/detail/config_undef.hpp | 24 + boost/iterator/detail/enable_if.hpp | 83 + .../detail/facade_iterator_category.hpp | 193 + boost/iterator/filter_iterator.hpp | 136 + boost/iterator/indirect_iterator.hpp | 145 + boost/iterator/interoperable.hpp | 54 + boost/iterator/iterator_adaptor.hpp | 358 + boost/iterator/iterator_categories.hpp | 216 + boost/iterator/iterator_concepts.hpp | 273 + boost/iterator/iterator_facade.hpp | 981 + boost/iterator/iterator_traits.hpp | 61 + boost/iterator/minimum_category.hpp | 95 + boost/iterator/reverse_iterator.hpp | 77 + boost/iterator/transform_iterator.hpp | 175 + boost/lexical_cast.hpp | 105 + boost/lexical_cast/bad_lexical_cast.hpp | 101 + .../lexical_cast/detail/converter_lexical.hpp | 498 + .../detail/converter_lexical_streams.hpp | 786 + .../lexical_cast/detail/converter_numeric.hpp | 172 + boost/lexical_cast/detail/inf_nan.hpp | 197 + boost/lexical_cast/detail/is_character.hpp | 58 + .../detail/lcast_char_constants.hpp | 46 + .../detail/lcast_unsigned_converters.hpp | 294 + boost/lexical_cast/detail/widest_char.hpp | 40 + boost/lexical_cast/try_lexical_convert.hpp | 227 + boost/limits.hpp | 146 + boost/make_shared.hpp | 16 + boost/math/policies/policy.hpp | 1040 + .../special_functions/detail/fp_traits.hpp | 581 + .../special_functions/detail/round_fwd.hpp | 93 + boost/math/special_functions/fpclassify.hpp | 640 + boost/math/special_functions/math_fwd.hpp | 1651 ++ boost/math/special_functions/sign.hpp | 194 + boost/math/tools/config.hpp | 469 + boost/math/tools/promotion.hpp | 182 + boost/math/tools/real_cast.hpp | 31 + boost/math/tools/user.hpp | 105 + boost/mem_fn.hpp | 24 + boost/memory_order.hpp | 88 + boost/move/adl_move_swap.hpp | 272 + boost/move/algo/adaptive_merge.hpp | 320 + .../move/algo/detail/adaptive_sort_merge.hpp | 1690 ++ boost/move/algo/detail/basic_op.hpp | 121 + boost/move/algo/detail/heap_sort.hpp | 111 + boost/move/algo/detail/insertion_sort.hpp | 128 + boost/move/algo/detail/is_sorted.hpp | 55 + boost/move/algo/detail/merge.hpp | 553 + boost/move/algo/detail/merge_sort.hpp | 139 + boost/move/algo/detail/set_difference.hpp | 207 + boost/move/algo/move.hpp | 156 + boost/move/algo/predicate.hpp | 86 + boost/move/algo/unique.hpp | 55 + boost/move/core.hpp | 494 + boost/move/default_delete.hpp | 217 + boost/move/detail/config_begin.hpp | 21 + boost/move/detail/config_end.hpp | 12 + boost/move/detail/destruct_n.hpp | 66 + boost/move/detail/fwd_macros.hpp | 881 + boost/move/detail/iterator_to_raw_pointer.hpp | 59 + boost/move/detail/iterator_traits.hpp | 77 + boost/move/detail/meta_utils.hpp | 585 + boost/move/detail/meta_utils_core.hpp | 132 + boost/move/detail/move_helpers.hpp | 256 + boost/move/detail/placement_new.hpp | 30 + boost/move/detail/pointer_element.hpp | 168 + boost/move/detail/reverse_iterator.hpp | 171 + boost/move/detail/std_ns_begin.hpp | 30 + boost/move/detail/std_ns_end.hpp | 14 + boost/move/detail/to_raw_pointer.hpp | 45 + boost/move/detail/type_traits.hpp | 1086 + boost/move/detail/unique_ptr_meta_utils.hpp | 591 + boost/move/detail/workaround.hpp | 69 + boost/move/iterator.hpp | 311 + boost/move/make_unique.hpp | 238 + boost/move/traits.hpp | 77 + boost/move/unique_ptr.hpp | 871 + boost/move/utility.hpp | 150 + boost/move/utility_core.hpp | 318 + boost/mpl/O1_size.hpp | 40 + boost/mpl/O1_size_fwd.hpp | 24 + boost/mpl/advance.hpp | 76 + boost/mpl/advance_fwd.hpp | 28 + boost/mpl/always.hpp | 38 + boost/mpl/and.hpp | 60 + boost/mpl/apply.hpp | 229 + boost/mpl/apply_fwd.hpp | 107 + boost/mpl/apply_wrap.hpp | 234 + boost/mpl/arg.hpp | 131 + boost/mpl/arg_fwd.hpp | 28 + boost/mpl/assert.hpp | 439 + boost/mpl/at.hpp | 52 + boost/mpl/at_fwd.hpp | 24 + boost/mpl/aux_/O1_size_impl.hpp | 87 + boost/mpl/aux_/adl_barrier.hpp | 48 + boost/mpl/aux_/advance_backward.hpp | 128 + boost/mpl/aux_/advance_forward.hpp | 127 + boost/mpl/aux_/arg_typedef.hpp | 31 + boost/mpl/aux_/arithmetic_op.hpp | 92 + boost/mpl/aux_/arity.hpp | 39 + boost/mpl/aux_/arity_spec.hpp | 67 + boost/mpl/aux_/at_impl.hpp | 45 + boost/mpl/aux_/begin_end_impl.hpp | 101 + boost/mpl/aux_/clear_impl.hpp | 35 + boost/mpl/aux_/common_name_wknd.hpp | 34 + boost/mpl/aux_/comparison_op.hpp | 83 + boost/mpl/aux_/config/adl.hpp | 40 + boost/mpl/aux_/config/arrays.hpp | 30 + boost/mpl/aux_/config/bcc.hpp | 28 + boost/mpl/aux_/config/bind.hpp | 33 + boost/mpl/aux_/config/compiler.hpp | 66 + boost/mpl/aux_/config/ctps.hpp | 30 + boost/mpl/aux_/config/dependent_nttp.hpp | 35 + boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp | 27 + boost/mpl/aux_/config/dtp.hpp | 46 + boost/mpl/aux_/config/eti.hpp | 47 + boost/mpl/aux_/config/forwarding.hpp | 27 + boost/mpl/aux_/config/gcc.hpp | 23 + boost/mpl/aux_/config/gpu.hpp | 35 + boost/mpl/aux_/config/has_apply.hpp | 32 + boost/mpl/aux_/config/has_xxx.hpp | 34 + boost/mpl/aux_/config/integral.hpp | 38 + boost/mpl/aux_/config/intel.hpp | 21 + boost/mpl/aux_/config/lambda.hpp | 32 + boost/mpl/aux_/config/msvc.hpp | 21 + boost/mpl/aux_/config/msvc_typename.hpp | 26 + boost/mpl/aux_/config/nttp.hpp | 41 + boost/mpl/aux_/config/overload_resolution.hpp | 29 + boost/mpl/aux_/config/pp_counter.hpp | 26 + boost/mpl/aux_/config/preprocessor.hpp | 39 + boost/mpl/aux_/config/static_constant.hpp | 25 + boost/mpl/aux_/config/ttp.hpp | 41 + boost/mpl/aux_/config/typeof.hpp | 38 + boost/mpl/aux_/config/use_preprocessed.hpp | 19 + boost/mpl/aux_/config/workaround.hpp | 19 + boost/mpl/aux_/contains_impl.hpp | 61 + boost/mpl/aux_/count_args.hpp | 105 + boost/mpl/aux_/find_if_pred.hpp | 31 + boost/mpl/aux_/fold_impl.hpp | 43 + boost/mpl/aux_/fold_impl_body.hpp | 365 + boost/mpl/aux_/full_lambda.hpp | 354 + boost/mpl/aux_/has_apply.hpp | 32 + boost/mpl/aux_/has_begin.hpp | 23 + boost/mpl/aux_/has_rebind.hpp | 99 + boost/mpl/aux_/has_size.hpp | 23 + boost/mpl/aux_/has_tag.hpp | 23 + boost/mpl/aux_/has_type.hpp | 23 + boost/mpl/aux_/include_preprocessed.hpp | 42 + boost/mpl/aux_/inserter_algorithm.hpp | 159 + boost/mpl/aux_/integral_wrapper.hpp | 93 + boost/mpl/aux_/is_msvc_eti_arg.hpp | 64 + boost/mpl/aux_/iter_apply.hpp | 47 + boost/mpl/aux_/iter_fold_if_impl.hpp | 210 + boost/mpl/aux_/iter_fold_impl.hpp | 42 + boost/mpl/aux_/lambda_arity_param.hpp | 25 + boost/mpl/aux_/lambda_no_ctps.hpp | 193 + boost/mpl/aux_/lambda_spec.hpp | 49 + boost/mpl/aux_/lambda_support.hpp | 169 + boost/mpl/aux_/largest_int.hpp | 63 + boost/mpl/aux_/logical_op.hpp | 165 + boost/mpl/aux_/msvc_dtw.hpp | 68 + boost/mpl/aux_/msvc_eti_base.hpp | 77 + boost/mpl/aux_/msvc_is_class.hpp | 58 + boost/mpl/aux_/msvc_never_true.hpp | 34 + boost/mpl/aux_/msvc_type.hpp | 62 + boost/mpl/aux_/na.hpp | 95 + boost/mpl/aux_/na_assert.hpp | 34 + boost/mpl/aux_/na_fwd.hpp | 31 + boost/mpl/aux_/na_spec.hpp | 175 + boost/mpl/aux_/nested_type_wknd.hpp | 48 + boost/mpl/aux_/nttp_decl.hpp | 35 + boost/mpl/aux_/numeric_cast_utils.hpp | 77 + boost/mpl/aux_/numeric_op.hpp | 315 + .../preprocessed/bcc/advance_backward.hpp | 97 + .../aux_/preprocessed/bcc/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/bcc/and.hpp | 69 + boost/mpl/aux_/preprocessed/bcc/apply.hpp | 169 + boost/mpl/aux_/preprocessed/bcc/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/bcc/apply_wrap.hpp | 461 + boost/mpl/aux_/preprocessed/bcc/arg.hpp | 117 + .../mpl/aux_/preprocessed/bcc/basic_bind.hpp | 300 + boost/mpl/aux_/preprocessed/bcc/bind.hpp | 397 + boost/mpl/aux_/preprocessed/bcc/bind_fwd.hpp | 46 + boost/mpl/aux_/preprocessed/bcc/bitand.hpp | 147 + boost/mpl/aux_/preprocessed/bcc/bitor.hpp | 147 + boost/mpl/aux_/preprocessed/bcc/bitxor.hpp | 147 + boost/mpl/aux_/preprocessed/bcc/deque.hpp | 323 + boost/mpl/aux_/preprocessed/bcc/divides.hpp | 146 + boost/mpl/aux_/preprocessed/bcc/equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/bcc/fold_impl.hpp | 180 + .../mpl/aux_/preprocessed/bcc/full_lambda.hpp | 558 + boost/mpl/aux_/preprocessed/bcc/greater.hpp | 94 + .../aux_/preprocessed/bcc/greater_equal.hpp | 94 + boost/mpl/aux_/preprocessed/bcc/inherit.hpp | 139 + .../preprocessed/bcc/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/bcc/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/bcc/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/bcc/less.hpp | 94 + .../mpl/aux_/preprocessed/bcc/less_equal.hpp | 94 + boost/mpl/aux_/preprocessed/bcc/list.hpp | 323 + boost/mpl/aux_/preprocessed/bcc/list_c.hpp | 328 + boost/mpl/aux_/preprocessed/bcc/map.hpp | 323 + boost/mpl/aux_/preprocessed/bcc/minus.hpp | 146 + boost/mpl/aux_/preprocessed/bcc/modulus.hpp | 101 + .../aux_/preprocessed/bcc/not_equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/bcc/or.hpp | 69 + .../aux_/preprocessed/bcc/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/bcc/plus.hpp | 146 + boost/mpl/aux_/preprocessed/bcc/quote.hpp | 119 + .../preprocessed/bcc/reverse_fold_impl.hpp | 295 + .../bcc/reverse_iter_fold_impl.hpp | 295 + boost/mpl/aux_/preprocessed/bcc/set.hpp | 323 + boost/mpl/aux_/preprocessed/bcc/set_c.hpp | 328 + .../mpl/aux_/preprocessed/bcc/shift_left.hpp | 99 + .../mpl/aux_/preprocessed/bcc/shift_right.hpp | 99 + .../aux_/preprocessed/bcc/template_arity.hpp | 40 + boost/mpl/aux_/preprocessed/bcc/times.hpp | 146 + .../mpl/aux_/preprocessed/bcc/unpack_args.hpp | 97 + boost/mpl/aux_/preprocessed/bcc/vector.hpp | 323 + boost/mpl/aux_/preprocessed/bcc/vector_c.hpp | 309 + .../preprocessed/bcc551/advance_backward.hpp | 97 + .../preprocessed/bcc551/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/bcc551/and.hpp | 69 + boost/mpl/aux_/preprocessed/bcc551/apply.hpp | 169 + .../aux_/preprocessed/bcc551/apply_fwd.hpp | 52 + .../aux_/preprocessed/bcc551/apply_wrap.hpp | 456 + boost/mpl/aux_/preprocessed/bcc551/arg.hpp | 123 + .../aux_/preprocessed/bcc551/basic_bind.hpp | 306 + boost/mpl/aux_/preprocessed/bcc551/bind.hpp | 403 + .../mpl/aux_/preprocessed/bcc551/bind_fwd.hpp | 46 + boost/mpl/aux_/preprocessed/bcc551/bitand.hpp | 147 + boost/mpl/aux_/preprocessed/bcc551/bitor.hpp | 147 + boost/mpl/aux_/preprocessed/bcc551/bitxor.hpp | 147 + boost/mpl/aux_/preprocessed/bcc551/deque.hpp | 323 + .../mpl/aux_/preprocessed/bcc551/divides.hpp | 146 + .../mpl/aux_/preprocessed/bcc551/equal_to.hpp | 94 + .../aux_/preprocessed/bcc551/fold_impl.hpp | 180 + .../aux_/preprocessed/bcc551/full_lambda.hpp | 558 + .../mpl/aux_/preprocessed/bcc551/greater.hpp | 94 + .../preprocessed/bcc551/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/bcc551/inherit.hpp | 141 + .../preprocessed/bcc551/iter_fold_if_impl.hpp | 133 + .../preprocessed/bcc551/iter_fold_impl.hpp | 180 + .../preprocessed/bcc551/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/bcc551/less.hpp | 94 + .../aux_/preprocessed/bcc551/less_equal.hpp | 94 + boost/mpl/aux_/preprocessed/bcc551/list.hpp | 323 + boost/mpl/aux_/preprocessed/bcc551/list_c.hpp | 328 + boost/mpl/aux_/preprocessed/bcc551/map.hpp | 323 + boost/mpl/aux_/preprocessed/bcc551/minus.hpp | 146 + .../mpl/aux_/preprocessed/bcc551/modulus.hpp | 101 + .../aux_/preprocessed/bcc551/not_equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/bcc551/or.hpp | 69 + .../aux_/preprocessed/bcc551/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/bcc551/plus.hpp | 146 + boost/mpl/aux_/preprocessed/bcc551/quote.hpp | 11 + .../preprocessed/bcc551/reverse_fold_impl.hpp | 295 + .../bcc551/reverse_iter_fold_impl.hpp | 295 + boost/mpl/aux_/preprocessed/bcc551/set.hpp | 323 + boost/mpl/aux_/preprocessed/bcc551/set_c.hpp | 328 + .../aux_/preprocessed/bcc551/shift_left.hpp | 99 + .../aux_/preprocessed/bcc551/shift_right.hpp | 99 + .../preprocessed/bcc551/template_arity.hpp | 40 + boost/mpl/aux_/preprocessed/bcc551/times.hpp | 146 + .../aux_/preprocessed/bcc551/unpack_args.hpp | 97 + boost/mpl/aux_/preprocessed/bcc551/vector.hpp | 323 + .../mpl/aux_/preprocessed/bcc551/vector_c.hpp | 309 + .../bcc_pre590/advance_backward.hpp | 97 + .../bcc_pre590/advance_forward.hpp | 97 + .../mpl/aux_/preprocessed/bcc_pre590/and.hpp | 69 + .../aux_/preprocessed/bcc_pre590/apply.hpp | 169 + .../preprocessed/bcc_pre590/apply_fwd.hpp | 52 + .../preprocessed/bcc_pre590/apply_wrap.hpp | 456 + .../mpl/aux_/preprocessed/bcc_pre590/arg.hpp | 117 + .../preprocessed/bcc_pre590/basic_bind.hpp | 300 + .../mpl/aux_/preprocessed/bcc_pre590/bind.hpp | 397 + .../aux_/preprocessed/bcc_pre590/bind_fwd.hpp | 46 + .../aux_/preprocessed/bcc_pre590/bitand.hpp | 147 + .../aux_/preprocessed/bcc_pre590/bitor.hpp | 147 + .../aux_/preprocessed/bcc_pre590/bitxor.hpp | 147 + .../aux_/preprocessed/bcc_pre590/deque.hpp | 323 + .../aux_/preprocessed/bcc_pre590/divides.hpp | 146 + .../aux_/preprocessed/bcc_pre590/equal_to.hpp | 94 + .../preprocessed/bcc_pre590/fold_impl.hpp | 180 + .../preprocessed/bcc_pre590/full_lambda.hpp | 558 + .../aux_/preprocessed/bcc_pre590/greater.hpp | 94 + .../preprocessed/bcc_pre590/greater_equal.hpp | 94 + .../aux_/preprocessed/bcc_pre590/inherit.hpp | 139 + .../bcc_pre590/iter_fold_if_impl.hpp | 133 + .../bcc_pre590/iter_fold_impl.hpp | 180 + .../bcc_pre590/lambda_no_ctps.hpp | 229 + .../mpl/aux_/preprocessed/bcc_pre590/less.hpp | 94 + .../preprocessed/bcc_pre590/less_equal.hpp | 94 + .../mpl/aux_/preprocessed/bcc_pre590/list.hpp | 323 + .../aux_/preprocessed/bcc_pre590/list_c.hpp | 328 + .../mpl/aux_/preprocessed/bcc_pre590/map.hpp | 323 + .../aux_/preprocessed/bcc_pre590/minus.hpp | 146 + .../aux_/preprocessed/bcc_pre590/modulus.hpp | 101 + .../preprocessed/bcc_pre590/not_equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/bcc_pre590/or.hpp | 69 + .../preprocessed/bcc_pre590/placeholders.hpp | 105 + .../mpl/aux_/preprocessed/bcc_pre590/plus.hpp | 146 + .../aux_/preprocessed/bcc_pre590/quote.hpp | 11 + .../bcc_pre590/reverse_fold_impl.hpp | 295 + .../bcc_pre590/reverse_iter_fold_impl.hpp | 295 + .../mpl/aux_/preprocessed/bcc_pre590/set.hpp | 323 + .../aux_/preprocessed/bcc_pre590/set_c.hpp | 328 + .../preprocessed/bcc_pre590/shift_left.hpp | 99 + .../preprocessed/bcc_pre590/shift_right.hpp | 99 + .../bcc_pre590/template_arity.hpp | 40 + .../aux_/preprocessed/bcc_pre590/times.hpp | 146 + .../preprocessed/bcc_pre590/unpack_args.hpp | 97 + .../aux_/preprocessed/bcc_pre590/vector.hpp | 323 + .../aux_/preprocessed/bcc_pre590/vector_c.hpp | 309 + .../preprocessed/dmc/advance_backward.hpp | 97 + .../aux_/preprocessed/dmc/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/dmc/and.hpp | 69 + boost/mpl/aux_/preprocessed/dmc/apply.hpp | 169 + boost/mpl/aux_/preprocessed/dmc/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/dmc/apply_wrap.hpp | 84 + boost/mpl/aux_/preprocessed/dmc/arg.hpp | 123 + .../mpl/aux_/preprocessed/dmc/basic_bind.hpp | 406 + boost/mpl/aux_/preprocessed/dmc/bind.hpp | 515 + boost/mpl/aux_/preprocessed/dmc/bind_fwd.hpp | 53 + boost/mpl/aux_/preprocessed/dmc/bitand.hpp | 147 + boost/mpl/aux_/preprocessed/dmc/bitor.hpp | 147 + boost/mpl/aux_/preprocessed/dmc/bitxor.hpp | 147 + boost/mpl/aux_/preprocessed/dmc/deque.hpp | 323 + boost/mpl/aux_/preprocessed/dmc/divides.hpp | 146 + boost/mpl/aux_/preprocessed/dmc/equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/dmc/fold_impl.hpp | 180 + .../mpl/aux_/preprocessed/dmc/full_lambda.hpp | 536 + boost/mpl/aux_/preprocessed/dmc/greater.hpp | 94 + .../aux_/preprocessed/dmc/greater_equal.hpp | 94 + boost/mpl/aux_/preprocessed/dmc/inherit.hpp | 141 + .../preprocessed/dmc/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/dmc/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/dmc/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/dmc/less.hpp | 94 + .../mpl/aux_/preprocessed/dmc/less_equal.hpp | 94 + boost/mpl/aux_/preprocessed/dmc/list.hpp | 323 + boost/mpl/aux_/preprocessed/dmc/list_c.hpp | 328 + boost/mpl/aux_/preprocessed/dmc/map.hpp | 323 + boost/mpl/aux_/preprocessed/dmc/minus.hpp | 146 + boost/mpl/aux_/preprocessed/dmc/modulus.hpp | 101 + .../aux_/preprocessed/dmc/not_equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/dmc/or.hpp | 69 + .../aux_/preprocessed/dmc/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/dmc/plus.hpp | 146 + boost/mpl/aux_/preprocessed/dmc/quote.hpp | 123 + .../preprocessed/dmc/reverse_fold_impl.hpp | 231 + .../dmc/reverse_iter_fold_impl.hpp | 231 + boost/mpl/aux_/preprocessed/dmc/set.hpp | 323 + boost/mpl/aux_/preprocessed/dmc/set_c.hpp | 328 + .../mpl/aux_/preprocessed/dmc/shift_left.hpp | 99 + .../mpl/aux_/preprocessed/dmc/shift_right.hpp | 99 + .../aux_/preprocessed/dmc/template_arity.hpp | 11 + boost/mpl/aux_/preprocessed/dmc/times.hpp | 146 + .../mpl/aux_/preprocessed/dmc/unpack_args.hpp | 94 + boost/mpl/aux_/preprocessed/dmc/vector.hpp | 323 + boost/mpl/aux_/preprocessed/dmc/vector_c.hpp | 309 + .../preprocessed/gcc/advance_backward.hpp | 97 + .../aux_/preprocessed/gcc/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/gcc/and.hpp | 69 + boost/mpl/aux_/preprocessed/gcc/apply.hpp | 169 + boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/gcc/apply_wrap.hpp | 84 + boost/mpl/aux_/preprocessed/gcc/arg.hpp | 123 + .../mpl/aux_/preprocessed/gcc/basic_bind.hpp | 440 + boost/mpl/aux_/preprocessed/gcc/bind.hpp | 561 + boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp | 52 + boost/mpl/aux_/preprocessed/gcc/bitand.hpp | 147 + boost/mpl/aux_/preprocessed/gcc/bitor.hpp | 147 + boost/mpl/aux_/preprocessed/gcc/bitxor.hpp | 147 + boost/mpl/aux_/preprocessed/gcc/deque.hpp | 323 + boost/mpl/aux_/preprocessed/gcc/divides.hpp | 146 + boost/mpl/aux_/preprocessed/gcc/equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp | 180 + .../mpl/aux_/preprocessed/gcc/full_lambda.hpp | 558 + boost/mpl/aux_/preprocessed/gcc/greater.hpp | 94 + .../aux_/preprocessed/gcc/greater_equal.hpp | 94 + boost/mpl/aux_/preprocessed/gcc/inherit.hpp | 141 + .../preprocessed/gcc/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/gcc/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/gcc/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/gcc/less.hpp | 94 + .../mpl/aux_/preprocessed/gcc/less_equal.hpp | 94 + boost/mpl/aux_/preprocessed/gcc/list.hpp | 323 + boost/mpl/aux_/preprocessed/gcc/list_c.hpp | 328 + boost/mpl/aux_/preprocessed/gcc/map.hpp | 323 + boost/mpl/aux_/preprocessed/gcc/minus.hpp | 146 + boost/mpl/aux_/preprocessed/gcc/modulus.hpp | 101 + .../aux_/preprocessed/gcc/not_equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/gcc/or.hpp | 69 + .../aux_/preprocessed/gcc/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/gcc/plus.hpp | 146 + boost/mpl/aux_/preprocessed/gcc/quote.hpp | 123 + .../preprocessed/gcc/reverse_fold_impl.hpp | 231 + .../gcc/reverse_iter_fold_impl.hpp | 231 + boost/mpl/aux_/preprocessed/gcc/set.hpp | 323 + boost/mpl/aux_/preprocessed/gcc/set_c.hpp | 328 + .../mpl/aux_/preprocessed/gcc/shift_left.hpp | 99 + .../mpl/aux_/preprocessed/gcc/shift_right.hpp | 99 + .../aux_/preprocessed/gcc/template_arity.hpp | 97 + boost/mpl/aux_/preprocessed/gcc/times.hpp | 146 + .../mpl/aux_/preprocessed/gcc/unpack_args.hpp | 94 + boost/mpl/aux_/preprocessed/gcc/vector.hpp | 323 + boost/mpl/aux_/preprocessed/gcc/vector_c.hpp | 309 + .../preprocessed/msvc60/advance_backward.hpp | 132 + .../preprocessed/msvc60/advance_forward.hpp | 132 + boost/mpl/aux_/preprocessed/msvc60/and.hpp | 73 + boost/mpl/aux_/preprocessed/msvc60/apply.hpp | 166 + .../aux_/preprocessed/msvc60/apply_fwd.hpp | 46 + .../aux_/preprocessed/msvc60/apply_wrap.hpp | 247 + boost/mpl/aux_/preprocessed/msvc60/arg.hpp | 123 + .../aux_/preprocessed/msvc60/basic_bind.hpp | 328 + boost/mpl/aux_/preprocessed/msvc60/bind.hpp | 432 + .../mpl/aux_/preprocessed/msvc60/bind_fwd.hpp | 46 + boost/mpl/aux_/preprocessed/msvc60/bitand.hpp | 149 + boost/mpl/aux_/preprocessed/msvc60/bitor.hpp | 149 + boost/mpl/aux_/preprocessed/msvc60/bitxor.hpp | 149 + boost/mpl/aux_/preprocessed/msvc60/deque.hpp | 556 + .../mpl/aux_/preprocessed/msvc60/divides.hpp | 148 + .../mpl/aux_/preprocessed/msvc60/equal_to.hpp | 102 + .../aux_/preprocessed/msvc60/fold_impl.hpp | 293 + .../aux_/preprocessed/msvc60/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/msvc60/greater.hpp | 102 + .../preprocessed/msvc60/greater_equal.hpp | 102 + .../mpl/aux_/preprocessed/msvc60/inherit.hpp | 166 + .../preprocessed/msvc60/iter_fold_if_impl.hpp | 133 + .../preprocessed/msvc60/iter_fold_impl.hpp | 293 + .../preprocessed/msvc60/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/msvc60/less.hpp | 102 + .../aux_/preprocessed/msvc60/less_equal.hpp | 102 + boost/mpl/aux_/preprocessed/msvc60/list.hpp | 556 + boost/mpl/aux_/preprocessed/msvc60/list_c.hpp | 534 + boost/mpl/aux_/preprocessed/msvc60/map.hpp | 556 + boost/mpl/aux_/preprocessed/msvc60/minus.hpp | 148 + .../mpl/aux_/preprocessed/msvc60/modulus.hpp | 115 + .../aux_/preprocessed/msvc60/not_equal_to.hpp | 102 + boost/mpl/aux_/preprocessed/msvc60/or.hpp | 73 + .../aux_/preprocessed/msvc60/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/msvc60/plus.hpp | 148 + boost/mpl/aux_/preprocessed/msvc60/quote.hpp | 11 + .../preprocessed/msvc60/reverse_fold_impl.hpp | 343 + .../msvc60/reverse_iter_fold_impl.hpp | 343 + boost/mpl/aux_/preprocessed/msvc60/set.hpp | 556 + boost/mpl/aux_/preprocessed/msvc60/set_c.hpp | 534 + .../aux_/preprocessed/msvc60/shift_left.hpp | 114 + .../aux_/preprocessed/msvc60/shift_right.hpp | 114 + .../preprocessed/msvc60/template_arity.hpp | 46 + boost/mpl/aux_/preprocessed/msvc60/times.hpp | 148 + .../aux_/preprocessed/msvc60/unpack_args.hpp | 109 + boost/mpl/aux_/preprocessed/msvc60/vector.hpp | 556 + .../mpl/aux_/preprocessed/msvc60/vector_c.hpp | 534 + .../preprocessed/msvc70/advance_backward.hpp | 97 + .../preprocessed/msvc70/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/msvc70/and.hpp | 71 + boost/mpl/aux_/preprocessed/msvc70/apply.hpp | 160 + .../aux_/preprocessed/msvc70/apply_fwd.hpp | 46 + .../aux_/preprocessed/msvc70/apply_wrap.hpp | 138 + boost/mpl/aux_/preprocessed/msvc70/arg.hpp | 123 + .../aux_/preprocessed/msvc70/basic_bind.hpp | 328 + boost/mpl/aux_/preprocessed/msvc70/bind.hpp | 432 + .../mpl/aux_/preprocessed/msvc70/bind_fwd.hpp | 46 + boost/mpl/aux_/preprocessed/msvc70/bitand.hpp | 151 + boost/mpl/aux_/preprocessed/msvc70/bitor.hpp | 151 + boost/mpl/aux_/preprocessed/msvc70/bitxor.hpp | 151 + boost/mpl/aux_/preprocessed/msvc70/deque.hpp | 556 + .../mpl/aux_/preprocessed/msvc70/divides.hpp | 150 + .../mpl/aux_/preprocessed/msvc70/equal_to.hpp | 102 + .../aux_/preprocessed/msvc70/fold_impl.hpp | 245 + .../aux_/preprocessed/msvc70/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/msvc70/greater.hpp | 102 + .../preprocessed/msvc70/greater_equal.hpp | 102 + .../mpl/aux_/preprocessed/msvc70/inherit.hpp | 166 + .../preprocessed/msvc70/iter_fold_if_impl.hpp | 133 + .../preprocessed/msvc70/iter_fold_impl.hpp | 245 + .../preprocessed/msvc70/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/msvc70/less.hpp | 102 + .../aux_/preprocessed/msvc70/less_equal.hpp | 102 + boost/mpl/aux_/preprocessed/msvc70/list.hpp | 556 + boost/mpl/aux_/preprocessed/msvc70/list_c.hpp | 534 + boost/mpl/aux_/preprocessed/msvc70/map.hpp | 556 + boost/mpl/aux_/preprocessed/msvc70/minus.hpp | 150 + .../mpl/aux_/preprocessed/msvc70/modulus.hpp | 115 + .../aux_/preprocessed/msvc70/not_equal_to.hpp | 102 + boost/mpl/aux_/preprocessed/msvc70/or.hpp | 71 + .../aux_/preprocessed/msvc70/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/msvc70/plus.hpp | 150 + boost/mpl/aux_/preprocessed/msvc70/quote.hpp | 116 + .../preprocessed/msvc70/reverse_fold_impl.hpp | 295 + .../msvc70/reverse_iter_fold_impl.hpp | 295 + boost/mpl/aux_/preprocessed/msvc70/set.hpp | 556 + boost/mpl/aux_/preprocessed/msvc70/set_c.hpp | 534 + .../aux_/preprocessed/msvc70/shift_left.hpp | 114 + .../aux_/preprocessed/msvc70/shift_right.hpp | 114 + .../preprocessed/msvc70/template_arity.hpp | 46 + boost/mpl/aux_/preprocessed/msvc70/times.hpp | 150 + .../aux_/preprocessed/msvc70/unpack_args.hpp | 109 + boost/mpl/aux_/preprocessed/msvc70/vector.hpp | 556 + .../mpl/aux_/preprocessed/msvc70/vector_c.hpp | 534 + .../preprocessed/mwcw/advance_backward.hpp | 97 + .../preprocessed/mwcw/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/mwcw/and.hpp | 69 + boost/mpl/aux_/preprocessed/mwcw/apply.hpp | 169 + .../mpl/aux_/preprocessed/mwcw/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/mwcw/apply_wrap.hpp | 456 + boost/mpl/aux_/preprocessed/mwcw/arg.hpp | 123 + .../mpl/aux_/preprocessed/mwcw/basic_bind.hpp | 440 + boost/mpl/aux_/preprocessed/mwcw/bind.hpp | 561 + boost/mpl/aux_/preprocessed/mwcw/bind_fwd.hpp | 52 + boost/mpl/aux_/preprocessed/mwcw/bitand.hpp | 147 + boost/mpl/aux_/preprocessed/mwcw/bitor.hpp | 147 + boost/mpl/aux_/preprocessed/mwcw/bitxor.hpp | 147 + boost/mpl/aux_/preprocessed/mwcw/deque.hpp | 323 + boost/mpl/aux_/preprocessed/mwcw/divides.hpp | 146 + boost/mpl/aux_/preprocessed/mwcw/equal_to.hpp | 94 + .../mpl/aux_/preprocessed/mwcw/fold_impl.hpp | 180 + .../aux_/preprocessed/mwcw/full_lambda.hpp | 554 + boost/mpl/aux_/preprocessed/mwcw/greater.hpp | 94 + .../aux_/preprocessed/mwcw/greater_equal.hpp | 94 + boost/mpl/aux_/preprocessed/mwcw/inherit.hpp | 141 + .../preprocessed/mwcw/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/mwcw/iter_fold_impl.hpp | 180 + .../aux_/preprocessed/mwcw/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/mwcw/less.hpp | 94 + .../mpl/aux_/preprocessed/mwcw/less_equal.hpp | 94 + boost/mpl/aux_/preprocessed/mwcw/list.hpp | 323 + boost/mpl/aux_/preprocessed/mwcw/list_c.hpp | 328 + boost/mpl/aux_/preprocessed/mwcw/map.hpp | 323 + boost/mpl/aux_/preprocessed/mwcw/minus.hpp | 146 + boost/mpl/aux_/preprocessed/mwcw/modulus.hpp | 101 + .../aux_/preprocessed/mwcw/not_equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/mwcw/or.hpp | 69 + .../aux_/preprocessed/mwcw/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/mwcw/plus.hpp | 146 + boost/mpl/aux_/preprocessed/mwcw/quote.hpp | 123 + .../preprocessed/mwcw/reverse_fold_impl.hpp | 231 + .../mwcw/reverse_iter_fold_impl.hpp | 231 + boost/mpl/aux_/preprocessed/mwcw/set.hpp | 323 + boost/mpl/aux_/preprocessed/mwcw/set_c.hpp | 328 + .../mpl/aux_/preprocessed/mwcw/shift_left.hpp | 99 + .../aux_/preprocessed/mwcw/shift_right.hpp | 99 + .../aux_/preprocessed/mwcw/template_arity.hpp | 11 + boost/mpl/aux_/preprocessed/mwcw/times.hpp | 146 + .../aux_/preprocessed/mwcw/unpack_args.hpp | 94 + boost/mpl/aux_/preprocessed/mwcw/vector.hpp | 323 + boost/mpl/aux_/preprocessed/mwcw/vector_c.hpp | 309 + .../preprocessed/no_ctps/advance_backward.hpp | 97 + .../preprocessed/no_ctps/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/no_ctps/and.hpp | 73 + boost/mpl/aux_/preprocessed/no_ctps/apply.hpp | 268 + .../aux_/preprocessed/no_ctps/apply_fwd.hpp | 50 + .../aux_/preprocessed/no_ctps/apply_wrap.hpp | 78 + boost/mpl/aux_/preprocessed/no_ctps/arg.hpp | 123 + .../aux_/preprocessed/no_ctps/basic_bind.hpp | 486 + boost/mpl/aux_/preprocessed/no_ctps/bind.hpp | 590 + .../aux_/preprocessed/no_ctps/bind_fwd.hpp | 52 + .../mpl/aux_/preprocessed/no_ctps/bitand.hpp | 134 + boost/mpl/aux_/preprocessed/no_ctps/bitor.hpp | 134 + .../mpl/aux_/preprocessed/no_ctps/bitxor.hpp | 134 + boost/mpl/aux_/preprocessed/no_ctps/deque.hpp | 556 + .../mpl/aux_/preprocessed/no_ctps/divides.hpp | 133 + .../aux_/preprocessed/no_ctps/equal_to.hpp | 94 + .../aux_/preprocessed/no_ctps/fold_impl.hpp | 245 + .../aux_/preprocessed/no_ctps/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/no_ctps/greater.hpp | 94 + .../preprocessed/no_ctps/greater_equal.hpp | 94 + .../mpl/aux_/preprocessed/no_ctps/inherit.hpp | 166 + .../no_ctps/iter_fold_if_impl.hpp | 133 + .../preprocessed/no_ctps/iter_fold_impl.hpp | 245 + .../preprocessed/no_ctps/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/no_ctps/less.hpp | 94 + .../aux_/preprocessed/no_ctps/less_equal.hpp | 94 + boost/mpl/aux_/preprocessed/no_ctps/list.hpp | 556 + .../mpl/aux_/preprocessed/no_ctps/list_c.hpp | 534 + boost/mpl/aux_/preprocessed/no_ctps/map.hpp | 556 + boost/mpl/aux_/preprocessed/no_ctps/minus.hpp | 133 + .../mpl/aux_/preprocessed/no_ctps/modulus.hpp | 101 + .../preprocessed/no_ctps/not_equal_to.hpp | 94 + boost/mpl/aux_/preprocessed/no_ctps/or.hpp | 73 + .../preprocessed/no_ctps/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/no_ctps/plus.hpp | 133 + boost/mpl/aux_/preprocessed/no_ctps/quote.hpp | 116 + .../no_ctps/reverse_fold_impl.hpp | 295 + .../no_ctps/reverse_iter_fold_impl.hpp | 295 + boost/mpl/aux_/preprocessed/no_ctps/set.hpp | 556 + boost/mpl/aux_/preprocessed/no_ctps/set_c.hpp | 534 + .../aux_/preprocessed/no_ctps/shift_left.hpp | 99 + .../aux_/preprocessed/no_ctps/shift_right.hpp | 99 + .../preprocessed/no_ctps/template_arity.hpp | 40 + boost/mpl/aux_/preprocessed/no_ctps/times.hpp | 133 + .../aux_/preprocessed/no_ctps/unpack_args.hpp | 109 + .../mpl/aux_/preprocessed/no_ctps/vector.hpp | 556 + .../aux_/preprocessed/no_ctps/vector_c.hpp | 534 + .../preprocessed/no_ttp/advance_backward.hpp | 97 + .../preprocessed/no_ttp/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/no_ttp/and.hpp | 69 + boost/mpl/aux_/preprocessed/no_ttp/apply.hpp | 169 + .../aux_/preprocessed/no_ttp/apply_fwd.hpp | 52 + .../aux_/preprocessed/no_ttp/apply_wrap.hpp | 84 + boost/mpl/aux_/preprocessed/no_ttp/arg.hpp | 123 + .../aux_/preprocessed/no_ttp/basic_bind.hpp | 369 + boost/mpl/aux_/preprocessed/no_ttp/bind.hpp | 466 + .../mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp | 52 + boost/mpl/aux_/preprocessed/no_ttp/bitand.hpp | 157 + boost/mpl/aux_/preprocessed/no_ttp/bitor.hpp | 157 + boost/mpl/aux_/preprocessed/no_ttp/bitxor.hpp | 157 + boost/mpl/aux_/preprocessed/no_ttp/deque.hpp | 323 + .../mpl/aux_/preprocessed/no_ttp/divides.hpp | 156 + .../mpl/aux_/preprocessed/no_ttp/equal_to.hpp | 98 + .../aux_/preprocessed/no_ttp/fold_impl.hpp | 180 + .../aux_/preprocessed/no_ttp/full_lambda.hpp | 554 + .../mpl/aux_/preprocessed/no_ttp/greater.hpp | 98 + .../preprocessed/no_ttp/greater_equal.hpp | 98 + .../mpl/aux_/preprocessed/no_ttp/inherit.hpp | 141 + .../preprocessed/no_ttp/iter_fold_if_impl.hpp | 133 + .../preprocessed/no_ttp/iter_fold_impl.hpp | 180 + .../preprocessed/no_ttp/lambda_no_ctps.hpp | 229 + boost/mpl/aux_/preprocessed/no_ttp/less.hpp | 98 + .../aux_/preprocessed/no_ttp/less_equal.hpp | 98 + boost/mpl/aux_/preprocessed/no_ttp/list.hpp | 323 + boost/mpl/aux_/preprocessed/no_ttp/list_c.hpp | 328 + boost/mpl/aux_/preprocessed/no_ttp/map.hpp | 323 + boost/mpl/aux_/preprocessed/no_ttp/minus.hpp | 156 + .../mpl/aux_/preprocessed/no_ttp/modulus.hpp | 111 + .../aux_/preprocessed/no_ttp/not_equal_to.hpp | 98 + boost/mpl/aux_/preprocessed/no_ttp/or.hpp | 69 + .../aux_/preprocessed/no_ttp/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/no_ttp/plus.hpp | 156 + boost/mpl/aux_/preprocessed/no_ttp/quote.hpp | 11 + .../preprocessed/no_ttp/reverse_fold_impl.hpp | 231 + .../no_ttp/reverse_iter_fold_impl.hpp | 231 + boost/mpl/aux_/preprocessed/no_ttp/set.hpp | 323 + boost/mpl/aux_/preprocessed/no_ttp/set_c.hpp | 328 + .../aux_/preprocessed/no_ttp/shift_left.hpp | 110 + .../aux_/preprocessed/no_ttp/shift_right.hpp | 110 + .../preprocessed/no_ttp/template_arity.hpp | 40 + boost/mpl/aux_/preprocessed/no_ttp/times.hpp | 156 + .../aux_/preprocessed/no_ttp/unpack_args.hpp | 94 + boost/mpl/aux_/preprocessed/no_ttp/vector.hpp | 323 + .../mpl/aux_/preprocessed/no_ttp/vector_c.hpp | 309 + .../preprocessed/plain/advance_backward.hpp | 97 + .../preprocessed/plain/advance_forward.hpp | 97 + boost/mpl/aux_/preprocessed/plain/and.hpp | 64 + boost/mpl/aux_/preprocessed/plain/apply.hpp | 139 + .../mpl/aux_/preprocessed/plain/apply_fwd.hpp | 52 + .../aux_/preprocessed/plain/apply_wrap.hpp | 84 + boost/mpl/aux_/preprocessed/plain/arg.hpp | 123 + .../aux_/preprocessed/plain/basic_bind.hpp | 440 + boost/mpl/aux_/preprocessed/plain/bind.hpp | 561 + .../mpl/aux_/preprocessed/plain/bind_fwd.hpp | 52 + boost/mpl/aux_/preprocessed/plain/bitand.hpp | 142 + boost/mpl/aux_/preprocessed/plain/bitor.hpp | 142 + boost/mpl/aux_/preprocessed/plain/bitxor.hpp | 142 + boost/mpl/aux_/preprocessed/plain/deque.hpp | 323 + boost/mpl/aux_/preprocessed/plain/divides.hpp | 141 + .../mpl/aux_/preprocessed/plain/equal_to.hpp | 92 + .../mpl/aux_/preprocessed/plain/fold_impl.hpp | 180 + .../aux_/preprocessed/plain/full_lambda.hpp | 554 + boost/mpl/aux_/preprocessed/plain/greater.hpp | 92 + .../aux_/preprocessed/plain/greater_equal.hpp | 92 + boost/mpl/aux_/preprocessed/plain/inherit.hpp | 125 + .../preprocessed/plain/iter_fold_if_impl.hpp | 133 + .../preprocessed/plain/iter_fold_impl.hpp | 180 + .../preprocessed/plain/lambda_no_ctps.hpp | 228 + boost/mpl/aux_/preprocessed/plain/less.hpp | 92 + .../aux_/preprocessed/plain/less_equal.hpp | 92 + boost/mpl/aux_/preprocessed/plain/list.hpp | 323 + boost/mpl/aux_/preprocessed/plain/list_c.hpp | 328 + boost/mpl/aux_/preprocessed/plain/map.hpp | 323 + boost/mpl/aux_/preprocessed/plain/minus.hpp | 141 + boost/mpl/aux_/preprocessed/plain/modulus.hpp | 99 + .../aux_/preprocessed/plain/not_equal_to.hpp | 92 + boost/mpl/aux_/preprocessed/plain/or.hpp | 64 + .../aux_/preprocessed/plain/placeholders.hpp | 105 + boost/mpl/aux_/preprocessed/plain/plus.hpp | 141 + boost/mpl/aux_/preprocessed/plain/quote.hpp | 123 + .../preprocessed/plain/reverse_fold_impl.hpp | 231 + .../plain/reverse_iter_fold_impl.hpp | 231 + boost/mpl/aux_/preprocessed/plain/set.hpp | 323 + boost/mpl/aux_/preprocessed/plain/set_c.hpp | 328 + .../aux_/preprocessed/plain/shift_left.hpp | 97 + .../aux_/preprocessed/plain/shift_right.hpp | 97 + .../preprocessed/plain/template_arity.hpp | 11 + boost/mpl/aux_/preprocessed/plain/times.hpp | 141 + .../aux_/preprocessed/plain/unpack_args.hpp | 94 + boost/mpl/aux_/preprocessed/plain/vector.hpp | 323 + .../mpl/aux_/preprocessed/plain/vector_c.hpp | 309 + boost/mpl/aux_/preprocessor/add.hpp | 65 + .../mpl/aux_/preprocessor/def_params_tail.hpp | 105 + .../mpl/aux_/preprocessor/default_params.hpp | 67 + boost/mpl/aux_/preprocessor/enum.hpp | 62 + boost/mpl/aux_/preprocessor/ext_params.hpp | 78 + boost/mpl/aux_/preprocessor/filter_params.hpp | 28 + boost/mpl/aux_/preprocessor/params.hpp | 65 + .../aux_/preprocessor/partial_spec_params.hpp | 32 + boost/mpl/aux_/preprocessor/range.hpp | 30 + boost/mpl/aux_/preprocessor/repeat.hpp | 51 + boost/mpl/aux_/preprocessor/sub.hpp | 65 + boost/mpl/aux_/preprocessor/tuple.hpp | 29 + boost/mpl/aux_/push_back_impl.hpp | 70 + boost/mpl/aux_/push_front_impl.hpp | 71 + boost/mpl/aux_/reverse_fold_impl.hpp | 44 + boost/mpl/aux_/reverse_fold_impl_body.hpp | 412 + boost/mpl/aux_/sequence_wrapper.hpp | 292 + boost/mpl/aux_/size_impl.hpp | 52 + boost/mpl/aux_/static_cast.hpp | 27 + boost/mpl/aux_/template_arity.hpp | 189 + boost/mpl/aux_/template_arity_fwd.hpp | 23 + boost/mpl/aux_/traits_lambda_spec.hpp | 63 + boost/mpl/aux_/type_wrapper.hpp | 47 + boost/mpl/aux_/unwrap.hpp | 51 + boost/mpl/aux_/value_wknd.hpp | 89 + boost/mpl/aux_/yes_no.hpp | 58 + boost/mpl/back_fwd.hpp | 24 + boost/mpl/back_inserter.hpp | 34 + boost/mpl/begin_end.hpp | 57 + boost/mpl/begin_end_fwd.hpp | 27 + boost/mpl/bind.hpp | 551 + boost/mpl/bind_fwd.hpp | 99 + boost/mpl/bool.hpp | 39 + boost/mpl/bool_fwd.hpp | 33 + boost/mpl/clear.hpp | 39 + boost/mpl/clear_fwd.hpp | 24 + boost/mpl/comparison.hpp | 24 + boost/mpl/contains.hpp | 41 + boost/mpl/contains_fwd.hpp | 25 + boost/mpl/deref.hpp | 41 + boost/mpl/distance.hpp | 78 + boost/mpl/distance_fwd.hpp | 28 + boost/mpl/empty_fwd.hpp | 24 + boost/mpl/equal_to.hpp | 21 + boost/mpl/eval_if.hpp | 71 + boost/mpl/find.hpp | 38 + boost/mpl/find_if.hpp | 50 + boost/mpl/fold.hpp | 48 + boost/mpl/for_each.hpp | 123 + boost/mpl/front_fwd.hpp | 24 + boost/mpl/front_inserter.hpp | 33 + boost/mpl/greater.hpp | 21 + boost/mpl/greater_equal.hpp | 21 + boost/mpl/has_xxx.hpp | 647 + boost/mpl/identity.hpp | 45 + boost/mpl/if.hpp | 135 + boost/mpl/inserter.hpp | 32 + boost/mpl/int.hpp | 22 + boost/mpl/int_fwd.hpp | 27 + boost/mpl/integral_c.hpp | 51 + boost/mpl/integral_c_fwd.hpp | 32 + boost/mpl/integral_c_tag.hpp | 26 + boost/mpl/is_placeholder.hpp | 67 + boost/mpl/is_sequence.hpp | 112 + boost/mpl/iter_fold.hpp | 49 + boost/mpl/iter_fold_if.hpp | 117 + boost/mpl/iterator_range.hpp | 42 + boost/mpl/iterator_tags.hpp | 27 + boost/mpl/lambda.hpp | 29 + boost/mpl/lambda_fwd.hpp | 57 + boost/mpl/less.hpp | 21 + boost/mpl/less_equal.hpp | 21 + boost/mpl/limits/arity.hpp | 21 + boost/mpl/limits/list.hpp | 21 + boost/mpl/limits/unrolling.hpp | 21 + boost/mpl/limits/vector.hpp | 21 + boost/mpl/list.hpp | 57 + boost/mpl/list/aux_/O1_size.hpp | 33 + boost/mpl/list/aux_/begin_end.hpp | 44 + boost/mpl/list/aux_/clear.hpp | 34 + boost/mpl/list/aux_/empty.hpp | 34 + boost/mpl/list/aux_/front.hpp | 33 + boost/mpl/list/aux_/include_preprocessed.hpp | 35 + boost/mpl/list/aux_/item.hpp | 55 + boost/mpl/list/aux_/iterator.hpp | 76 + boost/mpl/list/aux_/numbered.hpp | 68 + boost/mpl/list/aux_/numbered_c.hpp | 71 + boost/mpl/list/aux_/pop_front.hpp | 34 + .../list/aux_/preprocessed/plain/list10.hpp | 149 + .../list/aux_/preprocessed/plain/list10_c.hpp | 164 + .../list/aux_/preprocessed/plain/list20.hpp | 169 + .../list/aux_/preprocessed/plain/list20_c.hpp | 173 + .../list/aux_/preprocessed/plain/list30.hpp | 189 + .../list/aux_/preprocessed/plain/list30_c.hpp | 183 + .../list/aux_/preprocessed/plain/list40.hpp | 209 + .../list/aux_/preprocessed/plain/list40_c.hpp | 193 + .../list/aux_/preprocessed/plain/list50.hpp | 229 + .../list/aux_/preprocessed/plain/list50_c.hpp | 203 + boost/mpl/list/aux_/push_back.hpp | 36 + boost/mpl/list/aux_/push_front.hpp | 39 + boost/mpl/list/aux_/size.hpp | 33 + boost/mpl/list/aux_/tag.hpp | 24 + boost/mpl/list/list0.hpp | 42 + boost/mpl/list/list0_c.hpp | 31 + boost/mpl/list/list10.hpp | 43 + boost/mpl/list/list10_c.hpp | 43 + boost/mpl/list/list20.hpp | 43 + boost/mpl/list/list20_c.hpp | 43 + boost/mpl/list/list30.hpp | 43 + boost/mpl/list/list30_c.hpp | 43 + boost/mpl/list/list40.hpp | 43 + boost/mpl/list/list40_c.hpp | 43 + boost/mpl/list/list50.hpp | 43 + boost/mpl/list/list50_c.hpp | 43 + boost/mpl/logical.hpp | 21 + boost/mpl/long.hpp | 22 + boost/mpl/long_fwd.hpp | 27 + boost/mpl/minus.hpp | 21 + boost/mpl/multiplies.hpp | 53 + boost/mpl/negate.hpp | 81 + boost/mpl/next.hpp | 19 + boost/mpl/next_prior.hpp | 49 + boost/mpl/not.hpp | 51 + boost/mpl/not_equal_to.hpp | 21 + boost/mpl/numeric_cast.hpp | 41 + boost/mpl/or.hpp | 61 + boost/mpl/pair.hpp | 70 + boost/mpl/placeholders.hpp | 100 + boost/mpl/plus.hpp | 21 + boost/mpl/pop_back_fwd.hpp | 24 + boost/mpl/pop_front_fwd.hpp | 24 + boost/mpl/prior.hpp | 19 + boost/mpl/protect.hpp | 55 + boost/mpl/push_back.hpp | 53 + boost/mpl/push_back_fwd.hpp | 24 + boost/mpl/push_front.hpp | 52 + boost/mpl/push_front_fwd.hpp | 24 + boost/mpl/quote.hpp | 151 + boost/mpl/remove_if.hpp | 83 + boost/mpl/reverse_fold.hpp | 50 + boost/mpl/same_as.hpp | 55 + boost/mpl/sequence_tag.hpp | 124 + boost/mpl/sequence_tag_fwd.hpp | 26 + boost/mpl/size.hpp | 42 + boost/mpl/size_fwd.hpp | 24 + boost/mpl/tag.hpp | 52 + boost/mpl/times.hpp | 21 + boost/mpl/vector.hpp | 57 + boost/mpl/vector/aux_/O1_size.hpp | 56 + boost/mpl/vector/aux_/at.hpp | 116 + boost/mpl/vector/aux_/back.hpp | 59 + boost/mpl/vector/aux_/begin_end.hpp | 49 + boost/mpl/vector/aux_/clear.hpp | 55 + boost/mpl/vector/aux_/empty.hpp | 68 + boost/mpl/vector/aux_/front.hpp | 56 + .../mpl/vector/aux_/include_preprocessed.hpp | 55 + boost/mpl/vector/aux_/item.hpp | 103 + boost/mpl/vector/aux_/iterator.hpp | 130 + boost/mpl/vector/aux_/numbered.hpp | 218 + boost/mpl/vector/aux_/numbered_c.hpp | 77 + boost/mpl/vector/aux_/pop_back.hpp | 40 + boost/mpl/vector/aux_/pop_front.hpp | 40 + .../aux_/preprocessed/no_ctps/vector10.hpp | 1528 + .../aux_/preprocessed/no_ctps/vector10_c.hpp | 149 + .../aux_/preprocessed/no_ctps/vector20.hpp | 1804 ++ .../aux_/preprocessed/no_ctps/vector20_c.hpp | 195 + .../aux_/preprocessed/no_ctps/vector30.hpp | 2124 ++ .../aux_/preprocessed/no_ctps/vector30_c.hpp | 238 + .../aux_/preprocessed/no_ctps/vector40.hpp | 2444 ++ .../aux_/preprocessed/no_ctps/vector40_c.hpp | 281 + .../aux_/preprocessed/no_ctps/vector50.hpp | 2764 ++ .../aux_/preprocessed/no_ctps/vector50_c.hpp | 325 + .../aux_/preprocessed/plain/vector10.hpp | 829 + .../aux_/preprocessed/plain/vector10_c.hpp | 149 + .../aux_/preprocessed/plain/vector20.hpp | 1144 + .../aux_/preprocessed/plain/vector20_c.hpp | 195 + .../aux_/preprocessed/plain/vector30.hpp | 1464 + .../aux_/preprocessed/plain/vector30_c.hpp | 238 + .../aux_/preprocessed/plain/vector40.hpp | 1784 ++ .../aux_/preprocessed/plain/vector40_c.hpp | 281 + .../aux_/preprocessed/plain/vector50.hpp | 2104 ++ .../aux_/preprocessed/plain/vector50_c.hpp | 325 + .../preprocessed/typeof_based/vector10.hpp | 139 + .../preprocessed/typeof_based/vector10_c.hpp | 154 + .../preprocessed/typeof_based/vector20.hpp | 159 + .../preprocessed/typeof_based/vector20_c.hpp | 163 + .../preprocessed/typeof_based/vector30.hpp | 179 + .../preprocessed/typeof_based/vector30_c.hpp | 173 + .../preprocessed/typeof_based/vector40.hpp | 199 + .../preprocessed/typeof_based/vector40_c.hpp | 183 + .../preprocessed/typeof_based/vector50.hpp | 219 + .../preprocessed/typeof_based/vector50_c.hpp | 193 + boost/mpl/vector/aux_/push_back.hpp | 40 + boost/mpl/vector/aux_/push_front.hpp | 40 + boost/mpl/vector/aux_/size.hpp | 49 + boost/mpl/vector/aux_/tag.hpp | 32 + boost/mpl/vector/aux_/vector0.hpp | 52 + boost/mpl/vector/vector0.hpp | 34 + boost/mpl/vector/vector0_c.hpp | 31 + boost/mpl/vector/vector10.hpp | 45 + boost/mpl/vector/vector10_c.hpp | 46 + boost/mpl/vector/vector20.hpp | 45 + boost/mpl/vector/vector20_c.hpp | 46 + boost/mpl/vector/vector30.hpp | 45 + boost/mpl/vector/vector30_c.hpp | 47 + boost/mpl/vector/vector40.hpp | 45 + boost/mpl/vector/vector40_c.hpp | 46 + boost/mpl/vector/vector50.hpp | 45 + boost/mpl/vector/vector50_c.hpp | 46 + boost/mpl/void.hpp | 76 + boost/mpl/void_fwd.hpp | 26 + boost/next_prior.hpp | 195 + boost/non_type.hpp | 27 + boost/noncopyable.hpp | 17 + boost/none.hpp | 59 + boost/none_t.hpp | 39 + boost/numeric/conversion/bounds.hpp | 24 + boost/numeric/conversion/cast.hpp | 61 + .../numeric/conversion/conversion_traits.hpp | 32 + boost/numeric/conversion/converter.hpp | 68 + .../numeric/conversion/converter_policies.hpp | 194 + boost/numeric/conversion/detail/bounds.hpp | 58 + .../conversion/detail/conversion_traits.hpp | 97 + boost/numeric/conversion/detail/converter.hpp | 593 + .../conversion/detail/int_float_mixture.hpp | 72 + .../conversion/detail/is_subranged.hpp | 234 + boost/numeric/conversion/detail/meta.hpp | 120 + .../conversion/detail/numeric_cast_traits.hpp | 138 + .../conversion/detail/old_numeric_cast.hpp | 308 + .../numeric_cast_traits_common.hpp | 1741 ++ .../numeric_cast_traits_long_long.hpp | 347 + .../conversion/detail/sign_mixture.hpp | 72 + .../conversion/detail/udt_builtin_mixture.hpp | 69 + .../conversion/int_float_mixture_enum.hpp | 29 + .../conversion/numeric_cast_traits.hpp | 31 + .../numeric/conversion/sign_mixture_enum.hpp | 29 + .../conversion/udt_builtin_mixture_enum.hpp | 26 + boost/operators.hpp | 911 + boost/optional.hpp | 18 + boost/optional/bad_optional_access.hpp | 32 + .../detail/old_optional_implementation.hpp | 1059 + .../detail/optional_aligned_storage.hpp | 71 + boost/optional/detail/optional_config.hpp | 135 + .../detail/optional_factory_support.hpp | 36 + .../detail/optional_reference_spec.hpp | 253 + boost/optional/detail/optional_relops.hpp | 196 + boost/optional/detail/optional_swap.hpp | 117 + .../optional_trivially_copyable_base.hpp | 499 + boost/optional/optional.hpp | 1490 + boost/optional/optional_fwd.hpp | 41 + boost/pointee.hpp | 76 + boost/predef.h | 24 + boost/predef/architecture.h | 32 + boost/predef/architecture/alpha.h | 59 + boost/predef/architecture/arm.h | 75 + boost/predef/architecture/blackfin.h | 46 + boost/predef/architecture/convex.h | 65 + boost/predef/architecture/ia64.h | 49 + boost/predef/architecture/m68k.h | 82 + boost/predef/architecture/mips.h | 73 + boost/predef/architecture/parisc.h | 64 + boost/predef/architecture/ppc.h | 72 + boost/predef/architecture/pyramid.h | 42 + boost/predef/architecture/rs6k.h | 56 + boost/predef/architecture/sparc.h | 54 + boost/predef/architecture/superh.h | 67 + boost/predef/architecture/sys370.h | 43 + boost/predef/architecture/sys390.h | 43 + boost/predef/architecture/x86.h | 38 + boost/predef/architecture/x86/32.h | 87 + boost/predef/architecture/x86/64.h | 50 + boost/predef/architecture/z.h | 42 + boost/predef/compiler.h | 43 + boost/predef/compiler/borland.h | 63 + boost/predef/compiler/clang.h | 56 + boost/predef/compiler/comeau.h | 61 + boost/predef/compiler/compaq.h | 66 + boost/predef/compiler/diab.h | 56 + boost/predef/compiler/digitalmars.h | 56 + boost/predef/compiler/dignus.h | 56 + boost/predef/compiler/edg.h | 56 + boost/predef/compiler/ekopath.h | 57 + boost/predef/compiler/gcc.h | 68 + boost/predef/compiler/gcc_xml.h | 53 + boost/predef/compiler/greenhills.h | 66 + boost/predef/compiler/hp_acc.h | 61 + boost/predef/compiler/iar.h | 56 + boost/predef/compiler/ibm.h | 72 + boost/predef/compiler/intel.h | 79 + boost/predef/compiler/kai.h | 56 + boost/predef/compiler/llvm.h | 57 + boost/predef/compiler/metaware.h | 53 + boost/predef/compiler/metrowerks.h | 77 + boost/predef/compiler/microtec.h | 53 + boost/predef/compiler/mpw.h | 63 + boost/predef/compiler/palm.h | 56 + boost/predef/compiler/pgi.h | 60 + boost/predef/compiler/sgi_mipspro.h | 66 + boost/predef/compiler/sunpro.h | 76 + boost/predef/compiler/tendra.h | 53 + boost/predef/compiler/visualc.h | 105 + boost/predef/compiler/watcom.h | 56 + boost/predef/detail/_cassert.h | 17 + boost/predef/detail/_exception.h | 15 + boost/predef/detail/comp_detected.h | 10 + boost/predef/detail/endian_compat.h | 26 + boost/predef/detail/os_detected.h | 10 + boost/predef/detail/platform_detected.h | 10 + boost/predef/detail/test.h | 17 + boost/predef/detail/test_def.h | 71 + boost/predef/hardware.h | 16 + boost/predef/hardware/simd.h | 119 + boost/predef/hardware/simd/arm.h | 59 + boost/predef/hardware/simd/arm/versions.h | 32 + boost/predef/hardware/simd/ppc.h | 69 + boost/predef/hardware/simd/ppc/versions.h | 51 + boost/predef/hardware/simd/x86.h | 123 + boost/predef/hardware/simd/x86/versions.h | 129 + boost/predef/hardware/simd/x86_amd.h | 87 + boost/predef/hardware/simd/x86_amd/versions.h | 51 + boost/predef/language.h | 17 + boost/predef/language/objc.h | 42 + boost/predef/language/stdc.h | 53 + boost/predef/language/stdcpp.h | 121 + boost/predef/library.h | 16 + boost/predef/library/c.h | 21 + boost/predef/library/c/_prefix.h | 13 + boost/predef/library/c/cloudabi.h | 53 + boost/predef/library/c/gnu.h | 61 + boost/predef/library/c/uc.h | 47 + boost/predef/library/c/vms.h | 47 + boost/predef/library/c/zos.h | 56 + boost/predef/library/std.h | 25 + boost/predef/library/std/_prefix.h | 23 + boost/predef/library/std/cxx.h | 46 + boost/predef/library/std/dinkumware.h | 52 + boost/predef/library/std/libcomo.h | 47 + boost/predef/library/std/modena.h | 45 + boost/predef/library/std/msl.h | 53 + boost/predef/library/std/roguewave.h | 56 + boost/predef/library/std/sgi.h | 51 + boost/predef/library/std/stdcpp3.h | 53 + boost/predef/library/std/stlport.h | 59 + boost/predef/library/std/vacpp.h | 44 + boost/predef/make.h | 93 + boost/predef/os.h | 33 + boost/predef/os/aix.h | 66 + boost/predef/os/amigaos.h | 46 + boost/predef/os/android.h | 45 + boost/predef/os/beos.h | 45 + boost/predef/os/bsd.h | 103 + boost/predef/os/bsd/bsdi.h | 48 + boost/predef/os/bsd/dragonfly.h | 50 + boost/predef/os/bsd/free.h | 67 + boost/predef/os/bsd/net.h | 84 + boost/predef/os/bsd/open.h | 251 + boost/predef/os/cygwin.h | 45 + boost/predef/os/haiku.h | 46 + boost/predef/os/hpux.h | 47 + boost/predef/os/ios.h | 51 + boost/predef/os/irix.h | 46 + boost/predef/os/linux.h | 46 + boost/predef/os/macos.h | 65 + boost/predef/os/os400.h | 45 + boost/predef/os/qnxnto.h | 59 + boost/predef/os/solaris.h | 46 + boost/predef/os/unix.h | 76 + boost/predef/os/vms.h | 52 + boost/predef/os/windows.h | 51 + boost/predef/other.h | 16 + boost/predef/other/endian.h | 204 + boost/predef/other/workaround.h | 87 + boost/predef/platform.h | 28 + boost/predef/platform/cloudabi.h | 43 + boost/predef/platform/ios.h | 58 + boost/predef/platform/mingw.h | 69 + boost/predef/platform/mingw32.h | 63 + boost/predef/platform/mingw64.h | 63 + boost/predef/platform/windows_desktop.h | 51 + boost/predef/platform/windows_phone.h | 48 + boost/predef/platform/windows_runtime.h | 53 + boost/predef/platform/windows_server.h | 47 + boost/predef/platform/windows_store.h | 50 + boost/predef/platform/windows_system.h | 47 + boost/predef/platform/windows_uwp.h | 60 + boost/predef/version.h | 15 + boost/predef/version_number.h | 72 + boost/preprocessor/arithmetic/add.hpp | 51 + boost/preprocessor/arithmetic/dec.hpp | 289 + .../arithmetic/detail/div_base.hpp | 61 + boost/preprocessor/arithmetic/inc.hpp | 288 + boost/preprocessor/arithmetic/mod.hpp | 39 + boost/preprocessor/arithmetic/sub.hpp | 50 + boost/preprocessor/array/data.hpp | 28 + boost/preprocessor/array/elem.hpp | 29 + boost/preprocessor/array/size.hpp | 28 + boost/preprocessor/cat.hpp | 35 + boost/preprocessor/comma_if.hpp | 17 + boost/preprocessor/comparison/equal.hpp | 34 + boost/preprocessor/comparison/less_equal.hpp | 39 + boost/preprocessor/comparison/not_equal.hpp | 814 + boost/preprocessor/config/config.hpp | 106 + boost/preprocessor/control/deduce_d.hpp | 22 + .../preprocessor/control/detail/dmc/while.hpp | 536 + .../preprocessor/control/detail/edg/while.hpp | 534 + .../control/detail/msvc/while.hpp | 277 + boost/preprocessor/control/detail/while.hpp | 536 + boost/preprocessor/control/expr_if.hpp | 30 + boost/preprocessor/control/expr_iif.hpp | 31 + boost/preprocessor/control/if.hpp | 30 + boost/preprocessor/control/iif.hpp | 34 + boost/preprocessor/control/while.hpp | 312 + boost/preprocessor/debug/error.hpp | 33 + boost/preprocessor/dec.hpp | 17 + boost/preprocessor/detail/auto_rec.hpp | 293 + boost/preprocessor/detail/check.hpp | 48 + boost/preprocessor/detail/dmc/auto_rec.hpp | 286 + boost/preprocessor/detail/is_binary.hpp | 30 + boost/preprocessor/detail/split.hpp | 35 + boost/preprocessor/empty.hpp | 17 + boost/preprocessor/enum.hpp | 17 + boost/preprocessor/enum_params.hpp | 17 + .../enum_params_with_a_default.hpp | 17 + boost/preprocessor/enum_shifted_params.hpp | 17 + boost/preprocessor/expr_if.hpp | 17 + .../facilities/detail/is_empty.hpp | 55 + boost/preprocessor/facilities/empty.hpp | 23 + boost/preprocessor/facilities/expand.hpp | 28 + boost/preprocessor/facilities/identity.hpp | 27 + boost/preprocessor/facilities/intercept.hpp | 277 + boost/preprocessor/facilities/is_1.hpp | 23 + boost/preprocessor/facilities/is_empty.hpp | 56 + .../facilities/is_empty_variadic.hpp | 57 + boost/preprocessor/facilities/overload.hpp | 25 + boost/preprocessor/identity.hpp | 17 + boost/preprocessor/inc.hpp | 17 + boost/preprocessor/iterate.hpp | 17 + .../iteration/detail/bounds/lower1.hpp | 99 + .../iteration/detail/bounds/lower2.hpp | 99 + .../iteration/detail/bounds/lower3.hpp | 99 + .../iteration/detail/bounds/lower4.hpp | 99 + .../iteration/detail/bounds/lower5.hpp | 99 + .../iteration/detail/bounds/upper1.hpp | 99 + .../iteration/detail/bounds/upper2.hpp | 99 + .../iteration/detail/bounds/upper3.hpp | 99 + .../iteration/detail/bounds/upper4.hpp | 99 + .../iteration/detail/bounds/upper5.hpp | 99 + .../preprocessor/iteration/detail/finish.hpp | 99 + .../iteration/detail/iter/forward1.hpp | 1342 + .../iteration/detail/iter/forward2.hpp | 1338 + .../iteration/detail/iter/forward3.hpp | 1338 + .../iteration/detail/iter/forward4.hpp | 1338 + .../iteration/detail/iter/forward5.hpp | 1338 + .../iteration/detail/iter/reverse1.hpp | 1296 + .../iteration/detail/iter/reverse2.hpp | 1296 + .../iteration/detail/iter/reverse3.hpp | 1296 + .../iteration/detail/iter/reverse4.hpp | 1296 + .../iteration/detail/iter/reverse5.hpp | 1296 + boost/preprocessor/iteration/detail/local.hpp | 812 + .../preprocessor/iteration/detail/rlocal.hpp | 782 + boost/preprocessor/iteration/detail/self.hpp | 21 + boost/preprocessor/iteration/detail/start.hpp | 99 + boost/preprocessor/iteration/iterate.hpp | 82 + boost/preprocessor/iteration/local.hpp | 26 + boost/preprocessor/iteration/self.hpp | 19 + boost/preprocessor/list/adt.hpp | 73 + .../list/detail/dmc/fold_left.hpp | 279 + .../list/detail/edg/fold_left.hpp | 536 + .../list/detail/edg/fold_right.hpp | 794 + boost/preprocessor/list/detail/fold_left.hpp | 279 + boost/preprocessor/list/detail/fold_right.hpp | 277 + boost/preprocessor/list/fold_left.hpp | 303 + boost/preprocessor/list/fold_right.hpp | 40 + boost/preprocessor/list/for_each_i.hpp | 65 + boost/preprocessor/list/reverse.hpp | 40 + boost/preprocessor/logical/and.hpp | 30 + boost/preprocessor/logical/bitand.hpp | 38 + boost/preprocessor/logical/bool.hpp | 288 + boost/preprocessor/logical/compl.hpp | 36 + boost/preprocessor/logical/not.hpp | 30 + boost/preprocessor/punctuation/comma.hpp | 21 + boost/preprocessor/punctuation/comma_if.hpp | 31 + .../punctuation/detail/is_begin_parens.hpp | 48 + .../punctuation/is_begin_parens.hpp | 51 + boost/preprocessor/repeat.hpp | 17 + .../repetition/detail/dmc/for.hpp | 536 + .../repetition/detail/edg/for.hpp | 534 + boost/preprocessor/repetition/detail/for.hpp | 536 + .../repetition/detail/msvc/for.hpp | 277 + boost/preprocessor/repetition/enum.hpp | 66 + .../repetition/enum_binary_params.hpp | 54 + boost/preprocessor/repetition/enum_params.hpp | 41 + .../repetition/enum_params_with_a_default.hpp | 25 + .../repetition/enum_shifted_params.hpp | 44 + .../repetition/enum_trailing_params.hpp | 38 + boost/preprocessor/repetition/for.hpp | 324 + boost/preprocessor/repetition/repeat.hpp | 825 + .../repetition/repeat_from_to.hpp | 87 + boost/preprocessor/seq/cat.hpp | 49 + boost/preprocessor/seq/detail/is_empty.hpp | 49 + boost/preprocessor/seq/detail/split.hpp | 284 + boost/preprocessor/seq/elem.hpp | 304 + boost/preprocessor/seq/enum.hpp | 288 + boost/preprocessor/seq/first_n.hpp | 30 + boost/preprocessor/seq/fold_left.hpp | 1070 + boost/preprocessor/seq/for_each.hpp | 107 + boost/preprocessor/seq/for_each_i.hpp | 109 + boost/preprocessor/seq/rest_n.hpp | 46 + boost/preprocessor/seq/seq.hpp | 44 + boost/preprocessor/seq/size.hpp | 548 + boost/preprocessor/seq/subseq.hpp | 28 + boost/preprocessor/seq/to_tuple.hpp | 27 + boost/preprocessor/seq/transform.hpp | 48 + boost/preprocessor/slot/detail/counter.hpp | 269 + boost/preprocessor/slot/detail/def.hpp | 49 + boost/preprocessor/slot/detail/shared.hpp | 247 + boost/preprocessor/slot/detail/slot1.hpp | 267 + boost/preprocessor/slot/detail/slot2.hpp | 267 + boost/preprocessor/slot/detail/slot3.hpp | 267 + boost/preprocessor/slot/detail/slot4.hpp | 267 + boost/preprocessor/slot/detail/slot5.hpp | 267 + boost/preprocessor/slot/slot.hpp | 32 + boost/preprocessor/stringize.hpp | 33 + .../tuple/detail/is_single_return.hpp | 28 + boost/preprocessor/tuple/eat.hpp | 115 + boost/preprocessor/tuple/elem.hpp | 201 + boost/preprocessor/tuple/rem.hpp | 149 + boost/preprocessor/tuple/size.hpp | 28 + boost/preprocessor/tuple/to_list.hpp | 118 + boost/preprocessor/variadic/elem.hpp | 94 + boost/preprocessor/variadic/size.hpp | 30 + boost/program_options.hpp | 25 + boost/program_options/cmdline.hpp | 90 + boost/program_options/config.hpp | 52 + boost/program_options/detail/cmdline.hpp | 159 + boost/program_options/detail/config_file.hpp | 194 + boost/program_options/detail/convert.hpp | 107 + boost/program_options/detail/parsers.hpp | 135 + .../detail/utf8_codecvt_facet.hpp | 25 + .../program_options/detail/value_semantic.hpp | 222 + .../program_options/environment_iterator.hpp | 52 + boost/program_options/eof_iterator.hpp | 101 + boost/program_options/errors.hpp | 421 + boost/program_options/option.hpp | 71 + boost/program_options/options_description.hpp | 283 + boost/program_options/parsers.hpp | 293 + boost/program_options/positional_options.hpp | 74 + boost/program_options/value_semantic.hpp | 424 + boost/program_options/variables_map.hpp | 220 + boost/program_options/version.hpp | 22 + boost/progress.hpp | 142 + boost/range.hpp | 23 + boost/range/adaptor/adjacent_filtered.hpp | 237 + boost/range/adaptor/argument_fwd.hpp | 80 + boost/range/adaptor/copied.hpp | 68 + boost/range/adaptor/filtered.hpp | 121 + boost/range/adaptor/formatted.hpp | 229 + boost/range/adaptor/indexed.hpp | 370 + boost/range/adaptor/indirected.hpp | 100 + boost/range/adaptor/map.hpp | 204 + boost/range/adaptor/replaced.hpp | 169 + boost/range/adaptor/replaced_if.hpp | 177 + boost/range/adaptor/reversed.hpp | 103 + boost/range/adaptor/sliced.hpp | 97 + boost/range/adaptor/strided.hpp | 697 + boost/range/adaptor/tokenized.hpp | 137 + boost/range/adaptor/transformed.hpp | 137 + boost/range/adaptor/uniqued.hpp | 97 + boost/range/adaptors.hpp | 31 + boost/range/algorithm.hpp | 104 + boost/range/algorithm/adjacent_find.hpp | 125 + boost/range/algorithm/binary_search.hpp | 49 + boost/range/algorithm/copy.hpp | 41 + boost/range/algorithm/copy_backward.hpp | 43 + boost/range/algorithm/count.hpp | 50 + boost/range/algorithm/count_if.hpp | 51 + boost/range/algorithm/equal.hpp | 200 + boost/range/algorithm/equal_range.hpp | 80 + boost/range/algorithm/fill.hpp | 49 + boost/range/algorithm/fill_n.hpp | 53 + boost/range/algorithm/find.hpp | 80 + boost/range/algorithm/find_end.hpp | 152 + boost/range/algorithm/find_first_of.hpp | 155 + boost/range/algorithm/find_if.hpp | 81 + boost/range/algorithm/for_each.hpp | 110 + boost/range/algorithm/generate.hpp | 49 + boost/range/algorithm/heap_algorithm.hpp | 194 + boost/range/algorithm/inplace_merge.hpp | 74 + .../algorithm/lexicographical_compare.hpp | 58 + boost/range/algorithm/lower_bound.hpp | 124 + boost/range/algorithm/max_element.hpp | 115 + boost/range/algorithm/merge.hpp | 61 + boost/range/algorithm/min_element.hpp | 115 + boost/range/algorithm/mismatch.hpp | 195 + boost/range/algorithm/nth_element.hpp | 74 + boost/range/algorithm/partial_sort.hpp | 76 + boost/range/algorithm/partial_sort_copy.hpp | 82 + boost/range/algorithm/partition.hpp | 74 + boost/range/algorithm/permutation.hpp | 108 + boost/range/algorithm/random_shuffle.hpp | 68 + boost/range/algorithm/remove.hpp | 74 + boost/range/algorithm/remove_copy.hpp | 44 + boost/range/algorithm/remove_copy_if.hpp | 38 + boost/range/algorithm/remove_if.hpp | 75 + boost/range/algorithm/replace.hpp | 53 + boost/range/algorithm/replace_copy.hpp | 42 + boost/range/algorithm/replace_copy_if.hpp | 46 + boost/range/algorithm/replace_if.hpp | 54 + boost/range/algorithm/reverse.hpp | 50 + boost/range/algorithm/reverse_copy.hpp | 40 + boost/range/algorithm/rotate.hpp | 51 + boost/range/algorithm/rotate_copy.hpp | 44 + boost/range/algorithm/search.hpp | 134 + boost/range/algorithm/search_n.hpp | 360 + boost/range/algorithm/set_algorithm.hpp | 198 + boost/range/algorithm/sort.hpp | 68 + boost/range/algorithm/stable_partition.hpp | 73 + boost/range/algorithm/stable_sort.hpp | 68 + boost/range/algorithm/transform.hpp | 96 + boost/range/algorithm/unique.hpp | 107 + boost/range/algorithm/unique_copy.hpp | 51 + boost/range/algorithm/upper_bound.hpp | 127 + boost/range/as_literal.hpp | 127 + boost/range/begin.hpp | 135 + boost/range/category.hpp | 29 + boost/range/concepts.hpp | 388 + boost/range/config.hpp | 56 + boost/range/const_iterator.hpp | 76 + boost/range/const_reverse_iterator.hpp | 35 + boost/range/detail/as_literal.hpp | 33 + boost/range/detail/begin.hpp | 83 + boost/range/detail/common.hpp | 118 + .../detail/default_constructible_unary_fn.hpp | 64 + boost/range/detail/detail_str.hpp | 376 + boost/range/detail/end.hpp | 86 + boost/range/detail/extract_optional_type.hpp | 48 + boost/range/detail/has_member_size.hpp | 66 + boost/range/detail/implementation_help.hpp | 114 + boost/range/detail/misc_concept.hpp | 33 + .../detail/msvc_has_iterator_workaround.hpp | 132 + boost/range/detail/range_return.hpp | 181 + boost/range/detail/remove_extent.hpp | 157 + boost/range/detail/safe_bool.hpp | 72 + boost/range/detail/sfinae.hpp | 77 + boost/range/detail/size_type.hpp | 55 + boost/range/detail/str_types.hpp | 38 + boost/range/detail/value_type.hpp | 72 + boost/range/difference_type.hpp | 47 + boost/range/distance.hpp | 34 + boost/range/empty.hpp | 34 + boost/range/end.hpp | 128 + boost/range/functions.hpp | 27 + boost/range/has_range_iterator.hpp | 83 + boost/range/iterator.hpp | 74 + boost/range/iterator_range.hpp | 16 + boost/range/iterator_range_core.hpp | 884 + boost/range/iterator_range_io.hpp | 93 + boost/range/metafunctions.hpp | 31 + boost/range/mutable_iterator.hpp | 79 + boost/range/pointer.hpp | 30 + boost/range/range_fwd.hpp | 63 + boost/range/rbegin.hpp | 65 + boost/range/reference.hpp | 29 + boost/range/rend.hpp | 65 + boost/range/result_iterator.hpp | 33 + boost/range/reverse_iterator.hpp | 42 + boost/range/reverse_result_iterator.hpp | 32 + boost/range/size.hpp | 76 + boost/range/size_type.hpp | 90 + boost/range/sub_range.hpp | 287 + boost/range/traversal.hpp | 31 + boost/range/value_type.hpp | 30 + boost/ratio/config.hpp | 92 + boost/ratio/detail/mpl/abs.hpp | 89 + boost/ratio/detail/mpl/gcd.hpp | 124 + boost/ratio/detail/mpl/lcm.hpp | 126 + boost/ratio/detail/mpl/sign.hpp | 89 + boost/ratio/detail/overflow_helpers.hpp | 367 + boost/ratio/detail/ratio_io.hpp | 1342 + boost/ratio/mpl/rational_c_tag.hpp | 25 + boost/ratio/ratio.hpp | 293 + boost/ratio/ratio_fwd.hpp | 109 + boost/ratio/ratio_io.hpp | 1076 + boost/rational.hpp | 1002 + boost/ref.hpp | 17 + boost/regex.hpp | 37 + boost/regex/config.hpp | 477 + boost/regex/config/borland.hpp | 72 + boost/regex/config/cwchar.hpp | 207 + boost/regex/icu.hpp | 1040 + boost/regex/pattern_except.hpp | 100 + boost/regex/pending/object_cache.hpp | 165 + boost/regex/pending/static_mutex.hpp | 182 + boost/regex/pending/unicode_iterator.hpp | 785 + boost/regex/regex_traits.hpp | 35 + boost/regex/user.hpp | 93 + boost/regex/v4/basic_regex.hpp | 781 + boost/regex/v4/basic_regex_creator.hpp | 1573 ++ boost/regex/v4/basic_regex_parser.hpp | 3140 +++ boost/regex/v4/c_regex_traits.hpp | 211 + boost/regex/v4/char_regex_traits.hpp | 81 + boost/regex/v4/cpp_regex_traits.hpp | 1154 + boost/regex/v4/cregex.hpp | 330 + boost/regex/v4/error_type.hpp | 59 + boost/regex/v4/fileiter.hpp | 455 + boost/regex/v4/instances.hpp | 225 + boost/regex/v4/iterator_category.hpp | 91 + boost/regex/v4/iterator_traits.hpp | 135 + boost/regex/v4/match_flags.hpp | 150 + boost/regex/v4/match_results.hpp | 707 + boost/regex/v4/mem_block_cache.hpp | 145 + boost/regex/v4/perl_matcher.hpp | 621 + boost/regex/v4/perl_matcher_common.hpp | 1016 + boost/regex/v4/perl_matcher_non_recursive.hpp | 1944 ++ boost/regex/v4/perl_matcher_recursive.hpp | 1131 + boost/regex/v4/primary_transform.hpp | 146 + boost/regex/v4/protected_call.hpp | 81 + boost/regex/v4/regbase.hpp | 180 + boost/regex/v4/regex.hpp | 202 + boost/regex/v4/regex_format.hpp | 1156 + boost/regex/v4/regex_fwd.hpp | 73 + boost/regex/v4/regex_grep.hpp | 155 + boost/regex/v4/regex_iterator.hpp | 201 + boost/regex/v4/regex_match.hpp | 382 + boost/regex/v4/regex_merge.hpp | 93 + boost/regex/v4/regex_raw_buffer.hpp | 210 + boost/regex/v4/regex_replace.hpp | 99 + boost/regex/v4/regex_search.hpp | 217 + boost/regex/v4/regex_split.hpp | 172 + boost/regex/v4/regex_token_iterator.hpp | 333 + boost/regex/v4/regex_traits.hpp | 189 + boost/regex/v4/regex_traits_defaults.hpp | 380 + boost/regex/v4/regex_workaround.hpp | 234 + boost/regex/v4/states.hpp | 321 + boost/regex/v4/sub_match.hpp | 516 + boost/regex/v4/syntax_type.hpp | 105 + boost/regex/v4/u32regex_iterator.hpp | 193 + boost/regex/v4/u32regex_token_iterator.hpp | 368 + boost/regex/v4/w32_regex_traits.hpp | 743 + boost/regex_fwd.hpp | 33 + boost/scoped_array.hpp | 15 + boost/scoped_ptr.hpp | 15 + boost/shared_array.hpp | 19 + boost/shared_ptr.hpp | 19 + boost/smart_ptr.hpp | 26 + boost/smart_ptr/allocate_shared_array.hpp | 703 + boost/smart_ptr/bad_weak_ptr.hpp | 70 + boost/smart_ptr/detail/lightweight_mutex.hpp | 42 + boost/smart_ptr/detail/local_counted_base.hpp | 148 + boost/smart_ptr/detail/local_sp_deleter.hpp | 91 + boost/smart_ptr/detail/lwm_nop.hpp | 37 + boost/smart_ptr/detail/lwm_pthreads.hpp | 87 + boost/smart_ptr/detail/lwm_win32_cs.hpp | 134 + boost/smart_ptr/detail/operator_bool.hpp | 64 + boost/smart_ptr/detail/quick_allocator.hpp | 199 + boost/smart_ptr/detail/shared_count.hpp | 667 + boost/smart_ptr/detail/sp_convertible.hpp | 92 + boost/smart_ptr/detail/sp_counted_base.hpp | 96 + .../detail/sp_counted_base_acc_ia64.hpp | 152 + .../smart_ptr/detail/sp_counted_base_aix.hpp | 144 + .../detail/sp_counted_base_clang.hpp | 150 + .../detail/sp_counted_base_cw_ppc.hpp | 172 + .../detail/sp_counted_base_gcc_ia64.hpp | 159 + .../detail/sp_counted_base_gcc_mips.hpp | 189 + .../detail/sp_counted_base_gcc_ppc.hpp | 183 + .../detail/sp_counted_base_gcc_sparc.hpp | 168 + .../detail/sp_counted_base_gcc_x86.hpp | 175 + boost/smart_ptr/detail/sp_counted_base_nt.hpp | 109 + boost/smart_ptr/detail/sp_counted_base_pt.hpp | 138 + .../detail/sp_counted_base_snc_ps3.hpp | 163 + .../smart_ptr/detail/sp_counted_base_spin.hpp | 133 + .../detail/sp_counted_base_std_atomic.hpp | 138 + .../smart_ptr/detail/sp_counted_base_sync.hpp | 157 + .../detail/sp_counted_base_vacpp_ppc.hpp | 152 + .../smart_ptr/detail/sp_counted_base_w32.hpp | 132 + boost/smart_ptr/detail/sp_counted_impl.hpp | 292 + .../detail/sp_disable_deprecated.hpp | 40 + boost/smart_ptr/detail/sp_forward.hpp | 52 + boost/smart_ptr/detail/sp_has_sync.hpp | 69 + boost/smart_ptr/detail/sp_interlocked.hpp | 163 + boost/smart_ptr/detail/sp_noexcept.hpp | 48 + boost/smart_ptr/detail/sp_nullptr_t.hpp | 45 + boost/smart_ptr/detail/spinlock.hpp | 68 + boost/smart_ptr/detail/spinlock_gcc_arm.hpp | 121 + boost/smart_ptr/detail/spinlock_nt.hpp | 89 + boost/smart_ptr/detail/spinlock_pool.hpp | 91 + boost/smart_ptr/detail/spinlock_pt.hpp | 79 + .../smart_ptr/detail/spinlock_std_atomic.hpp | 83 + boost/smart_ptr/detail/spinlock_sync.hpp | 87 + boost/smart_ptr/detail/spinlock_w32.hpp | 113 + boost/smart_ptr/detail/yield_k.hpp | 177 + boost/smart_ptr/enable_shared_from_this.hpp | 90 + boost/smart_ptr/intrusive_ptr.hpp | 361 + boost/smart_ptr/make_shared.hpp | 21 + boost/smart_ptr/make_shared_array.hpp | 66 + boost/smart_ptr/make_shared_object.hpp | 801 + boost/smart_ptr/scoped_array.hpp | 132 + boost/smart_ptr/scoped_ptr.hpp | 167 + boost/smart_ptr/shared_array.hpp | 293 + boost/smart_ptr/shared_ptr.hpp | 1184 + boost/smart_ptr/weak_ptr.hpp | 254 + boost/static_assert.hpp | 180 + boost/swap.hpp | 17 + boost/system/api_config.hpp | 42 + boost/system/config.hpp | 70 + boost/system/cygwin_error.hpp | 56 + boost/system/detail/error_code.ipp | 496 + .../detail/local_free_on_destruction.hpp | 42 + boost/system/error_code.hpp | 769 + boost/system/linux_error.hpp | 110 + boost/system/system_error.hpp | 84 + boost/system/windows_error.hpp | 128 + boost/test/debug.hpp | 138 + boost/test/debug_config.hpp | 24 + boost/test/detail/config.hpp | 127 + boost/test/detail/enable_warnings.hpp | 36 + boost/test/detail/fwd_decl.hpp | 46 + boost/test/detail/global_typedef.hpp | 111 + boost/test/detail/log_level.hpp | 40 + boost/test/detail/pp_variadic.hpp | 49 + boost/test/detail/suppress_warnings.hpp | 38 + boost/test/detail/throw_exception.hpp | 71 + boost/test/detail/workaround.hpp | 56 + boost/test/execution_monitor.hpp | 579 + boost/test/framework.hpp | 303 + boost/test/impl/compiler_log_formatter.ipp | 298 + boost/test/impl/cpp_main.ipp | 136 + boost/test/impl/debug.ipp | 1009 + boost/test/impl/decorator.ipp | 202 + boost/test/impl/execution_monitor.ipp | 1448 + boost/test/impl/framework.ipp | 1713 ++ boost/test/impl/junit_log_formatter.ipp | 840 + boost/test/impl/plain_report_formatter.ipp | 207 + boost/test/impl/progress_monitor.ipp | 185 + boost/test/impl/results_collector.ipp | 285 + boost/test/impl/results_reporter.ipp | 197 + .../impl/test_framework_init_observer.ipp | 109 + boost/test/impl/test_main.ipp | 65 + boost/test/impl/test_tools.ipp | 823 + boost/test/impl/test_tree.ipp | 504 + boost/test/impl/unit_test_log.ipp | 691 + boost/test/impl/unit_test_main.ipp | 293 + boost/test/impl/unit_test_monitor.ipp | 75 + boost/test/impl/unit_test_parameters.ipp | 772 + boost/test/impl/xml_log_formatter.ipp | 223 + boost/test/impl/xml_report_formatter.ipp | 111 + boost/test/included/prg_exec_monitor.hpp | 25 + boost/test/output/compiler_log_formatter.hpp | 70 + boost/test/output/junit_log_formatter.hpp | 167 + boost/test/output/plain_report_formatter.hpp | 59 + boost/test/output/xml_log_formatter.hpp | 72 + boost/test/output/xml_report_formatter.hpp | 52 + boost/test/prg_exec_monitor.hpp | 81 + boost/test/progress_monitor.hpp | 66 + boost/test/results_collector.hpp | 143 + boost/test/results_reporter.hpp | 122 + boost/test/test_framework_init_observer.hpp | 63 + boost/test/test_tools.hpp | 68 + boost/test/tools/assertion.hpp | 410 + boost/test/tools/assertion_result.hpp | 90 + boost/test/tools/collection_comparison_op.hpp | 449 + boost/test/tools/context.hpp | 65 + boost/test/tools/cstring_comparison_op.hpp | 88 + boost/test/tools/detail/bitwise_manip.hpp | 123 + boost/test/tools/detail/expression_holder.hpp | 70 + boost/test/tools/detail/fwd.hpp | 121 + boost/test/tools/detail/indirections.hpp | 94 + boost/test/tools/detail/it_pair.hpp | 74 + .../test/tools/detail/lexicographic_manip.hpp | 69 + boost/test/tools/detail/per_element_manip.hpp | 69 + boost/test/tools/detail/print_helper.hpp | 246 + boost/test/tools/detail/tolerance_manip.hpp | 130 + .../test/tools/floating_point_comparison.hpp | 315 + boost/test/tools/fpc_op.hpp | 210 + boost/test/tools/fpc_tolerance.hpp | 103 + boost/test/tools/interface.hpp | 369 + boost/test/tools/old/impl.hpp | 358 + boost/test/tools/old/interface.hpp | 282 + boost/test/tools/output_test_stream.hpp | 107 + boost/test/tree/auto_registration.hpp | 53 + boost/test/tree/decorator.hpp | 277 + boost/test/tree/fixture.hpp | 191 + boost/test/tree/global_fixture.hpp | 123 + boost/test/tree/observer.hpp | 116 + boost/test/tree/test_case_counter.hpp | 52 + boost/test/tree/test_case_template.hpp | 190 + boost/test/tree/test_unit.hpp | 275 + boost/test/tree/traverse.hpp | 58 + boost/test/tree/visitor.hpp | 52 + boost/test/unit_test_log.hpp | 280 + boost/test/unit_test_log_formatter.hpp | 322 + boost/test/unit_test_monitor.hpp | 60 + boost/test/unit_test_parameters.hpp | 158 + boost/test/unit_test_suite.hpp | 403 + boost/test/utils/algorithm.hpp | 326 + boost/test/utils/assign_op.hpp | 39 + .../utils/basic_cstring/basic_cstring.hpp | 749 + .../utils/basic_cstring/basic_cstring_fwd.hpp | 40 + .../utils/basic_cstring/bcs_char_traits.hpp | 150 + boost/test/utils/basic_cstring/compare.hpp | 151 + boost/test/utils/basic_cstring/io.hpp | 73 + boost/test/utils/class_properties.hpp | 195 + boost/test/utils/custom_manip.hpp | 61 + boost/test/utils/foreach.hpp | 316 + boost/test/utils/is_cstring.hpp | 116 + boost/test/utils/is_forward_iterable.hpp | 267 + .../utils/iterator/input_iterator_facade.hpp | 105 + boost/test/utils/iterator/token_iterator.hpp | 421 + boost/test/utils/lazy_ostream.hpp | 128 + boost/test/utils/named_params.hpp | 388 + boost/test/utils/rtti.hpp | 63 + boost/test/utils/runtime/argument.hpp | 131 + boost/test/utils/runtime/argument_factory.hpp | 242 + .../test/utils/runtime/cla/argv_traverser.hpp | 105 + boost/test/utils/runtime/cla/parser.hpp | 584 + boost/test/utils/runtime/env/fetch.hpp | 108 + boost/test/utils/runtime/errors.hpp | 195 + boost/test/utils/runtime/finalize.hpp | 56 + boost/test/utils/runtime/fwd.hpp | 45 + boost/test/utils/runtime/modifier.hpp | 106 + boost/test/utils/runtime/parameter.hpp | 526 + boost/test/utils/setcolor.hpp | 315 + boost/test/utils/string_cast.hpp | 69 + boost/test/utils/trivial_singleton.hpp | 79 + boost/test/utils/wrap_stringstream.hpp | 162 + boost/test/utils/xml_printer.hpp | 143 + boost/thread.hpp | 26 + boost/thread/barrier.hpp | 255 + boost/thread/condition_variable.hpp | 21 + boost/thread/csbl/functional.hpp | 49 + boost/thread/csbl/memory/allocator_arg.hpp | 41 + boost/thread/csbl/memory/allocator_traits.hpp | 35 + boost/thread/csbl/memory/config.hpp | 16 + boost/thread/csbl/memory/pointer_traits.hpp | 35 + boost/thread/csbl/memory/scoped_allocator.hpp | 35 + boost/thread/csbl/memory/shared_ptr.hpp | 42 + boost/thread/csbl/memory/unique_ptr.hpp | 28 + boost/thread/csbl/tuple.hpp | 49 + boost/thread/csbl/vector.hpp | 35 + boost/thread/cv_status.hpp | 26 + boost/thread/detail/atomic_redef_macros.hpp | 19 + boost/thread/detail/atomic_undef_macros.hpp | 39 + boost/thread/detail/config.hpp | 525 + boost/thread/detail/delete.hpp | 58 + boost/thread/detail/invoke.hpp | 1604 ++ boost/thread/detail/invoker.hpp | 762 + boost/thread/detail/is_convertible.hpp | 49 + boost/thread/detail/lockable_wrapper.hpp | 45 + boost/thread/detail/make_tuple_indices.hpp | 224 + boost/thread/detail/memory.hpp | 48 + boost/thread/detail/move.hpp | 372 + boost/thread/detail/nullary_function.hpp | 234 + boost/thread/detail/platform.hpp | 75 + boost/thread/detail/platform_time.hpp | 478 + boost/thread/detail/thread.hpp | 846 + boost/thread/detail/thread_group.hpp | 155 + boost/thread/detail/thread_heap_alloc.hpp | 23 + boost/thread/detail/thread_interruption.hpp | 39 + boost/thread/detail/tss_hooks.hpp | 65 + boost/thread/detail/variadic_footer.hpp | 10 + boost/thread/detail/variadic_header.hpp | 19 + boost/thread/exceptional_ptr.hpp | 44 + boost/thread/exceptions.hpp | 225 + boost/thread/executor.hpp | 15 + boost/thread/executors/executor.hpp | 148 + boost/thread/executors/executor_adaptor.hpp | 136 + .../thread/executors/generic_executor_ref.hpp | 213 + boost/thread/executors/work.hpp | 30 + boost/thread/future.hpp | 5888 ++++ boost/thread/futures/future_error.hpp | 98 + boost/thread/futures/future_error_code.hpp | 61 + boost/thread/futures/future_status.hpp | 30 + boost/thread/futures/is_future_type.hpp | 21 + boost/thread/futures/launch.hpp | 32 + boost/thread/futures/wait_for_all.hpp | 74 + boost/thread/futures/wait_for_any.hpp | 161 + boost/thread/is_locked_by_this_thread.hpp | 39 + boost/thread/lock_algorithms.hpp | 468 + boost/thread/lock_guard.hpp | 88 + boost/thread/lock_options.hpp | 31 + boost/thread/lock_types.hpp | 1230 + boost/thread/lockable_traits.hpp | 207 + boost/thread/locks.hpp | 17 + boost/thread/mutex.hpp | 53 + boost/thread/once.hpp | 54 + boost/thread/pthread/condition_variable.hpp | 502 + .../thread/pthread/condition_variable_fwd.hpp | 348 + boost/thread/pthread/mutex.hpp | 391 + boost/thread/pthread/once.hpp | 540 + boost/thread/pthread/once_atomic.hpp | 313 + boost/thread/pthread/pthread_helpers.hpp | 42 + .../pthread/pthread_mutex_scoped_lock.hpp | 70 + boost/thread/pthread/recursive_mutex.hpp | 436 + boost/thread/pthread/shared_mutex.hpp | 642 + boost/thread/pthread/thread_data.hpp | 400 + boost/thread/pthread/thread_heap_alloc.hpp | 272 + boost/thread/recursive_mutex.hpp | 64 + boost/thread/shared_lock_guard.hpp | 53 + boost/thread/shared_mutex.hpp | 57 + boost/thread/thread.hpp | 16 + boost/thread/thread_only.hpp | 29 + boost/thread/thread_time.hpp | 55 + boost/thread/tss.hpp | 113 + boost/thread/v2/shared_mutex.hpp | 1052 + boost/thread/win32/basic_recursive_mutex.hpp | 176 + boost/thread/win32/basic_timed_mutex.hpp | 297 + boost/thread/win32/condition_variable.hpp | 725 + boost/thread/win32/interlocked_read.hpp | 214 + boost/thread/win32/mutex.hpp | 72 + boost/thread/win32/once.hpp | 1087 + boost/thread/win32/recursive_mutex.hpp | 70 + boost/thread/win32/shared_mutex.hpp | 849 + boost/thread/win32/thread_data.hpp | 294 + boost/thread/win32/thread_heap_alloc.hpp | 469 + boost/thread/win32/thread_primitives.hpp | 426 + boost/thread/xtime.hpp | 93 + boost/throw_exception.hpp | 102 + boost/timer.hpp | 72 + boost/timer/config.hpp | 84 + boost/timer/timer.hpp | 131 + boost/token_functions.hpp | 652 + boost/token_iterator.hpp | 131 + boost/tokenizer.hpp | 98 + boost/tuple/detail/tuple_basic.hpp | 987 + boost/tuple/tuple.hpp | 67 + boost/type.hpp | 18 + boost/type_index.hpp | 265 + boost/type_index/ctti_type_index.hpp | 213 + .../detail/compile_time_type_info.hpp | 291 + .../type_index/detail/ctti_register_class.hpp | 40 + .../type_index/detail/stl_register_class.hpp | 40 + boost/type_index/stl_type_index.hpp | 276 + boost/type_index/type_index_facade.hpp | 297 + boost/type_traits/add_const.hpp | 52 + boost/type_traits/add_cv.hpp | 47 + boost/type_traits/add_lvalue_reference.hpp | 33 + boost/type_traits/add_pointer.hpp | 67 + boost/type_traits/add_reference.hpp | 66 + boost/type_traits/add_rvalue_reference.hpp | 70 + boost/type_traits/add_volatile.hpp | 46 + boost/type_traits/aligned_storage.hpp | 138 + boost/type_traits/alignment_of.hpp | 119 + boost/type_traits/common_type.hpp | 152 + boost/type_traits/composite_traits.hpp | 29 + boost/type_traits/conditional.hpp | 28 + boost/type_traits/conversion_traits.hpp | 17 + boost/type_traits/copy_cv.hpp | 40 + boost/type_traits/cv_traits.hpp | 24 + boost/type_traits/decay.hpp | 49 + boost/type_traits/declval.hpp | 44 + boost/type_traits/detail/bool_trait_undef.hpp | 28 + .../detail/common_arithmetic_type.hpp | 218 + boost/type_traits/detail/common_type_impl.hpp | 107 + .../detail/composite_member_pointer_type.hpp | 113 + .../detail/composite_pointer_type.hpp | 153 + boost/type_traits/detail/config.hpp | 83 + .../detail/has_binary_operator.hpp | 279 + .../detail/is_function_ptr_helper.hpp | 444 + .../detail/is_function_ptr_tester.hpp | 449 + boost/type_traits/detail/is_likely_lambda.hpp | 94 + .../detail/is_mem_fun_pointer_impl.hpp | 1328 + .../detail/is_mem_fun_pointer_tester.hpp | 1800 ++ boost/type_traits/detail/mp_defer.hpp | 56 + boost/type_traits/detail/yes_no_type.hpp | 26 + boost/type_traits/function_traits.hpp | 174 + boost/type_traits/has_left_shift.hpp | 49 + boost/type_traits/has_minus.hpp | 153 + boost/type_traits/has_minus_assign.hpp | 158 + boost/type_traits/has_nothrow_assign.hpp | 84 + boost/type_traits/has_nothrow_constructor.hpp | 73 + boost/type_traits/has_nothrow_copy.hpp | 82 + boost/type_traits/has_plus.hpp | 54 + boost/type_traits/has_plus_assign.hpp | 156 + boost/type_traits/has_right_shift.hpp | 49 + boost/type_traits/has_trivial_assign.hpp | 52 + boost/type_traits/has_trivial_constructor.hpp | 57 + boost/type_traits/has_trivial_copy.hpp | 63 + boost/type_traits/has_trivial_destructor.hpp | 48 + boost/type_traits/has_trivial_move_assign.hpp | 73 + .../has_trivial_move_constructor.hpp | 78 + boost/type_traits/integral_constant.hpp | 107 + boost/type_traits/intrinsics.hpp | 381 + boost/type_traits/is_abstract.hpp | 150 + boost/type_traits/is_arithmetic.hpp | 22 + boost/type_traits/is_array.hpp | 43 + boost/type_traits/is_assignable.hpp | 85 + boost/type_traits/is_base_and_derived.hpp | 244 + boost/type_traits/is_base_of.hpp | 39 + boost/type_traits/is_class.hpp | 114 + boost/type_traits/is_complete.hpp | 90 + boost/type_traits/is_const.hpp | 47 + boost/type_traits/is_constructible.hpp | 90 + boost/type_traits/is_convertible.hpp | 506 + boost/type_traits/is_copy_constructible.hpp | 187 + .../type_traits/is_default_constructible.hpp | 98 + boost/type_traits/is_destructible.hpp | 69 + boost/type_traits/is_enum.hpp | 166 + boost/type_traits/is_float.hpp | 20 + boost/type_traits/is_floating_point.hpp | 30 + boost/type_traits/is_function.hpp | 102 + boost/type_traits/is_fundamental.hpp | 26 + boost/type_traits/is_integral.hpp | 89 + boost/type_traits/is_lvalue_reference.hpp | 50 + .../is_member_function_pointer.hpp | 120 + boost/type_traits/is_member_pointer.hpp | 45 + .../is_nothrow_move_assignable.hpp | 92 + .../is_nothrow_move_constructible.hpp | 97 + boost/type_traits/is_pod.hpp | 59 + boost/type_traits/is_pointer.hpp | 47 + boost/type_traits/is_polymorphic.hpp | 122 + boost/type_traits/is_reference.hpp | 30 + boost/type_traits/is_rvalue_reference.hpp | 25 + boost/type_traits/is_same.hpp | 41 + boost/type_traits/is_scalar.hpp | 27 + boost/type_traits/is_signed.hpp | 163 + boost/type_traits/is_union.hpp | 31 + boost/type_traits/is_unsigned.hpp | 163 + boost/type_traits/is_void.hpp | 26 + boost/type_traits/is_volatile.hpp | 46 + boost/type_traits/make_signed.hpp | 137 + boost/type_traits/make_unsigned.hpp | 136 + boost/type_traits/make_void.hpp | 52 + boost/type_traits/remove_all_extents.hpp | 41 + boost/type_traits/remove_bounds.hpp | 28 + boost/type_traits/remove_const.hpp | 39 + boost/type_traits/remove_cv.hpp | 45 + boost/type_traits/remove_extent.hpp | 41 + boost/type_traits/remove_pointer.hpp | 84 + boost/type_traits/remove_reference.hpp | 59 + boost/type_traits/remove_volatile.hpp | 39 + boost/type_traits/type_identity.hpp | 31 + boost/type_traits/type_with_alignment.hpp | 260 + boost/utility.hpp | 24 + boost/utility/addressof.hpp | 17 + boost/utility/base_from_member.hpp | 172 + boost/utility/binary.hpp | 708 + boost/utility/compare_pointees.hpp | 76 + boost/utility/declval.hpp | 13 + boost/utility/detail/result_of_iterate.hpp | 218 + boost/utility/enable_if.hpp | 17 + boost/utility/identity_type.hpp | 46 + boost/utility/result_of.hpp | 234 + boost/utility/swap.hpp | 17 + boost/utility/value_init.hpp | 281 + boost/version.hpp | 32 + boost/visit_each.hpp | 27 + boost/weak_ptr.hpp | 18 + boost/winapi/access_rights.hpp | 81 + boost/winapi/basic_types.hpp | 255 + boost/winapi/character_code_conversion.hpp | 105 + boost/winapi/config.hpp | 218 + boost/winapi/dll.hpp | 238 + boost/winapi/error_codes.hpp | 2956 ++ boost/winapi/error_handling.hpp | 153 + boost/winapi/event.hpp | 190 + boost/winapi/get_current_process.hpp | 31 + boost/winapi/get_current_process_id.hpp | 30 + boost/winapi/get_current_thread.hpp | 31 + boost/winapi/get_current_thread_id.hpp | 31 + boost/winapi/get_last_error.hpp | 30 + boost/winapi/get_process_times.hpp | 60 + boost/winapi/get_thread_times.hpp | 55 + boost/winapi/handles.hpp | 69 + boost/winapi/heap_memory.hpp | 83 + boost/winapi/local_memory.hpp | 53 + boost/winapi/semaphore.hpp | 186 + boost/winapi/system.hpp | 87 + boost/winapi/thread.hpp | 42 + boost/winapi/thread_pool.hpp | 129 + boost/winapi/time.hpp | 140 + boost/winapi/timers.hpp | 45 + boost/winapi/wait.hpp | 113 + boostcpp.jam | 741 + bootstrap.bat | 91 + bootstrap.sh | 408 + build.cmd | 12 + doc/src/boostbook.css | 789 + doc/src/images/home.png | Bin 0 -> 358 bytes doc/src/images/important.png | Bin 0 -> 722 bytes doc/src/images/next.png | Bin 0 -> 336 bytes doc/src/images/prev.png | Bin 0 -> 334 bytes doc/src/images/up.png | Bin 0 -> 370 bytes doc/src/minimal.css | 23 + libs/atomic/build/Jamfile.v2 | 37 + libs/atomic/src/lockpool.cpp | 161 + libs/chrono/build/Jamfile.v2 | 118 + libs/chrono/src/chrono.cpp | 15 + libs/chrono/src/process_cpu_clocks.cpp | 18 + libs/chrono/src/thread_clock.cpp | 19 + libs/config/appveyor.bat | 12 + libs/config/checks/Jamfile.v2 | 205 + libs/config/checks/architecture/32.cpp | 9 + libs/config/checks/architecture/64.cpp | 9 + libs/config/checks/architecture/Jamroot.jam | 23 + libs/config/checks/architecture/arm.cpp | 15 + libs/config/checks/architecture/combined.cpp | 21 + libs/config/checks/architecture/mips1.cpp | 11 + libs/config/checks/architecture/power.cpp | 14 + libs/config/checks/architecture/sparc.cpp | 11 + libs/config/checks/architecture/x86.cpp | 16 + libs/config/checks/config.jam | 21 + libs/config/checks/test_case.cpp | 979 + libs/config/config.htm | 15 + libs/config/configure | 3894 +++ libs/config/doc/Jamfile.v2 | 66 + libs/config/doc/acknowledgements.qbk | 32 + libs/config/doc/build_time.qbk | 65 + libs/config/doc/config.qbk | 62 + libs/config/doc/configuring_boost.qbk | 440 + libs/config/doc/cstdint.qbk | 139 + libs/config/doc/guidelines.qbk | 219 + libs/config/doc/html/HTML.manifest | 5 + .../html/boost_config/acknowledgements.html | 62 + .../boost_config/boost_macro_reference.html | 6310 +++++ .../doc/html/boost_config/build_config.html | 144 + .../config/doc/html/boost_config/cstdint.html | 289 + .../guidelines_for_boost_authors.html | 377 + .../doc/html/boost_config/rationale.html | 124 + libs/config/doc/html/index.html | 1001 + libs/config/doc/html/standalone_HTML.manifest | 7 + libs/config/doc/macro_reference.qbk | 1666 ++ libs/config/doc/rationale.qbk | 80 + libs/config/index.html | 15 + libs/config/meta/libraries.json | 13 + libs/config/test/Jamfile.v2 | 120 + libs/config/test/abi/abi_test.cpp | 27 + libs/config/test/abi/abi_test.hpp | 54 + libs/config/test/abi/main.cpp | 31 + libs/config/test/all/Jamfile.v2 | 601 + libs/config/test/all/options_v2.jam | 12 + libs/config/test/boost_fallthrough_test.cpp | 20 + libs/config/test/boost_has_2arg_use_facet.ipp | 32 + libs/config/test/boost_has_bethreads.ipp | 34 + libs/config/test/boost_has_clock_gettime.ipp | 35 + libs/config/test/boost_has_dirent_h.ipp | 30 + libs/config/test/boost_has_expm1.ipp | 25 + libs/config/test/boost_has_float128.ipp | 29 + libs/config/test/boost_has_ftime.ipp | 32 + .../boost_has_getsystemtimeasfiletime.ipp | 30 + libs/config/test/boost_has_gettimeofday.ipp | 35 + libs/config/test/boost_has_hash.ipp | 68 + libs/config/test/boost_has_int128.ipp | 75 + libs/config/test/boost_has_log1p.ipp | 24 + libs/config/test/boost_has_long_long.ipp | 36 + .../config/test/boost_has_macro_use_facet.ipp | 35 + libs/config/test/boost_has_ms_int64.ipp | 32 + libs/config/test/boost_has_nanosleep.ipp | 36 + libs/config/test/boost_has_nl_types_h.ipp | 29 + libs/config/test/boost_has_nrvo.ipp | 57 + libs/config/test/boost_has_part_alloc.ipp | 67 + .../test/boost_has_pthread_delay_np.ipp | 35 + libs/config/test/boost_has_pthread_ma_st.ipp | 37 + libs/config/test/boost_has_pthread_yield.ipp | 34 + libs/config/test/boost_has_pthreads.ipp | 64 + libs/config/test/boost_has_rvalue_refs.ipp | 26 + libs/config/test/boost_has_sched_yield.ipp | 34 + .../config/test/boost_has_sgi_type_traits.ipp | 40 + libs/config/test/boost_has_sigaction.ipp | 36 + libs/config/test/boost_has_slist.ipp | 44 + libs/config/test/boost_has_static_assert.ipp | 20 + libs/config/test/boost_has_stdint_h.ipp | 48 + libs/config/test/boost_has_stlp_use_facet.ipp | 31 + libs/config/test/boost_has_unistd_h.ipp | 26 + libs/config/test/boost_has_variadic_tmpl.ipp | 21 + libs/config/test/boost_has_vc6_mem_templ.ipp | 58 + libs/config/test/boost_has_vc_iterator.ipp | 40 + libs/config/test/boost_has_winthreads.ipp | 34 + libs/config/test/boost_no_adl_barrier.ipp | 38 + libs/config/test/boost_no_arg_dep_lookup.ipp | 37 + libs/config/test/boost_no_array_type_spec.ipp | 30 + .../test/boost_no_auto_declarations.ipp | 26 + libs/config/test/boost_no_auto_multidecl.ipp | 26 + libs/config/test/boost_no_auto_ptr.ipp | 53 + .../config/test/boost_no_bcb_partial_spec.ipp | 53 + libs/config/test/boost_no_char16_t.ipp | 32 + libs/config/test/boost_no_char32_t.ipp | 31 + libs/config/test/boost_no_com_value_init.ipp | 1016 + libs/config/test/boost_no_constexpr.ipp | 85 + libs/config/test/boost_no_ctype_functions.ipp | 44 + libs/config/test/boost_no_cv_spec.ipp | 47 + libs/config/test/boost_no_cv_void_spec.ipp | 45 + libs/config/test/boost_no_cwchar.ipp | 33 + libs/config/test/boost_no_cwctype.ipp | 47 + libs/config/test/boost_no_cxx11_addressof.ipp | 28 + libs/config/test/boost_no_cxx11_alignas.ipp | 36 + libs/config/test/boost_no_cxx11_allocator.ipp | 44 + libs/config/test/boost_no_cxx11_atomic_sp.ipp | 36 + .../test/boost_no_cxx11_defaulted_moves.ipp | 25 + libs/config/test/boost_no_cxx11_final.ipp | 41 + libs/config/test/boost_no_cxx11_hdr_array.ipp | 23 + .../config/test/boost_no_cxx11_hdr_atomic.ipp | 90 + .../config/test/boost_no_cxx11_hdr_chrono.ipp | 31 + .../test/boost_no_cxx11_hdr_codecvt.ipp | 29 + .../boost_no_cxx11_hdr_condition_variable.ipp | 24 + .../test/boost_no_cxx11_hdr_forward_list.ipp | 23 + .../config/test/boost_no_cxx11_hdr_future.ipp | 34 + .../boost_no_cxx11_hdr_initializer_list.ipp | 27 + libs/config/test/boost_no_cxx11_hdr_mutex.ipp | 26 + .../config/test/boost_no_cxx11_hdr_random.ipp | 31 + libs/config/test/boost_no_cxx11_hdr_ratio.ipp | 37 + libs/config/test/boost_no_cxx11_hdr_regex.ipp | 29 + .../test/boost_no_cxx11_hdr_system_error.ipp | 26 + .../config/test/boost_no_cxx11_hdr_thread.ipp | 27 + libs/config/test/boost_no_cxx11_hdr_tuple.ipp | 23 + .../test/boost_no_cxx11_hdr_type_traits.ipp | 109 + .../test/boost_no_cxx11_hdr_typeindex.ipp | 33 + .../test/boost_no_cxx11_hdr_unordered_map.ipp | 24 + .../test/boost_no_cxx11_hdr_unordered_set.ipp | 24 + .../test/boost_no_cxx11_inline_namespaces.ipp | 30 + .../test/boost_no_cxx11_non_pub_def_fun.ipp | 38 + .../test/boost_no_cxx11_numeric_limits.ipp | 31 + .../test/boost_no_cxx11_pointer_traits.ipp | 37 + .../test/boost_no_cxx11_ref_qualifiers.ipp | 33 + .../test/boost_no_cxx11_sfinae_expr.ipp | 46 + libs/config/test/boost_no_cxx11_smart_ptr.ipp | 35 + libs/config/test/boost_no_cxx11_std_align.ipp | 34 + .../test/boost_no_cxx11_thread_local.ipp | 36 + .../boost_no_cxx11_trailing_result_types.ipp | 26 + libs/config/test/boost_no_cxx11_user_lit.ipp | 67 + .../test/boost_no_cxx14_binary_literals.ipp | 23 + libs/config/test/boost_no_cxx14_constexpr.ipp | 72 + .../test/boost_no_cxx14_decltype_auto.ipp | 33 + .../test/boost_no_cxx14_digit_separator.ipp | 23 + .../test/boost_no_cxx14_generic_lambda.ipp | 23 + .../test/boost_no_cxx14_hdr_shared_mutex.ipp | 27 + .../test/boost_no_cxx14_lambda_capture.ipp | 23 + .../test/boost_no_cxx14_member_init.ipp | 30 + .../test/boost_no_cxx14_return_type_ded.ipp | 29 + .../test/boost_no_cxx14_std_exchange.ipp | 23 + libs/config/test/boost_no_cxx14_var_templ.ipp | 26 + .../test/boost_no_cxx17_fold_expressions.ipp | 27 + .../test/boost_no_cxx17_inline_variables.ipp | 27 + .../test/boost_no_cxx17_iterator_traits.ipp | 54 + libs/config/test/boost_no_cxx17_std_apply.ipp | 28 + .../config/test/boost_no_cxx17_std_invoke.ipp | 27 + .../boost_no_cxx17_structured_bindings.ipp | 36 + libs/config/test/boost_no_cxx98_binders.ipp | 30 + .../test/boost_no_cxx98_function_base.ipp | 28 + .../test/boost_no_cxx98_random_shuffle.ipp | 23 + .../test/boost_no_cxx_hdr_functional.ipp | 43 + libs/config/test/boost_no_decltype.ipp | 54 + libs/config/test/boost_no_decltype_n3276.ipp | 137 + libs/config/test/boost_no_ded_typename.ipp | 40 + .../test/boost_no_defaulted_functions.ipp | 28 + .../test/boost_no_deleted_functions.ipp | 28 + .../config/test/boost_no_dep_nested_class.ipp | 58 + libs/config/test/boost_no_dep_val_param.ipp | 37 + libs/config/test/boost_no_excep_std.ipp | 35 + libs/config/test/boost_no_exceptions.ipp | 43 + .../config/test/boost_no_exp_func_tem_arg.ipp | 55 + .../config/test/boost_no_explicit_cvt_ops.ipp | 33 + libs/config/test/boost_no_extern_template.ipp | 41 + libs/config/test/boost_no_fenv_h.ipp | 58 + .../boost_no_fixed_len_variadic_templates.ipp | 26 + libs/config/test/boost_no_func_tmp_order.ipp | 49 + ...oost_no_function_template_default_args.ipp | 38 + .../test/boost_no_function_type_spec.ipp | 44 + libs/config/test/boost_no_i64_limits.ipp | 29 + .../config/test/boost_no_inline_memb_init.ipp | 62 + .../config/test/boost_no_integral_int64_t.ipp | 54 + libs/config/test/boost_no_iosfwd.ipp | 23 + libs/config/test/boost_no_iostream.ipp | 25 + libs/config/test/boost_no_is_abstract.ipp | 53 + libs/config/test/boost_no_iter_construct.ipp | 38 + libs/config/test/boost_no_lambdas.ipp | 30 + libs/config/test/boost_no_limits.ipp | 34 + .../config/test/boost_no_limits_const_exp.ipp | 42 + libs/config/test/boost_no_ll_limits.ipp | 37 + libs/config/test/boost_no_long_long.ipp | 36 + libs/config/test/boost_no_mem_func_spec.ipp | 62 + libs/config/test/boost_no_mem_tem_keyword.ipp | 69 + libs/config/test/boost_no_mem_tem_pnts.ipp | 50 + libs/config/test/boost_no_mem_templ_frnds.ipp | 72 + libs/config/test/boost_no_mem_templates.ipp | 64 + .../test/boost_no_nested_friendship.ipp | 44 + libs/config/test/boost_no_noexcept.ipp | 26 + libs/config/test/boost_no_nullptr.ipp | 24 + .../config/test/boost_no_ops_in_namespace.ipp | 73 + .../test/boost_no_part_spec_def_args.ipp | 46 + libs/config/test/boost_no_partial_spec.ipp | 56 + libs/config/test/boost_no_priv_aggregate.ipp | 39 + libs/config/test/boost_no_ptr_mem_const.ipp | 84 + libs/config/test/boost_no_range_based_for.ipp | 23 + libs/config/test/boost_no_raw_literals.ipp | 27 + .../test/boost_no_restrict_references.ipp | 47 + libs/config/test/boost_no_ret_det.ipp | 43 + libs/config/test/boost_no_rtti.ipp | 64 + .../test/boost_no_rvalue_references.ipp | 26 + libs/config/test/boost_no_scoped_enums.ipp | 28 + libs/config/test/boost_no_sfinae.ipp | 68 + libs/config/test/boost_no_sfinae_expr.ipp | 37 + libs/config/test/boost_no_sstream.ipp | 29 + libs/config/test/boost_no_static_assert.ipp | 20 + libs/config/test/boost_no_std_allocator.ipp | 87 + libs/config/test/boost_no_std_distance.ipp | 31 + libs/config/test/boost_no_std_iter_traits.ipp | 80 + libs/config/test/boost_no_std_iterator.ipp | 67 + libs/config/test/boost_no_std_locale.ipp | 36 + libs/config/test/boost_no_std_messages.ipp | 39 + libs/config/test/boost_no_std_min_max.ipp | 33 + libs/config/test/boost_no_std_oi_assign.ipp | 42 + libs/config/test/boost_no_std_typeinfo.ipp | 26 + libs/config/test/boost_no_std_use_facet.ipp | 29 + libs/config/test/boost_no_std_wstreambuf.ipp | 108 + libs/config/test/boost_no_std_wstring.ipp | 28 + libs/config/test/boost_no_stdc_namespace.ipp | 43 + libs/config/test/boost_no_swprintf.ipp | 31 + .../test/boost_no_tem_local_classes.ipp | 33 + .../config/test/boost_no_template_aliases.ipp | 22 + .../config/test/boost_no_template_streams.ipp | 29 + .../test/boost_no_template_template.ipp | 50 + .../config/test/boost_no_two_phase_lookup.ipp | 41 + libs/config/test/boost_no_typeid.ipp | 24 + .../test/boost_no_typename_with_ctor.ipp | 34 + .../config/test/boost_no_unicode_literals.ipp | 29 + libs/config/test/boost_no_unified_init.ipp | 59 + .../config/test/boost_no_using_breaks_adl.ipp | 73 + .../test/boost_no_using_decl_overld.ipp | 33 + libs/config/test/boost_no_using_template.ipp | 47 + libs/config/test/boost_no_variadic_macros.ipp | 64 + .../test/boost_no_variadic_templates.ipp | 21 + libs/config/test/boost_no_void_returns.ipp | 34 + libs/config/test/boost_no_wchar_t.ipp | 45 + libs/config/test/cmd_line_check.cpp | 9 + libs/config/test/config_build_check.cpp | 20 + libs/config/test/config_info.cpp | 1330 + libs/config/test/config_test.cpp | 1951 ++ libs/config/test/config_test_c.c | 9 + libs/config/test/cstdint_include_test.cpp | 69 + libs/config/test/cstdint_test.cpp | 238 + libs/config/test/cstdint_test2.cpp | 248 + libs/config/test/has_2arg_use_facet_fail.cpp | 34 + libs/config/test/has_2arg_use_facet_pass.cpp | 34 + libs/config/test/has_bethreads_fail.cpp | 34 + libs/config/test/has_bethreads_pass.cpp | 34 + libs/config/test/has_clock_gettime_fail.cpp | 34 + libs/config/test/has_clock_gettime_pass.cpp | 34 + libs/config/test/has_dirent_h_fail.cpp | 34 + libs/config/test/has_dirent_h_pass.cpp | 34 + libs/config/test/has_expm1_fail.cpp | 34 + libs/config/test/has_expm1_pass.cpp | 34 + libs/config/test/has_float128_fail.cpp | 37 + libs/config/test/has_float128_pass.cpp | 37 + libs/config/test/has_ftime_fail.cpp | 34 + libs/config/test/has_ftime_pass.cpp | 34 + .../test/has_getsystemtimeasfiletime_fail.cpp | 37 + .../test/has_getsystemtimeasfiletime_pass.cpp | 37 + libs/config/test/has_gettimeofday_fail.cpp | 34 + libs/config/test/has_gettimeofday_pass.cpp | 34 + libs/config/test/has_hash_fail.cpp | 34 + libs/config/test/has_hash_pass.cpp | 34 + libs/config/test/has_int128_fail.cpp | 37 + libs/config/test/has_int128_pass.cpp | 37 + libs/config/test/has_log1p_fail.cpp | 34 + libs/config/test/has_log1p_pass.cpp | 34 + libs/config/test/has_long_long_fail.cpp | 34 + libs/config/test/has_long_long_pass.cpp | 34 + libs/config/test/has_macro_use_facet_fail.cpp | 34 + libs/config/test/has_macro_use_facet_pass.cpp | 34 + libs/config/test/has_ms_int64_fail.cpp | 34 + libs/config/test/has_ms_int64_pass.cpp | 34 + libs/config/test/has_nanosleep_fail.cpp | 34 + libs/config/test/has_nanosleep_pass.cpp | 34 + libs/config/test/has_nl_types_h_fail.cpp | 34 + libs/config/test/has_nl_types_h_pass.cpp | 34 + libs/config/test/has_nrvo_fail.cpp | 34 + libs/config/test/has_nrvo_pass.cpp | 34 + libs/config/test/has_part_alloc_fail.cpp | 34 + libs/config/test/has_part_alloc_pass.cpp | 34 + .../config/test/has_pthread_delay_np_fail.cpp | 34 + .../config/test/has_pthread_delay_np_pass.cpp | 34 + libs/config/test/has_pthread_ma_st_fail.cpp | 34 + libs/config/test/has_pthread_ma_st_pass.cpp | 34 + libs/config/test/has_pthread_yield_fail.cpp | 34 + libs/config/test/has_pthread_yield_pass.cpp | 34 + libs/config/test/has_pthreads_fail.cpp | 34 + libs/config/test/has_pthreads_pass.cpp | 34 + libs/config/test/has_rvalue_refs_fail.cpp | 34 + libs/config/test/has_rvalue_refs_pass.cpp | 34 + libs/config/test/has_sched_yield_fail.cpp | 34 + libs/config/test/has_sched_yield_pass.cpp | 34 + libs/config/test/has_sgi_type_traits_fail.cpp | 34 + libs/config/test/has_sgi_type_traits_pass.cpp | 34 + libs/config/test/has_sigaction_fail.cpp | 34 + libs/config/test/has_sigaction_pass.cpp | 34 + libs/config/test/has_slist_fail.cpp | 34 + libs/config/test/has_slist_pass.cpp | 34 + libs/config/test/has_static_assert_fail.cpp | 34 + libs/config/test/has_static_assert_pass.cpp | 34 + libs/config/test/has_stdint_h_fail.cpp | 34 + libs/config/test/has_stdint_h_pass.cpp | 34 + libs/config/test/has_stlp_use_facet_fail.cpp | 34 + libs/config/test/has_stlp_use_facet_pass.cpp | 34 + libs/config/test/has_unistd_h_fail.cpp | 34 + libs/config/test/has_unistd_h_pass.cpp | 34 + libs/config/test/has_variadic_tmpl_fail.cpp | 34 + libs/config/test/has_variadic_tmpl_pass.cpp | 34 + libs/config/test/has_vc6_mem_templ_fail.cpp | 34 + libs/config/test/has_vc6_mem_templ_pass.cpp | 34 + libs/config/test/has_vc_iterator_fail.cpp | 34 + libs/config/test/has_vc_iterator_pass.cpp | 34 + libs/config/test/has_winthreads_fail.cpp | 34 + libs/config/test/has_winthreads_pass.cpp | 34 + libs/config/test/header_deprecated_test.cpp | 18 + libs/config/test/helper_macro_test.cpp | 63 + libs/config/test/helper_macros_test.cpp | 30 + libs/config/test/limits_test.cpp | 213 + libs/config/test/link/Jamfile.v2 | 19 + libs/config/test/link/bc_gen.sh | 286 + libs/config/test/link/borland.mak | 429 + libs/config/test/link/common.sh | 19 + libs/config/test/link/link_test.cpp | 54 + libs/config/test/link/link_test.hpp | 108 + libs/config/test/link/main.cpp | 19 + libs/config/test/link/test/Jamfile.v2 | 117 + libs/config/test/link/vc6-stlport.mak | 292 + libs/config/test/link/vc6.mak | 260 + libs/config/test/link/vc7-stlport.mak | 292 + libs/config/test/link/vc7.mak | 260 + libs/config/test/link/vc71-stlport.mak | 292 + libs/config/test/link/vc71.mak | 260 + libs/config/test/link/vc_gen.sh | 424 + libs/config/test/math_info.cpp | 365 + libs/config/test/no_adl_barrier_fail.cpp | 37 + libs/config/test/no_adl_barrier_pass.cpp | 37 + libs/config/test/no_arg_dep_lookup_fail.cpp | 34 + libs/config/test/no_arg_dep_lookup_pass.cpp | 34 + libs/config/test/no_array_type_spec_fail.cpp | 34 + libs/config/test/no_array_type_spec_pass.cpp | 34 + .../config/test/no_auto_declarations_fail.cpp | 37 + .../config/test/no_auto_declarations_pass.cpp | 37 + libs/config/test/no_auto_multidecl_fail.cpp | 37 + libs/config/test/no_auto_multidecl_pass.cpp | 37 + libs/config/test/no_auto_ptr_fail.cpp | 34 + libs/config/test/no_auto_ptr_pass.cpp | 34 + libs/config/test/no_bcb_partial_spec_fail.cpp | 34 + libs/config/test/no_bcb_partial_spec_pass.cpp | 34 + libs/config/test/no_char16_t_fail.cpp | 37 + libs/config/test/no_char16_t_pass.cpp | 37 + libs/config/test/no_char32_t_fail.cpp | 37 + libs/config/test/no_char32_t_pass.cpp | 37 + libs/config/test/no_com_value_init_fail.cpp | 37 + libs/config/test/no_com_value_init_pass.cpp | 37 + libs/config/test/no_constexpr_fail.cpp | 37 + libs/config/test/no_constexpr_pass.cpp | 37 + libs/config/test/no_ctype_functions_fail.cpp | 34 + libs/config/test/no_ctype_functions_pass.cpp | 34 + libs/config/test/no_cv_spec_fail.cpp | 34 + libs/config/test/no_cv_spec_pass.cpp | 34 + libs/config/test/no_cv_void_spec_fail.cpp | 34 + libs/config/test/no_cv_void_spec_pass.cpp | 34 + libs/config/test/no_cwchar_fail.cpp | 34 + libs/config/test/no_cwchar_pass.cpp | 34 + libs/config/test/no_cwctype_fail.cpp | 34 + libs/config/test/no_cwctype_pass.cpp | 34 + libs/config/test/no_cxx11_addressof_fail.cpp | 37 + libs/config/test/no_cxx11_addressof_pass.cpp | 37 + libs/config/test/no_cxx11_alignas_fail.cpp | 37 + libs/config/test/no_cxx11_alignas_pass.cpp | 37 + libs/config/test/no_cxx11_allocator_fail.cpp | 37 + libs/config/test/no_cxx11_allocator_pass.cpp | 37 + libs/config/test/no_cxx11_atomic_sp_fail.cpp | 37 + libs/config/test/no_cxx11_atomic_sp_pass.cpp | 37 + .../test/no_cxx11_defaulted_moves_fail.cpp | 37 + .../test/no_cxx11_defaulted_moves_pass.cpp | 37 + libs/config/test/no_cxx11_final_fail.cpp | 37 + libs/config/test/no_cxx11_final_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_array_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_array_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_atomic_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_atomic_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_chrono_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_chrono_pass.cpp | 37 + .../config/test/no_cxx11_hdr_codecvt_fail.cpp | 37 + .../config/test/no_cxx11_hdr_codecvt_pass.cpp | 37 + .../no_cxx11_hdr_condition_variable_fail.cpp | 37 + .../no_cxx11_hdr_condition_variable_pass.cpp | 37 + .../test/no_cxx11_hdr_forward_list_fail.cpp | 37 + .../test/no_cxx11_hdr_forward_list_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_future_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_future_pass.cpp | 37 + .../no_cxx11_hdr_initializer_list_fail.cpp | 37 + .../no_cxx11_hdr_initializer_list_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_mutex_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_mutex_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_random_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_random_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_ratio_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_ratio_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_regex_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_regex_pass.cpp | 37 + .../test/no_cxx11_hdr_system_error_fail.cpp | 37 + .../test/no_cxx11_hdr_system_error_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_thread_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_thread_pass.cpp | 37 + libs/config/test/no_cxx11_hdr_tuple_fail.cpp | 37 + libs/config/test/no_cxx11_hdr_tuple_pass.cpp | 37 + .../test/no_cxx11_hdr_type_traits_fail.cpp | 37 + .../test/no_cxx11_hdr_type_traits_pass.cpp | 37 + .../test/no_cxx11_hdr_typeindex_fail.cpp | 37 + .../test/no_cxx11_hdr_typeindex_pass.cpp | 37 + .../test/no_cxx11_hdr_unordered_map_fail.cpp | 37 + .../test/no_cxx11_hdr_unordered_map_pass.cpp | 37 + .../test/no_cxx11_hdr_unordered_set_fail.cpp | 37 + .../test/no_cxx11_hdr_unordered_set_pass.cpp | 37 + .../test/no_cxx11_inline_namespaces_fail.cpp | 37 + .../test/no_cxx11_inline_namespaces_pass.cpp | 37 + .../test/no_cxx11_non_pub_def_fun_fail.cpp | 37 + .../test/no_cxx11_non_pub_def_fun_pass.cpp | 37 + .../test/no_cxx11_numeric_limits_fail.cpp | 37 + .../test/no_cxx11_numeric_limits_pass.cpp | 37 + .../test/no_cxx11_pointer_traits_fail.cpp | 37 + .../test/no_cxx11_pointer_traits_pass.cpp | 37 + .../test/no_cxx11_ref_qualifiers_fail.cpp | 37 + .../test/no_cxx11_ref_qualifiers_pass.cpp | 37 + .../config/test/no_cxx11_sfinae_expr_fail.cpp | 37 + .../config/test/no_cxx11_sfinae_expr_pass.cpp | 37 + libs/config/test/no_cxx11_smart_ptr_fail.cpp | 37 + libs/config/test/no_cxx11_smart_ptr_pass.cpp | 37 + libs/config/test/no_cxx11_std_align_fail.cpp | 37 + libs/config/test/no_cxx11_std_align_pass.cpp | 37 + .../test/no_cxx11_thread_local_fail.cpp | 37 + .../test/no_cxx11_thread_local_pass.cpp | 37 + .../no_cxx11_trailing_result_types_fail.cpp | 37 + .../no_cxx11_trailing_result_types_pass.cpp | 37 + libs/config/test/no_cxx11_user_lit_fail.cpp | 37 + libs/config/test/no_cxx11_user_lit_pass.cpp | 37 + .../test/no_cxx14_binary_literals_fail.cpp | 37 + .../test/no_cxx14_binary_literals_pass.cpp | 37 + libs/config/test/no_cxx14_constexpr_fail.cpp | 37 + libs/config/test/no_cxx14_constexpr_pass.cpp | 37 + .../test/no_cxx14_decltype_auto_fail.cpp | 37 + .../test/no_cxx14_decltype_auto_pass.cpp | 37 + .../test/no_cxx14_digit_separator_fail.cpp | 37 + .../test/no_cxx14_digit_separator_pass.cpp | 37 + .../test/no_cxx14_generic_lambda_fail.cpp | 37 + .../test/no_cxx14_generic_lambda_pass.cpp | 37 + .../test/no_cxx14_hdr_shared_mutex_fail.cpp | 37 + .../test/no_cxx14_hdr_shared_mutex_pass.cpp | 37 + .../test/no_cxx14_lambda_capture_fail.cpp | 37 + .../test/no_cxx14_lambda_capture_pass.cpp | 37 + .../config/test/no_cxx14_member_init_fail.cpp | 37 + .../config/test/no_cxx14_member_init_pass.cpp | 37 + .../test/no_cxx14_return_type_ded_fail.cpp | 37 + .../test/no_cxx14_return_type_ded_pass.cpp | 37 + .../test/no_cxx14_std_exchange_fail.cpp | 37 + .../test/no_cxx14_std_exchange_pass.cpp | 37 + libs/config/test/no_cxx14_var_templ_fail.cpp | 37 + libs/config/test/no_cxx14_var_templ_pass.cpp | 37 + .../test/no_cxx17_fold_expressions_fail.cpp | 37 + .../test/no_cxx17_fold_expressions_pass.cpp | 37 + .../test/no_cxx17_inline_variables_fail.cpp | 37 + .../test/no_cxx17_inline_variables_pass.cpp | 37 + .../test/no_cxx17_iterator_traits_fail.cpp | 37 + .../test/no_cxx17_iterator_traits_pass.cpp | 37 + libs/config/test/no_cxx17_std_apply_fail.cpp | 37 + libs/config/test/no_cxx17_std_apply_pass.cpp | 37 + libs/config/test/no_cxx17_std_invoke_fail.cpp | 37 + libs/config/test/no_cxx17_std_invoke_pass.cpp | 37 + .../no_cxx17_structured_bindings_fail.cpp | 37 + .../no_cxx17_structured_bindings_pass.cpp | 37 + libs/config/test/no_cxx98_binders_fail.cpp | 37 + libs/config/test/no_cxx98_binders_pass.cpp | 37 + .../test/no_cxx98_function_base_fail.cpp | 37 + .../test/no_cxx98_function_base_pass.cpp | 37 + .../test/no_cxx98_random_shuffle_fail.cpp | 37 + .../test/no_cxx98_random_shuffle_pass.cpp | 37 + .../test/no_cxx_hdr_functional_fail.cpp | 37 + .../test/no_cxx_hdr_functional_pass.cpp | 37 + libs/config/test/no_decltype_fail.cpp | 37 + libs/config/test/no_decltype_n3276_fail.cpp | 37 + libs/config/test/no_decltype_n3276_pass.cpp | 37 + libs/config/test/no_decltype_pass.cpp | 37 + libs/config/test/no_ded_typename_fail.cpp | 34 + libs/config/test/no_ded_typename_pass.cpp | 34 + .../test/no_defaulted_functions_fail.cpp | 37 + .../test/no_defaulted_functions_pass.cpp | 37 + .../config/test/no_deleted_functions_fail.cpp | 37 + .../config/test/no_deleted_functions_pass.cpp | 37 + libs/config/test/no_dep_nested_class_fail.cpp | 34 + libs/config/test/no_dep_nested_class_pass.cpp | 34 + libs/config/test/no_dep_val_param_fail.cpp | 34 + libs/config/test/no_dep_val_param_pass.cpp | 34 + libs/config/test/no_excep_std_fail.cpp | 34 + libs/config/test/no_excep_std_pass.cpp | 34 + libs/config/test/no_exceptions_fail.cpp | 34 + libs/config/test/no_exceptions_pass.cpp | 34 + libs/config/test/no_exp_func_tem_arg_fail.cpp | 34 + libs/config/test/no_exp_func_tem_arg_pass.cpp | 34 + libs/config/test/no_explicit_cvt_ops_fail.cpp | 37 + libs/config/test/no_explicit_cvt_ops_pass.cpp | 37 + libs/config/test/no_extern_template_fail.cpp | 37 + libs/config/test/no_extern_template_pass.cpp | 37 + libs/config/test/no_fenv_h_fail.cpp | 33 + libs/config/test/no_fenv_h_pass.cpp | 33 + .../no_fixed_len_variadic_templates_fail.cpp | 37 + .../no_fixed_len_variadic_templates_pass.cpp | 37 + libs/config/test/no_func_tmp_order_fail.cpp | 34 + libs/config/test/no_func_tmp_order_pass.cpp | 34 + ...no_function_template_default_args_fail.cpp | 37 + ...no_function_template_default_args_pass.cpp | 37 + .../test/no_function_type_spec_fail.cpp | 34 + .../test/no_function_type_spec_pass.cpp | 34 + libs/config/test/no_i64_limits_fail.cpp | 34 + libs/config/test/no_i64_limits_pass.cpp | 34 + libs/config/test/no_inline_memb_init_fail.cpp | 34 + libs/config/test/no_inline_memb_init_pass.cpp | 34 + libs/config/test/no_integral_int64_t_fail.cpp | 34 + libs/config/test/no_integral_int64_t_pass.cpp | 34 + libs/config/test/no_iosfwd_fail.cpp | 34 + libs/config/test/no_iosfwd_pass.cpp | 34 + libs/config/test/no_iostream_fail.cpp | 34 + libs/config/test/no_iostream_pass.cpp | 34 + libs/config/test/no_is_abstract_fail.cpp | 34 + libs/config/test/no_is_abstract_pass.cpp | 34 + libs/config/test/no_iter_construct_fail.cpp | 34 + libs/config/test/no_iter_construct_pass.cpp | 34 + libs/config/test/no_lambdas_fail.cpp | 37 + libs/config/test/no_lambdas_pass.cpp | 37 + libs/config/test/no_limits_const_exp_fail.cpp | 34 + libs/config/test/no_limits_const_exp_pass.cpp | 34 + libs/config/test/no_limits_fail.cpp | 34 + libs/config/test/no_limits_pass.cpp | 34 + libs/config/test/no_ll_limits_fail.cpp | 34 + libs/config/test/no_ll_limits_pass.cpp | 34 + libs/config/test/no_long_long_fail.cpp | 37 + libs/config/test/no_long_long_pass.cpp | 37 + libs/config/test/no_mem_func_spec_fail.cpp | 34 + libs/config/test/no_mem_func_spec_pass.cpp | 34 + libs/config/test/no_mem_tem_keyword_fail.cpp | 34 + libs/config/test/no_mem_tem_keyword_pass.cpp | 34 + libs/config/test/no_mem_tem_pnts_fail.cpp | 34 + libs/config/test/no_mem_tem_pnts_pass.cpp | 34 + libs/config/test/no_mem_templ_frnds_fail.cpp | 34 + libs/config/test/no_mem_templ_frnds_pass.cpp | 34 + libs/config/test/no_mem_templates_fail.cpp | 34 + libs/config/test/no_mem_templates_pass.cpp | 34 + .../config/test/no_nested_friendship_fail.cpp | 37 + .../config/test/no_nested_friendship_pass.cpp | 37 + libs/config/test/no_noexcept_fail.cpp | 37 + libs/config/test/no_noexcept_pass.cpp | 37 + libs/config/test/no_nullptr_fail.cpp | 37 + libs/config/test/no_nullptr_pass.cpp | 37 + libs/config/test/no_ops_in_namespace_fail.cpp | 34 + libs/config/test/no_ops_in_namespace_pass.cpp | 34 + .../test/no_part_spec_def_args_fail.cpp | 37 + .../test/no_part_spec_def_args_pass.cpp | 37 + libs/config/test/no_partial_spec_fail.cpp | 34 + libs/config/test/no_partial_spec_pass.cpp | 34 + libs/config/test/no_priv_aggregate_fail.cpp | 34 + libs/config/test/no_priv_aggregate_pass.cpp | 34 + libs/config/test/no_ptr_mem_const_fail.cpp | 34 + libs/config/test/no_ptr_mem_const_pass.cpp | 34 + libs/config/test/no_range_based_for_fail.cpp | 37 + libs/config/test/no_range_based_for_pass.cpp | 37 + libs/config/test/no_raw_literals_fail.cpp | 37 + libs/config/test/no_raw_literals_pass.cpp | 37 + .../test/no_restrict_references_fail.cpp | 37 + .../test/no_restrict_references_pass.cpp | 37 + libs/config/test/no_ret_det_fail.cpp | 34 + libs/config/test/no_ret_det_pass.cpp | 34 + libs/config/test/no_rtti_fail.cpp | 37 + libs/config/test/no_rtti_pass.cpp | 37 + .../config/test/no_rvalue_references_fail.cpp | 37 + .../config/test/no_rvalue_references_pass.cpp | 37 + libs/config/test/no_scoped_enums_fail.cpp | 37 + libs/config/test/no_scoped_enums_pass.cpp | 37 + libs/config/test/no_sfinae_expr_fail.cpp | 37 + libs/config/test/no_sfinae_expr_pass.cpp | 37 + libs/config/test/no_sfinae_fail.cpp | 34 + libs/config/test/no_sfinae_pass.cpp | 34 + libs/config/test/no_sstream_fail.cpp | 34 + libs/config/test/no_sstream_pass.cpp | 34 + libs/config/test/no_static_assert_fail.cpp | 37 + libs/config/test/no_static_assert_pass.cpp | 37 + libs/config/test/no_std_allocator_fail.cpp | 34 + libs/config/test/no_std_allocator_pass.cpp | 34 + libs/config/test/no_std_distance_fail.cpp | 34 + libs/config/test/no_std_distance_pass.cpp | 34 + libs/config/test/no_std_iter_traits_fail.cpp | 34 + libs/config/test/no_std_iter_traits_pass.cpp | 34 + libs/config/test/no_std_iterator_fail.cpp | 34 + libs/config/test/no_std_iterator_pass.cpp | 34 + libs/config/test/no_std_locale_fail.cpp | 34 + libs/config/test/no_std_locale_pass.cpp | 34 + libs/config/test/no_std_messages_fail.cpp | 34 + libs/config/test/no_std_messages_pass.cpp | 34 + libs/config/test/no_std_min_max_fail.cpp | 34 + libs/config/test/no_std_min_max_pass.cpp | 34 + libs/config/test/no_std_oi_assign_fail.cpp | 34 + libs/config/test/no_std_oi_assign_pass.cpp | 34 + libs/config/test/no_std_typeinfo_fail.cpp | 34 + libs/config/test/no_std_typeinfo_pass.cpp | 34 + libs/config/test/no_std_use_facet_fail.cpp | 34 + libs/config/test/no_std_use_facet_pass.cpp | 34 + libs/config/test/no_std_wstreambuf_fail.cpp | 34 + libs/config/test/no_std_wstreambuf_pass.cpp | 34 + libs/config/test/no_std_wstring_fail.cpp | 34 + libs/config/test/no_std_wstring_pass.cpp | 34 + libs/config/test/no_stdc_namespace_fail.cpp | 34 + libs/config/test/no_stdc_namespace_pass.cpp | 34 + libs/config/test/no_swprintf_fail.cpp | 34 + libs/config/test/no_swprintf_pass.cpp | 34 + .../config/test/no_tem_local_classes_fail.cpp | 37 + .../config/test/no_tem_local_classes_pass.cpp | 37 + libs/config/test/no_template_aliases_fail.cpp | 37 + libs/config/test/no_template_aliases_pass.cpp | 37 + libs/config/test/no_template_streams_fail.cpp | 37 + libs/config/test/no_template_streams_pass.cpp | 37 + .../config/test/no_template_template_fail.cpp | 34 + .../config/test/no_template_template_pass.cpp | 34 + libs/config/test/no_two_phase_lookup_fail.cpp | 34 + libs/config/test/no_two_phase_lookup_pass.cpp | 34 + libs/config/test/no_typeid_fail.cpp | 34 + libs/config/test/no_typeid_pass.cpp | 34 + .../test/no_typename_with_ctor_fail.cpp | 37 + .../test/no_typename_with_ctor_pass.cpp | 37 + libs/config/test/no_unicode_literals_fail.cpp | 37 + libs/config/test/no_unicode_literals_pass.cpp | 37 + libs/config/test/no_unified_init_fail.cpp | 37 + libs/config/test/no_unified_init_pass.cpp | 37 + libs/config/test/no_using_breaks_adl_fail.cpp | 34 + libs/config/test/no_using_breaks_adl_pass.cpp | 34 + .../config/test/no_using_decl_overld_fail.cpp | 34 + .../config/test/no_using_decl_overld_pass.cpp | 34 + libs/config/test/no_using_template_fail.cpp | 34 + libs/config/test/no_using_template_pass.cpp | 34 + libs/config/test/no_variadic_macros_fail.cpp | 37 + libs/config/test/no_variadic_macros_pass.cpp | 37 + .../test/no_variadic_templates_fail.cpp | 37 + .../test/no_variadic_templates_pass.cpp | 37 + libs/config/test/no_void_returns_fail.cpp | 34 + libs/config/test/no_void_returns_pass.cpp | 34 + libs/config/test/no_wchar_t_fail.cpp | 34 + libs/config/test/no_wchar_t_pass.cpp | 34 + libs/config/test/pragma_message_test.cpp | 18 + libs/config/test/test.hpp | 21 + .../config/test/threads/test_thread_fail1.cpp | 10 + .../config/test/threads/test_thread_fail2.cpp | 13 + libs/config/tools/Jamfile.v2 | 15 + libs/config/tools/configure.in | 463 + libs/config/tools/generate.cpp | 345 + libs/date_time/build/Jamfile.v2 | 33 + libs/date_time/src/date_time.doc | 72 + .../src/gregorian/date_generators.cpp | 38 + libs/date_time/src/gregorian/greg_month.cpp | 173 + libs/date_time/src/gregorian/greg_names.hpp | 43 + libs/date_time/src/gregorian/greg_weekday.cpp | 50 + .../src/gregorian/gregorian_types.cpp | 62 + .../src/posix_time/posix_time_types.cpp | 35 + libs/exception/build/Jamfile.v2 | 14 + .../clone_current_exception_non_intrusive.cpp | 349 + libs/filesystem/bug/Jamfile.v2 | 19 + libs/filesystem/bug/bug.cpp | 19 + libs/filesystem/bug/index.html | 13 + libs/filesystem/build/Jamfile.v2 | 42 + libs/filesystem/doc/Jamfile.v2 | 25 + .../doc/POSIX_filename_encoding.txt | 55 + libs/filesystem/doc/build_tutorial.bat | 7 + libs/filesystem/doc/deprecated.html | 387 + libs/filesystem/doc/design.htm | 353 + libs/filesystem/doc/do_list.html | 146 + libs/filesystem/doc/faq.htm | 148 + libs/filesystem/doc/index.htm | 456 + libs/filesystem/doc/issue_reporting.html | 224 + libs/filesystem/doc/path_table.cpp | 260 + libs/filesystem/doc/path_table.txt | 50 + libs/filesystem/doc/portability_guide.htm | 242 + libs/filesystem/doc/publish.bat | 21 + libs/filesystem/doc/reference.html | 4273 +++ libs/filesystem/doc/relative_proposal.html | 510 + libs/filesystem/doc/release_history.html | 467 + libs/filesystem/doc/styles.css | 19 + libs/filesystem/doc/tickets.html | 52 + libs/filesystem/doc/tutorial.html | 1340 + libs/filesystem/doc/v3.html | 152 + libs/filesystem/doc/v3_design.html | 199 + libs/filesystem/example/Jamfile.v2 | 27 + .../directory_symlink_parent_resolution.cpp | 41 + libs/filesystem/example/error_demo.cpp | 185 + libs/filesystem/example/file_size.cpp | 44 + libs/filesystem/example/file_status.cpp | 117 + libs/filesystem/example/mbcopy.cpp | 90 + libs/filesystem/example/mbpath.cpp | 80 + libs/filesystem/example/mbpath.hpp | 44 + libs/filesystem/example/msvc/common.props | 15 + ...irectory_symlink_parent_resolution.vcxproj | 170 + .../example/msvc/filesystem-tutorials.sln | 88 + .../example/msvc/path_info/path_info.vcxproj | 158 + .../filesystem/example/msvc/tut1/tut1.vcxproj | 158 + .../filesystem/example/msvc/tut2/tut2.vcxproj | 158 + .../filesystem/example/msvc/tut3/tut3.vcxproj | 170 + .../filesystem/example/msvc/tut4/tut4.vcxproj | 170 + .../filesystem/example/msvc/tut5/tut5.vcxproj | 158 + libs/filesystem/example/path_info.cpp | 82 + libs/filesystem/example/simple_ls.cpp | 91 + libs/filesystem/example/stems.cpp | 31 + libs/filesystem/example/tchar.cpp | 39 + libs/filesystem/example/test/Jamfile.v2 | 31 + libs/filesystem/example/test/build.bat | 7 + libs/filesystem/example/test/build.sh | 8 + libs/filesystem/example/test/setup.bat | 13 + libs/filesystem/example/test/setup.sh | 19 + libs/filesystem/example/tut0.cpp | 23 + libs/filesystem/example/tut1.cpp | 23 + libs/filesystem/example/tut2.cpp | 40 + libs/filesystem/example/tut3.cpp | 52 + libs/filesystem/example/tut4.cpp | 61 + libs/filesystem/example/tut5.cpp | 52 + libs/filesystem/example/tut6a.cpp | 48 + libs/filesystem/example/tut6b.cpp | 50 + libs/filesystem/example/tut6c.cpp | 40 + libs/filesystem/index.html | 13 + libs/filesystem/meta/libraries.json | 14 + .../filesystem/src/codecvt_error_category.cpp | 84 + libs/filesystem/src/operations.cpp | 2365 ++ libs/filesystem/src/path.cpp | 953 + libs/filesystem/src/path_traits.cpp | 200 + libs/filesystem/src/portability.cpp | 119 + libs/filesystem/src/unique_path.cpp | 163 + libs/filesystem/src/utf8_codecvt_facet.cpp | 27 + libs/filesystem/src/windows_file_codecvt.cpp | 75 + libs/filesystem/src/windows_file_codecvt.hpp | 56 + libs/filesystem/test/Jamfile.v2 | 44 + libs/filesystem/test/b2.log | 1456 + libs/filesystem/test/config_info.cpp | 52 + libs/filesystem/test/convenience_test.cpp | 177 + libs/filesystem/test/deprecated_test.cpp | 251 + libs/filesystem/test/design_use_cases.cpp | 81 + libs/filesystem/test/equivalent.cpp | 39 + libs/filesystem/test/fstream_test.cpp | 169 + libs/filesystem/test/issues/10038.cpp | 8 + libs/filesystem/test/issues/10205.cpp | 17 + libs/filesystem/test/issues/10485.cpp | 14 + libs/filesystem/test/issues/10641.cpp | 20 + .../test/issues/11166-remove-race.cpp | 38 + ...red-recursive_directory_iterator-range.cpp | 25 + libs/filesystem/test/issues/3332/test.cpp | 37 + .../filesystem/test/issues/4329.-basename.cpp | 20 + .../test/issues/5300-temp-dir-path-130.cpp | 0 .../test/issues/6638-global-init-fails-3.cpp | 36 + libs/filesystem/test/issues/8930.cpp | 7 + ...static_const_codecvt_segfault_pre_main.cpp | 10 + libs/filesystem/test/issues/9219.cpp | 40 + libs/filesystem/test/issues/Jamfile.v2 | 40 + libs/filesystem/test/issues/boost-no-inspect | 0 ...copy_file-compilation-error-2015-05-04.cpp | 14 + .../fchmodat_AT_SYMLINK_NOFOLLOW_6659.cpp | 38 + .../test/issues/hello_filesystem.cpp | 39 + libs/filesystem/test/issues/readme.txt | 9 + .../test/issues/recurse_dir_iter_5403.cpp | 132 + .../test/large_file_support_test.cpp | 42 + libs/filesystem/test/locale_info.cpp | 88 + libs/filesystem/test/long_path_test.cpp | 59 + libs/filesystem/test/macro_default_test.cpp | 36 + libs/filesystem/test/msvc/boost-no-inspect | 0 libs/filesystem/test/msvc/common.props | 18 + .../test/msvc/config_info/config_info.vcxproj | 164 + .../convenience_test/convenience_test.vcxproj | 108 + .../deprecated_test/deprecated_test.vcxproj | 108 + .../exec_monitor_dll/exec_monitor_dll.vcxproj | 88 + .../exec_monitor_lib/exec_monitor_lib.vcxproj | 81 + .../test/msvc/file_status/file_status.vcxproj | 102 + libs/filesystem/test/msvc/filesystem.sln | 344 + .../filesystem_dll/filesystem_dll.vcxproj | 109 + .../filesystem_lib/filesystem_lib.vcxproj | 93 + .../msvc/fstream_test/fstream_test.vcxproj | 108 + .../test/msvc/headers/headers.vcxproj | 95 + .../hello_filesystem/hello_filesystem.vcxproj | 110 + .../test/msvc/issue_test/issue_test.vcxproj | 103 + .../issues_test_static.vcxproj | 171 + .../test/msvc/locale_info/locale_info.vcxproj | 98 + .../long_path_test/long_path_test.vcxproj | 102 + .../macro_default_test.vcxproj | 94 + .../test/msvc/odr_test/odr_test.vcxproj | 97 + .../operations_test/operations_test.vcxproj | 107 + .../operations_unit_test.vcxproj | 110 + .../test/msvc/path_test/path_test.vcxproj | 108 + .../path_test_static/path_test_static.vcxproj | 106 + .../msvc/path_timings/path_timings.vcxproj | 98 + .../path_unit_test/path_unit_test.vcxproj | 108 + .../recurse_dir_iter_test.vcxproj | 96 + .../msvc/relative_test/relative_test.vcxproj | 178 + libs/filesystem/test/msvc/stems/stems.vcxproj | 94 + .../test/msvc/system_dll/system_dll.vcxproj | 95 + .../test/msvc/system_lib/system_lib.vcxproj | 81 + libs/filesystem/test/msvc/tut1/tut1.vcxproj | 102 + libs/filesystem/test/msvc/tut2/tut2.vcxproj | 103 + libs/filesystem/test/msvc/tut3/tut3.vcxproj | 102 + libs/filesystem/test/msvc/tut4/tut4.vcxproj | 106 + libs/filesystem/test/msvc/tut5/tut5.vcxproj | 94 + libs/filesystem/test/msvc/tut6a/tut6a.vcxproj | 94 + libs/filesystem/test/msvc/tut6b/tut6b.vcxproj | 94 + libs/filesystem/test/msvc/tut6c/tut6c.vcxproj | 94 + .../windows_attributes.vcxproj | 94 + libs/filesystem/test/odr1_test.cpp | 24 + libs/filesystem/test/odr2_test.cpp | 18 + libs/filesystem/test/operations_test.cpp | 2302 ++ libs/filesystem/test/operations_unit_test.cpp | 402 + libs/filesystem/test/path_test.cpp | 2033 ++ libs/filesystem/test/path_times.cpp | 103 + libs/filesystem/test/path_unit_test.cpp | 1253 + libs/filesystem/test/quick.cpp | 24 + libs/filesystem/test/relative_test.cpp | 111 + libs/filesystem/test/sample_test.cpp | 63 + libs/filesystem/test/test_codecvt.hpp | 79 + libs/filesystem/test/test_links.html | 1405 + libs/filesystem/test/test_status.html | 56 + libs/filesystem/test/windows_attributes.cpp | 108 + libs/filesystem/tools/backup.bat | 27 + libs/filesystem/tools/exclude.txt | 14 + libs/filesystem/tools/publish.bat | 8 + libs/predef/build.jam | 6 + libs/predef/check/predef.jam | 17 + libs/predef/doc/build.jam | 100 + libs/predef/doc/hardware_simd.qbk | 89 + libs/predef/doc/history.qbk | 85 + libs/predef/doc/predef.qbk | 734 + libs/predef/doc/todo.qbk | 12 + libs/predef/index.html | 14 + libs/predef/meta/libraries.json | 14 + libs/predef/test/build.jam | 80 + libs/predef/test/check_value.cpp | 26 + libs/predef/test/info_as_c.c | 7 + libs/predef/test/info_as_cpp.cpp | 7 + libs/predef/test/info_as_objc.m | 7 + libs/predef/test/info_as_objcpp.mm | 7 + libs/predef/test/macos_endian.c | 21 + libs/predef/test/macos_vs_bsd.c | 19 + libs/predef/test/make.cpp | 92 + libs/predef/test/platform_windows.cpp | 177 + libs/predef/test/predef_info.h | 46 + libs/predef/test/tested_at.cpp | 62 + libs/predef/test/tested_at_outdated.cpp | 18 + libs/predef/test/version.cpp | 83 + libs/predef/test/workaround.cpp | 62 + libs/predef/test/workaround_strict_config.cpp | 17 + libs/predef/tools/check/build.jam | 9 + libs/predef/tools/check/predef.jam | 202 + libs/predef/tools/check/predef_check.h | 98 + libs/predef/tools/check/predef_check_as_c.c | 7 + .../tools/check/predef_check_as_cpp.cpp | 7 + .../predef/tools/check/predef_check_as_objc.m | 7 + .../tools/check/predef_check_as_objcpp.mm | 7 + libs/predef/tools/check/predef_check_cc.h | 19 + .../predef/tools/check/predef_check_cc_as_c.c | 7 + .../tools/check/predef_check_cc_as_cpp.cpp | 7 + .../tools/check/predef_check_cc_as_objc.m | 7 + .../tools/check/predef_check_cc_as_objcpp.mm | 7 + libs/program_options/Jamfile | 11 + libs/program_options/README.md | 37 + libs/program_options/build/Jamfile.v2 | 16 + libs/program_options/ci/build.sh | 19 + libs/program_options/ci/codecov.sh | 43 + libs/program_options/ci/coverity.sh | 42 + libs/program_options/ci/cppcheck.sh | 38 + libs/program_options/ci/mingw.bat | 50 + libs/program_options/doc/Jamfile.v2 | 23 + libs/program_options/doc/acknowledgements.xml | 85 + libs/program_options/doc/alternatives | 43 + libs/program_options/doc/autodoc.xml | 571 + libs/program_options/doc/changes.xml | 150 + libs/program_options/doc/design.xml | 213 + libs/program_options/doc/glossary.dox | 19 + libs/program_options/doc/glossary.xml | 48 + libs/program_options/doc/howto.xml | 499 + libs/program_options/doc/index.html | 14 + libs/program_options/doc/overview.xml | 652 + libs/program_options/doc/post_review_plan.txt | 181 + libs/program_options/doc/program_options.dox | 162 + libs/program_options/doc/program_options.ent | 46 + libs/program_options/doc/program_options.xml | 87 + libs/program_options/doc/questions | 16 + libs/program_options/doc/questions.dox | 12 + libs/program_options/doc/rationale | 15 + libs/program_options/doc/rationale.dox | 95 + libs/program_options/doc/recipes.dox | 91 + .../program_options/doc/requirements-Rozental | 209 + libs/program_options/doc/todo.txt | 238 + libs/program_options/doc/tutorial.xml | 353 + libs/program_options/example/Jamfile.v2 | 14 + .../program_options/example/custom_syntax.cpp | 63 + libs/program_options/example/first.cpp | 51 + .../example/multiple_sources.cfg | 5 + .../example/multiple_sources.cpp | 121 + .../program_options/example/option_groups.cpp | 97 + .../example/options_description.cpp | 86 + libs/program_options/example/real.cpp | 96 + libs/program_options/example/regex.cpp | 101 + .../program_options/example/response_file.cpp | 94 + .../program_options/example/response_file.rsp | 3 + libs/program_options/index.html | 14 + libs/program_options/meta/libraries.json | 15 + libs/program_options/src/cmdline.cpp | 713 + libs/program_options/src/config_file.cpp | 198 + libs/program_options/src/convert.cpp | 161 + .../src/options_description.cpp | 664 + libs/program_options/src/parsers.cpp | 258 + .../src/positional_options.cpp | 53 + libs/program_options/src/split.cpp | 62 + .../src/utf8_codecvt_facet.cpp | 21 + libs/program_options/src/value_semantic.cpp | 428 + libs/program_options/src/variables_map.cpp | 248 + libs/program_options/src/winmain.cpp | 102 + libs/program_options/test/Jamfile.v2 | 44 + libs/program_options/test/cmdline_test.cpp | 652 + libs/program_options/test/config_test.cfg | 9 + libs/program_options/test/exception_test.cpp | 164 + .../test/exception_txt_test.cpp | 693 + libs/program_options/test/minitest.hpp | 25 + libs/program_options/test/optional_test.cpp | 53 + .../test/options_description_test.cpp | 261 + libs/program_options/test/parsers_test.cpp | 327 + .../test/positional_options_test.cpp | 91 + .../test/program_options_size_test.py | 53 + libs/program_options/test/quick.cpp | 49 + libs/program_options/test/required_test.cfg | 1 + libs/program_options/test/required_test.cpp | 98 + libs/program_options/test/split_test.cpp | 189 + libs/program_options/test/test_convert.cpp | 146 + libs/program_options/test/ucs2.txt | Bin 0 -> 2762 bytes libs/program_options/test/unicode_test.cpp | 163 + .../test/unrecognized_test.cpp | 88 + libs/program_options/test/utf8.txt | Bin 0 -> 2624 bytes .../test/variable_map_test.cpp | 290 + libs/program_options/test/winmain.cpp | 74 + libs/program_options/test/winmain.py | 39 + libs/regex/build/Jamfile.v2 | 133 + libs/regex/build/has_icu_test.cpp | 52 + libs/regex/src/c_regex_traits.cpp | 206 + libs/regex/src/cpp_regex_traits.cpp | 117 + libs/regex/src/cregex.cpp | 660 + libs/regex/src/fileiter.cpp | 928 + libs/regex/src/icu.cpp | 511 + libs/regex/src/instances.cpp | 32 + libs/regex/src/internals.hpp | 35 + libs/regex/src/posix_api.cpp | 295 + libs/regex/src/regex.cpp | 229 + libs/regex/src/regex_debug.cpp | 59 + libs/regex/src/regex_raw_buffer.cpp | 72 + libs/regex/src/regex_traits_defaults.cpp | 692 + libs/regex/src/static_mutex.cpp | 183 + libs/regex/src/usinstances.cpp | 81 + libs/regex/src/w32_regex_traits.cpp | 652 + libs/regex/src/wc_regex_traits.cpp | 314 + libs/regex/src/wide_posix_api.cpp | 312 + libs/regex/src/winstances.cpp | 35 + .../test/config_info/regex_config_info.cpp | 73 + libs/system/build/Jamfile.v2 | 25 + libs/system/doc/index.html | 163 + libs/system/doc/reference.html | 834 + libs/system/index.html | 14 + libs/system/meta/libraries.json | 11 + libs/system/src/error_code.cpp | 20 + libs/system/test/Jamfile.v2 | 132 + libs/system/test/before_main_test.cpp | 30 + libs/system/test/config_test.cpp | 65 + libs/system/test/dynamic_link_test.cpp | 55 + libs/system/test/error_code_test.cpp | 331 + libs/system/test/error_code_user_test.cpp | 402 + libs/system/test/header_only_test.cpp | 23 + libs/system/test/initialization_test.cpp | 28 + libs/system/test/msvc/common.props | 22 + .../test/msvc/config_test/config_test.vcxproj | 97 + .../error_code_test/error_code_test.vcxproj | 91 + .../header_only_error_code_test.vcxproj | 151 + .../header_only_test/header_only_test.vcxproj | 86 + .../std_interop_test/std_interop_test.vcxproj | 156 + .../test/msvc/system-dll/system-dll.vcxproj | 90 + libs/system/test/msvc/system.sln | 83 + libs/system/test/quick.cpp | 36 + libs/system/test/single_instance_1.cpp | 29 + libs/system/test/single_instance_2.cpp | 29 + libs/system/test/single_instance_test.cpp | 32 + libs/system/test/std_interop_test.cpp | 370 + libs/system/test/std_mismatch_test.cpp | 65 + libs/system/test/system_error_test.cpp | 106 + libs/system/test/throw_test.cpp | 31 + libs/system/test/throws_assign_fail.cpp | 28 + libs/test/build/CMakeLists.txt | 203 + libs/test/build/Jamfile.v2 | 123 + libs/test/src/compiler_log_formatter.cpp | 18 + libs/test/src/cpp_main.cpp | 19 + libs/test/src/debug.cpp | 24 + libs/test/src/decorator.cpp | 18 + libs/test/src/execution_monitor.cpp | 18 + libs/test/src/framework.cpp | 18 + libs/test/src/junit_log_formatter.cpp | 13 + libs/test/src/plain_report_formatter.cpp | 18 + libs/test/src/progress_monitor.cpp | 18 + libs/test/src/results_collector.cpp | 18 + libs/test/src/results_reporter.cpp | 18 + .../test/src/test_framework_init_observer.cpp | 15 + libs/test/src/test_main.cpp | 15 + libs/test/src/test_tools.cpp | 18 + libs/test/src/test_tree.cpp | 18 + libs/test/src/unit_test_log.cpp | 18 + libs/test/src/unit_test_main.cpp | 18 + libs/test/src/unit_test_monitor.cpp | 18 + libs/test/src/unit_test_parameters.cpp | 18 + libs/test/src/xml_log_formatter.cpp | 18 + libs/test/src/xml_report_formatter.cpp | 18 + libs/thread/build/Jamfile.v2 | 321 + .../build/has_atomic_flag_lockfree_test.cpp | 13 + libs/thread/src/future.cpp | 64 + libs/thread/src/pthread/once.cpp | 83 + libs/thread/src/pthread/once_atomic.cpp | 90 + libs/thread/src/pthread/thread.cpp | 790 + libs/thread/src/tss_null.cpp | 38 + libs/thread/src/win32/thread.cpp | 973 + libs/thread/src/win32/thread_primitives.cpp | 140 + libs/thread/src/win32/tss_dll.cpp | 85 + libs/thread/src/win32/tss_pe.cpp | 337 + libs/timer/build/Jamfile.v2 | 28 + libs/timer/src/auto_timers_construction.cpp | 46 + libs/timer/src/cpu_timer.cpp | 265 + tools/build/CONTRIBUTING.rst | 161 + tools/build/Jamroot.jam | 48 + tools/build/README.rst | 6 + tools/build/boost-build.jam | 8 + tools/build/bootstrap.bat | 50 + tools/build/bootstrap.sh | 120 + tools/build/bootstrap_vms.com | 48 + tools/build/doc/bjam.qbk | 1732 ++ tools/build/doc/boost.png | Bin 0 -> 6308 bytes tools/build/doc/boostbook.css | 706 + tools/build/doc/examples.qbk | 25 + tools/build/doc/history.qbk | 377 + tools/build/doc/images/alert.png | Bin 0 -> 603 bytes tools/build/doc/images/blank.png | Bin 0 -> 374 bytes tools/build/doc/images/callouts/1.png | Bin 0 -> 391 bytes tools/build/doc/images/callouts/1.svg | 15 + tools/build/doc/images/callouts/10.png | Bin 0 -> 485 bytes tools/build/doc/images/callouts/10.svg | 18 + tools/build/doc/images/callouts/11.png | Bin 0 -> 410 bytes tools/build/doc/images/callouts/11.svg | 16 + tools/build/doc/images/callouts/12.png | Bin 0 -> 488 bytes tools/build/doc/images/callouts/12.svg | 18 + tools/build/doc/images/callouts/13.png | Bin 0 -> 509 bytes tools/build/doc/images/callouts/13.svg | 20 + tools/build/doc/images/callouts/14.png | Bin 0 -> 499 bytes tools/build/doc/images/callouts/14.svg | 17 + tools/build/doc/images/callouts/15.png | Bin 0 -> 507 bytes tools/build/doc/images/callouts/15.svg | 19 + tools/build/doc/images/callouts/16.svg | 20 + tools/build/doc/images/callouts/17.svg | 17 + tools/build/doc/images/callouts/18.svg | 21 + tools/build/doc/images/callouts/19.svg | 20 + tools/build/doc/images/callouts/2.png | Bin 0 -> 446 bytes tools/build/doc/images/callouts/2.svg | 17 + tools/build/doc/images/callouts/20.svg | 20 + tools/build/doc/images/callouts/21.svg | 18 + tools/build/doc/images/callouts/22.svg | 20 + tools/build/doc/images/callouts/23.svg | 22 + tools/build/doc/images/callouts/24.svg | 19 + tools/build/doc/images/callouts/25.svg | 21 + tools/build/doc/images/callouts/26.svg | 22 + tools/build/doc/images/callouts/27.svg | 19 + tools/build/doc/images/callouts/28.svg | 23 + tools/build/doc/images/callouts/29.svg | 22 + tools/build/doc/images/callouts/3.png | Bin 0 -> 431 bytes tools/build/doc/images/callouts/3.svg | 19 + tools/build/doc/images/callouts/30.svg | 22 + tools/build/doc/images/callouts/4.png | Bin 0 -> 441 bytes tools/build/doc/images/callouts/4.svg | 16 + tools/build/doc/images/callouts/5.png | Bin 0 -> 423 bytes tools/build/doc/images/callouts/5.svg | 18 + tools/build/doc/images/callouts/6.png | Bin 0 -> 431 bytes tools/build/doc/images/callouts/6.svg | 19 + tools/build/doc/images/callouts/7.png | Bin 0 -> 397 bytes tools/build/doc/images/callouts/7.svg | 16 + tools/build/doc/images/callouts/8.png | Bin 0 -> 434 bytes tools/build/doc/images/callouts/8.svg | 20 + tools/build/doc/images/callouts/9.png | Bin 0 -> 420 bytes tools/build/doc/images/callouts/9.svg | 19 + tools/build/doc/images/caution.png | Bin 0 -> 1250 bytes tools/build/doc/images/caution.svg | 68 + tools/build/doc/images/draft.png | Bin 0 -> 17454 bytes tools/build/doc/images/home.png | Bin 0 -> 358 bytes tools/build/doc/images/home.svg | 26 + tools/build/doc/images/important.png | Bin 0 -> 722 bytes tools/build/doc/images/important.svg | 25 + tools/build/doc/images/next.png | Bin 0 -> 336 bytes tools/build/doc/images/next.svg | 19 + tools/build/doc/images/next_disabled.png | Bin 0 -> 1110 bytes tools/build/doc/images/note.png | Bin 0 -> 490 bytes tools/build/doc/images/note.svg | 33 + tools/build/doc/images/prev.png | Bin 0 -> 334 bytes tools/build/doc/images/prev.svg | 19 + tools/build/doc/images/prev_disabled.png | Bin 0 -> 1109 bytes tools/build/doc/images/smiley.png | Bin 0 -> 867 bytes tools/build/doc/images/tip.png | Bin 0 -> 449 bytes tools/build/doc/images/tip.svg | 84 + tools/build/doc/images/toc-blank.png | Bin 0 -> 318 bytes tools/build/doc/images/toc-minus.png | Bin 0 -> 259 bytes tools/build/doc/images/toc-plus.png | Bin 0 -> 264 bytes tools/build/doc/images/up.png | Bin 0 -> 370 bytes tools/build/doc/images/up.svg | 19 + tools/build/doc/images/up_disabled.png | Bin 0 -> 1115 bytes tools/build/doc/images/warning.png | Bin 0 -> 1241 bytes tools/build/doc/images/warning.svg | 23 + tools/build/doc/jamfile.jam | 61 + tools/build/doc/src/abstract-target.xml | 126 + tools/build/doc/src/architecture.xml | 668 + tools/build/doc/src/basic-target.xml | 96 + tools/build/doc/src/debug.xml | 120 + tools/build/doc/src/extending.xml | 1216 + tools/build/doc/src/faq.xml | 490 + tools/build/doc/src/fragments.xml | 59 + tools/build/doc/src/howto.xml | 44 + tools/build/doc/src/install.xml | 150 + tools/build/doc/src/main-target.xml | 59 + tools/build/doc/src/overview.xml | 1778 ++ tools/build/doc/src/path.xml | 249 + tools/build/doc/src/project-target.xml | 144 + tools/build/doc/src/property-set.xml | 128 + tools/build/doc/src/recipes.xml | 11 + tools/build/doc/src/reference.xml | 3053 ++ tools/build/doc/src/regex.xml | 170 + tools/build/doc/src/sequence.xml | 135 + tools/build/doc/src/standalone.xml | 42 + tools/build/doc/src/tasks.xml | 842 + tools/build/doc/src/tools.adoc | 14 + tools/build/doc/src/tutorial.xml | 682 + tools/build/doc/src/type.xml | 236 + tools/build/doc/src/typed-target.xml | 106 + tools/build/doc/src/userman.xml | 29 + tools/build/example/asciidoctor/example.adoc | 3 + .../example/asciidoctor/example_manpage.adoc | 38 + tools/build/example/asciidoctor/jamroot.jam | 11 + tools/build/example/boost-build.jam | 6 + tools/build/example/built_tool/Jamroot.jam | 8 + .../build/example/built_tool/core/Jamfile.jam | 39 + tools/build/example/built_tool/core/a.td | 0 tools/build/example/built_tool/core/core.cpp | 5 + tools/build/example/built_tool/readme.txt | 5 + .../example/built_tool/tblgen/Jamfile.jam | 4 + .../example/built_tool/tblgen/tblgen.cpp | 9 + .../example/complex-testing/compile-fail.cpp | 17 + tools/build/example/complex-testing/fail.cpp | 17 + .../build/example/complex-testing/jamroot.jam | 15 + tools/build/example/complex-testing/post.cpp | 17 + .../build/example/complex-testing/success.cpp | 17 + .../example/customization/class.verbatim | 7 + tools/build/example/customization/codegen.cpp | 36 + .../example/customization/inline_file.py | 44 + tools/build/example/customization/jamroot.jam | 9 + tools/build/example/customization/readme.txt | 11 + tools/build/example/customization/t1.verbatim | 2 + tools/build/example/customization/t2.verbatim | 0 .../example/customization/usage.verbatim | 5 + .../build/example/customization/verbatim.jam | 61 + tools/build/example/customization/verbatim.py | 47 + tools/build/example/generate/README.txt | 11 + tools/build/example/generate/a.cpp | 10 + tools/build/example/generate/gen.jam | 26 + tools/build/example/generate/gen.py | 16 + tools/build/example/generate/jamroot.jam | 9 + tools/build/example/generator/README.txt | 6 + tools/build/example/generator/foo.gci | 10 + tools/build/example/generator/jamroot.jam | 6 + tools/build/example/generator/soap.jam | 86 + tools/build/example/gettext/jamfile.jam | 26 + tools/build/example/gettext/jamroot.jam | 6 + tools/build/example/gettext/main.cpp | 28 + tools/build/example/gettext/readme.txt | 24 + tools/build/example/gettext/russian.po | 21 + tools/build/example/hello/hello.cpp | 16 + tools/build/example/hello/jamroot.jam | 3 + tools/build/example/hello/readme.qbk | 45 + tools/build/example/libraries/app/app.cpp | 15 + tools/build/example/libraries/app/jamfile.jam | 9 + tools/build/example/libraries/jamroot.jam | 4 + .../build/example/libraries/util/foo/bar.cpp | 13 + .../example/libraries/util/foo/include/lib1.h | 10 + .../example/libraries/util/foo/jamfile.jam | 9 + tools/build/example/make/foo.py | 2 + tools/build/example/make/jamroot.jam | 22 + tools/build/example/make/main_cpp.pro | 1 + tools/build/example/make/readme.txt | 7 + tools/build/example/pch/include/pch.hpp | 19 + tools/build/example/pch/jamroot.jam | 29 + .../build/example/pch/source/hello_world.cpp | 15 + .../build/example/python_modules/jamroot.jam | 8 + .../example/python_modules/python_helpers.jam | 15 + .../example/python_modules/python_helpers.py | 18 + tools/build/example/python_modules/readme.txt | 16 + tools/build/example/qt/README.txt | 20 + tools/build/example/qt/qt3/hello/canvas.cpp | 73 + tools/build/example/qt/qt3/hello/canvas.h | 35 + tools/build/example/qt/qt3/hello/jamroot.jam | 13 + tools/build/example/qt/qt3/hello/main.cpp | 36 + .../example/qt/qt3/moccable-cpp/jamroot.jam | 11 + .../example/qt/qt3/moccable-cpp/main.cpp | 41 + .../example/qt/qt3/uic/hello_world_widget.ui | 58 + tools/build/example/qt/qt3/uic/jamroot.jam | 15 + tools/build/example/qt/qt3/uic/main.cpp | 18 + tools/build/example/qt/qt4/hello/arrow.cpp | 158 + tools/build/example/qt/qt4/hello/arrow.h | 30 + tools/build/example/qt/qt4/hello/jamroot.jam | 14 + tools/build/example/qt/qt4/hello/main.cpp | 27 + .../example/qt/qt4/moccable-cpp/jamroot.jam | 18 + .../example/qt/qt4/moccable-cpp/main.cpp | 39 + .../example/qt/qt4/uic/hello_world_widget.ui | 55 + tools/build/example/qt/qt4/uic/jamroot.jam | 18 + tools/build/example/qt/qt4/uic/main.cpp | 23 + tools/build/example/sass/importing.scss | 3 + tools/build/example/sass/include/foobar.scss | 3 + tools/build/example/sass/jamroot.jam | 15 + tools/build/example/sass/singleton.sass | 12 + tools/build/example/sass/singleton.scss | 11 + tools/build/example/site-config.jam | 4 + tools/build/example/testing/compile-fail.cpp | 17 + tools/build/example/testing/fail.cpp | 17 + tools/build/example/testing/jamroot.jam | 10 + tools/build/example/testing/success.cpp | 17 + tools/build/example/time/hello.cpp | 16 + tools/build/example/time/jamroot.jam | 16 + tools/build/example/time/readme.qbk | 47 + tools/build/example/try_compile/Jamroot.jam | 29 + tools/build/example/try_compile/foo.cpp | 6 + tools/build/example/try_compile/main.cpp | 8 + tools/build/example/user-config.jam | 92 + tools/build/example/variant/a.cpp | 7 + tools/build/example/variant/jamfile.jam | 11 + tools/build/example/variant/jamroot.jam | 12 + tools/build/example/variant/libs/jamfile.jam | 8 + tools/build/example/variant/libs/l.cpp | 9 + tools/build/example/variant/readme.qbk | 94 + tools/build/index.html | 100 + tools/build/notes/README.txt | 8 + tools/build/notes/build_dir_option.txt | 77 + tools/build/notes/changes.txt | 317 + tools/build/notes/relative_source_paths.txt | 76 + tools/build/notes/release_procedure.txt | 83 + tools/build/scripts/build-docs.sh | 34 + tools/build/scripts/nightly.sh | 30 + tools/build/scripts/roll.sh | 64 + tools/build/scripts/to_merge.sh | 16 + tools/build/src/__init__.py | 0 tools/build/src/bootstrap.jam | 18 + tools/build/src/build-system.jam | 1079 + tools/build/src/build/__init__.py | 0 tools/build/src/build/ac.jam | 324 + tools/build/src/build/alias.jam | 78 + tools/build/src/build/alias.py | 75 + tools/build/src/build/build-request.jam | 400 + tools/build/src/build/build_request.py | 222 + tools/build/src/build/config-cache.jam | 78 + tools/build/src/build/configure.jam | 592 + tools/build/src/build/configure.py | 176 + tools/build/src/build/engine.py | 246 + tools/build/src/build/errors.py | 135 + tools/build/src/build/feature.jam | 1435 + tools/build/src/build/feature.py | 914 + tools/build/src/build/generators.jam | 1447 + tools/build/src/build/generators.py | 1209 + tools/build/src/build/project.jam | 1287 + tools/build/src/build/project.py | 1285 + tools/build/src/build/property-set.jam | 591 + tools/build/src/build/property.jam | 973 + tools/build/src/build/property.py | 750 + tools/build/src/build/property_set.py | 498 + tools/build/src/build/readme.txt | 11 + tools/build/src/build/scanner.jam | 163 + tools/build/src/build/scanner.py | 167 + tools/build/src/build/targets.jam | 1791 ++ tools/build/src/build/targets.py | 1523 + tools/build/src/build/toolset.jam | 703 + tools/build/src/build/toolset.py | 417 + tools/build/src/build/type.jam | 404 + tools/build/src/build/type.py | 381 + tools/build/src/build/version.jam | 165 + tools/build/src/build/version.py | 38 + tools/build/src/build/virtual-target.jam | 1393 + tools/build/src/build/virtual_target.py | 1175 + tools/build/src/build_system.py | 682 + tools/build/src/contrib/__init__.py | 0 tools/build/src/contrib/boost.jam | 308 + tools/build/src/contrib/boost.py | 280 + tools/build/src/contrib/modular.jam | 288 + tools/build/src/contrib/tntnet.jam | 208 + tools/build/src/contrib/wxFormBuilder.jam | 195 + tools/build/src/engine/Jambase | 189 + tools/build/src/engine/boehm_gc/AmigaOS.c | 623 + tools/build/src/engine/boehm_gc/BCC_MAKEFILE | 87 + tools/build/src/engine/boehm_gc/ChangeLog | 363 + tools/build/src/engine/boehm_gc/EMX_MAKEFILE | 140 + tools/build/src/engine/boehm_gc/MacOS.c | 156 + .../src/engine/boehm_gc/MacProjects.sit.hqx | 886 + .../boehm_gc/Mac_files/MacOS_Test_config.h | 91 + .../engine/boehm_gc/Mac_files/MacOS_config.h | 89 + .../src/engine/boehm_gc/Mac_files/dataend.c | 9 + .../src/engine/boehm_gc/Mac_files/datastart.c | 9 + tools/build/src/engine/boehm_gc/Makefile.DLLs | 107 + tools/build/src/engine/boehm_gc/Makefile.am | 206 + .../build/src/engine/boehm_gc/Makefile.direct | 737 + tools/build/src/engine/boehm_gc/Makefile.dj | 428 + tools/build/src/engine/boehm_gc/Makefile.in | 1405 + tools/build/src/engine/boehm_gc/NT_MAKEFILE | 60 + .../boehm_gc/NT_STATIC_THREADS_MAKEFILE | 74 + .../src/engine/boehm_gc/NT_THREADS_MAKEFILE | 2220 ++ .../boehm_gc/NT_X64_STATIC_THREADS_MAKEFILE | 74 + tools/build/src/engine/boehm_gc/OS2_MAKEFILE | 45 + tools/build/src/engine/boehm_gc/PCR-Makefile | 68 + tools/build/src/engine/boehm_gc/README.QUICK | 88 + .../build/src/engine/boehm_gc/SMakefile.amiga | 177 + tools/build/src/engine/boehm_gc/WCC_MAKEFILE | 196 + tools/build/src/engine/boehm_gc/acinclude.m4 | 49 + tools/build/src/engine/boehm_gc/aclocal.m4 | 929 + .../build/src/engine/boehm_gc/add_gc_prefix.c | 20 + tools/build/src/engine/boehm_gc/allchblk.c | 850 + tools/build/src/engine/boehm_gc/alloc.c | 1023 + .../src/engine/boehm_gc/alpha_mach_dep.S | 86 + tools/build/src/engine/boehm_gc/backgraph.c | 469 + tools/build/src/engine/boehm_gc/bdw-gc.pc | 10 + tools/build/src/engine/boehm_gc/bdw-gc.pc.in | 10 + tools/build/src/engine/boehm_gc/blacklst.c | 285 + tools/build/src/engine/boehm_gc/callprocs | 4 + tools/build/src/engine/boehm_gc/checksums.c | 196 + tools/build/src/engine/boehm_gc/compile | 142 + tools/build/src/engine/boehm_gc/config.guess | 1500 + tools/build/src/engine/boehm_gc/config.sub | 1608 ++ tools/build/src/engine/boehm_gc/configure | 23503 ++++++++++++++++ tools/build/src/engine/boehm_gc/configure.ac | 658 + .../build/src/engine/boehm_gc/configure.host | 61 + .../engine/boehm_gc/configure_atomic_ops.sh | 4 + tools/build/src/engine/boehm_gc/cord/cord.am | 17 + .../build/src/engine/boehm_gc/cord/cordbscs.c | 919 + .../build/src/engine/boehm_gc/cord/cordprnt.c | 396 + .../build/src/engine/boehm_gc/cord/cordtest.c | 235 + .../build/src/engine/boehm_gc/cord/cordxtra.c | 621 + tools/build/src/engine/boehm_gc/cord/de.c | 603 + .../build/src/engine/boehm_gc/cord/de_cmds.h | 33 + .../build/src/engine/boehm_gc/cord/de_win.ICO | Bin 0 -> 766 bytes .../build/src/engine/boehm_gc/cord/de_win.RC | 78 + tools/build/src/engine/boehm_gc/cord/de_win.c | 370 + tools/build/src/engine/boehm_gc/cord/de_win.h | 103 + .../src/engine/boehm_gc/darwin_stop_world.c | 599 + tools/build/src/engine/boehm_gc/dbg_mlc.c | 1053 + tools/build/src/engine/boehm_gc/depcomp | 436 + tools/build/src/engine/boehm_gc/digimars.mak | 90 + tools/build/src/engine/boehm_gc/doc/README | 548 + .../src/engine/boehm_gc/doc/README.DGUX386 | 215 + .../build/src/engine/boehm_gc/doc/README.Mac | 390 + .../src/engine/boehm_gc/doc/README.MacOSX | 1 + .../build/src/engine/boehm_gc/doc/README.OS2 | 6 + .../src/engine/boehm_gc/doc/README.amiga | 322 + .../src/engine/boehm_gc/doc/README.arm.cross | 68 + .../src/engine/boehm_gc/doc/README.autoconf | 59 + .../src/engine/boehm_gc/doc/README.changes | 2594 ++ .../engine/boehm_gc/doc/README.contributors | 57 + .../src/engine/boehm_gc/doc/README.cords | 53 + .../src/engine/boehm_gc/doc/README.darwin | 142 + tools/build/src/engine/boehm_gc/doc/README.dj | 12 + .../engine/boehm_gc/doc/README.environment | 135 + .../src/engine/boehm_gc/doc/README.ews4800 | 81 + tools/build/src/engine/boehm_gc/doc/README.hp | 18 + .../src/engine/boehm_gc/doc/README.linux | 131 + .../src/engine/boehm_gc/doc/README.macros | 82 + .../src/engine/boehm_gc/doc/README.rs6000 | 9 + .../build/src/engine/boehm_gc/doc/README.sgi | 41 + .../src/engine/boehm_gc/doc/README.solaris2 | 64 + .../build/src/engine/boehm_gc/doc/README.uts | 2 + .../src/engine/boehm_gc/doc/README.win32 | 221 + .../src/engine/boehm_gc/doc/README.win64 | 17 + .../src/engine/boehm_gc/doc/barrett_diagram | 106 + .../src/engine/boehm_gc/doc/debugging.html | 306 + tools/build/src/engine/boehm_gc/doc/doc.am | 55 + tools/build/src/engine/boehm_gc/doc/gc.man | 97 + .../src/engine/boehm_gc/doc/gcdescr.html | 621 + .../src/engine/boehm_gc/doc/gcinterface.html | 278 + tools/build/src/engine/boehm_gc/doc/leak.html | 200 + .../src/engine/boehm_gc/doc/overview.html | 446 + .../src/engine/boehm_gc/doc/porting.html | 333 + .../build/src/engine/boehm_gc/doc/scale.html | 210 + .../engine/boehm_gc/doc/simple_example.html | 202 + tools/build/src/engine/boehm_gc/doc/tree.html | 199 + tools/build/src/engine/boehm_gc/dyn_load.c | 1195 + tools/build/src/engine/boehm_gc/finalize.c | 869 + tools/build/src/engine/boehm_gc/gc.mak | 2220 ++ tools/build/src/engine/boehm_gc/gc_cpp.cc | 67 + tools/build/src/engine/boehm_gc/gc_cpp.cpp | 2 + tools/build/src/engine/boehm_gc/gc_dlopen.c | 89 + tools/build/src/engine/boehm_gc/gcj_mlc.c | 245 + tools/build/src/engine/boehm_gc/gcname.c | 13 + tools/build/src/engine/boehm_gc/headers.c | 394 + .../src/engine/boehm_gc/hpux_test_and_clear.s | 21 + .../engine/boehm_gc/ia64_save_regs_in_stack.s | 12 + tools/build/src/engine/boehm_gc/if_mach.c | 25 + .../build/src/engine/boehm_gc/if_not_there.c | 38 + .../build/src/engine/boehm_gc/include/cord.h | 327 + tools/build/src/engine/boehm_gc/include/ec.h | 70 + tools/build/src/engine/boehm_gc/include/gc.h | 1139 + .../engine/boehm_gc/include/gc_allocator.h | 245 + .../boehm_gc/include/gc_amiga_redirects.h | 30 + .../src/engine/boehm_gc/include/gc_backptr.h | 65 + .../boehm_gc/include/gc_config_macros.h | 180 + .../src/engine/boehm_gc/include/gc_cpp.h | 374 + .../src/engine/boehm_gc/include/gc_gcj.h | 94 + .../src/engine/boehm_gc/include/gc_inline.h | 128 + .../src/engine/boehm_gc/include/gc_mark.h | 201 + .../boehm_gc/include/gc_pthread_redirects.h | 54 + .../src/engine/boehm_gc/include/gc_tiny_fl.h | 89 + .../src/engine/boehm_gc/include/gc_typed.h | 111 + .../src/engine/boehm_gc/include/include.am | 54 + .../src/engine/boehm_gc/include/javaxfc.h | 21 + .../engine/boehm_gc/include/leak_detector.h | 9 + .../engine/boehm_gc/include/new_gc_alloc.h | 484 + .../boehm_gc/include/private/cord_pos.h | 118 + .../include/private/darwin_semaphore.h | 68 + .../include/private/darwin_stop_world.h | 22 + .../engine/boehm_gc/include/private/dbg_mlc.h | 178 + .../engine/boehm_gc/include/private/gc_hdrs.h | 206 + .../boehm_gc/include/private/gc_locks.h | 210 + .../boehm_gc/include/private/gc_pmark.h | 494 + .../engine/boehm_gc/include/private/gc_priv.h | 2040 ++ .../boehm_gc/include/private/gcconfig.h | 2350 ++ .../boehm_gc/include/private/msvc_dbg.h | 69 + .../include/private/pthread_stop_world.h | 11 + .../include/private/pthread_support.h | 84 + .../boehm_gc/include/private/specific.h | 96 + .../include/private/thread_local_alloc.h | 152 + .../src/engine/boehm_gc/include/weakpointer.h | 221 + tools/build/src/engine/boehm_gc/install-sh | 251 + tools/build/src/engine/boehm_gc/libtool.m4 | 6397 +++++ tools/build/src/engine/boehm_gc/ltmain.sh | 6863 +++++ tools/build/src/engine/boehm_gc/mach_dep.c | 242 + tools/build/src/engine/boehm_gc/malloc.c | 510 + tools/build/src/engine/boehm_gc/mallocx.c | 574 + tools/build/src/engine/boehm_gc/mark.c | 1866 ++ tools/build/src/engine/boehm_gc/mark_rts.c | 617 + .../src/engine/boehm_gc/mips_sgi_mach_dep.s | 46 + .../engine/boehm_gc/mips_ultrix_mach_dep.s | 26 + tools/build/src/engine/boehm_gc/misc.c | 1177 + tools/build/src/engine/boehm_gc/missing | 336 + tools/build/src/engine/boehm_gc/mkinstalldirs | 101 + tools/build/src/engine/boehm_gc/msvc_dbg.c | 348 + tools/build/src/engine/boehm_gc/new_hblk.c | 201 + tools/build/src/engine/boehm_gc/obj_map.c | 90 + tools/build/src/engine/boehm_gc/os_dep.c | 4344 +++ .../build/src/engine/boehm_gc/pcr_interface.c | 179 + .../src/engine/boehm_gc/pthread_stop_world.c | 537 + .../src/engine/boehm_gc/pthread_support.c | 1495 + tools/build/src/engine/boehm_gc/ptr_chck.c | 283 + tools/build/src/engine/boehm_gc/real_malloc.c | 31 + tools/build/src/engine/boehm_gc/reclaim.c | 608 + .../src/engine/boehm_gc/rs6000_mach_dep.s | 114 + tools/build/src/engine/boehm_gc/setjmp_t.c | 135 + .../src/engine/boehm_gc/sparc_mach_dep.S | 70 + .../engine/boehm_gc/sparc_netbsd_mach_dep.s | 34 + .../engine/boehm_gc/sparc_sunos4_mach_dep.s | 38 + tools/build/src/engine/boehm_gc/specific.c | 165 + tools/build/src/engine/boehm_gc/stubborn.c | 58 + .../src/engine/boehm_gc/tests/leak_test.c | 25 + .../build/src/engine/boehm_gc/tests/middle.c | 26 + tools/build/src/engine/boehm_gc/tests/test.c | 1634 ++ .../src/engine/boehm_gc/tests/test_cpp.cc | 292 + .../build/src/engine/boehm_gc/tests/tests.am | 57 + .../engine/boehm_gc/tests/thread_leak_test.c | 45 + .../src/engine/boehm_gc/thread_local_alloc.c | 310 + tools/build/src/engine/boehm_gc/threadlibs.c | 63 + tools/build/src/engine/boehm_gc/typd_mlc.c | 722 + tools/build/src/engine/boehm_gc/version.h | 30 + .../build/src/engine/boehm_gc/win32_threads.c | 1570 ++ tools/build/src/engine/boost-jam.spec | 64 + tools/build/src/engine/boost-no-inspect | 1 + tools/build/src/engine/build.bat | 283 + tools/build/src/engine/build.jam | 1099 + tools/build/src/engine/build.sh | 340 + tools/build/src/engine/build_vms.com | 153 + tools/build/src/engine/builtins.c | 2715 ++ tools/build/src/engine/builtins.h | 73 + tools/build/src/engine/bump_version.py | 98 + tools/build/src/engine/class.c | 192 + tools/build/src/engine/class.h | 14 + tools/build/src/engine/command.c | 121 + tools/build/src/engine/command.h | 100 + tools/build/src/engine/compile.c | 233 + tools/build/src/engine/compile.h | 59 + tools/build/src/engine/config_toolset.bat | 239 + tools/build/src/engine/constants.c | 192 + tools/build/src/engine/constants.h | 75 + tools/build/src/engine/cwd.c | 88 + tools/build/src/engine/cwd.h | 35 + tools/build/src/engine/debian/changelog | 72 + tools/build/src/engine/debian/control | 16 + tools/build/src/engine/debian/copyright | 25 + tools/build/src/engine/debian/jam.man.sgml | 236 + tools/build/src/engine/debian/rules | 73 + tools/build/src/engine/debug.c | 158 + tools/build/src/engine/debug.h | 62 + tools/build/src/engine/debugger.c | 2766 ++ tools/build/src/engine/debugger.h | 63 + tools/build/src/engine/execcmd.c | 122 + tools/build/src/engine/execcmd.h | 114 + tools/build/src/engine/execnt.c | 1382 + tools/build/src/engine/execunix.c | 611 + tools/build/src/engine/execvms.c | 419 + tools/build/src/engine/filent.c | 518 + tools/build/src/engine/filesys.c | 713 + tools/build/src/engine/filesys.h | 110 + tools/build/src/engine/fileunix.c | 527 + tools/build/src/engine/filevms.c | 440 + tools/build/src/engine/frames.c | 29 + tools/build/src/engine/frames.h | 45 + tools/build/src/engine/function.c | 5344 ++++ tools/build/src/engine/function.h | 48 + tools/build/src/engine/glob.c | 152 + tools/build/src/engine/guess_toolset.bat | 183 + tools/build/src/engine/hash.c | 388 + tools/build/src/engine/hash.h | 79 + tools/build/src/engine/hcache.c | 520 + tools/build/src/engine/hcache.h | 19 + tools/build/src/engine/hdrmacro.c | 140 + tools/build/src/engine/hdrmacro.h | 21 + tools/build/src/engine/headers.c | 198 + tools/build/src/engine/headers.h | 25 + tools/build/src/engine/jam.c | 768 + tools/build/src/engine/jam.h | 517 + tools/build/src/engine/jambase.c | 142 + tools/build/src/engine/jambase.h | 15 + tools/build/src/engine/jamgram.c | 2446 ++ tools/build/src/engine/jamgram.h | 160 + tools/build/src/engine/jamgram.y | 385 + tools/build/src/engine/jamgram.yy | 339 + tools/build/src/engine/jamgramtab.h | 46 + tools/build/src/engine/lists.c | 476 + tools/build/src/engine/lists.h | 113 + tools/build/src/engine/make.c | 941 + tools/build/src/engine/make.h | 44 + tools/build/src/engine/make1.c | 1535 + tools/build/src/engine/md5.c | 381 + tools/build/src/engine/md5.h | 91 + tools/build/src/engine/mem.c | 75 + tools/build/src/engine/mem.h | 133 + tools/build/src/engine/mkjambase.c | 123 + tools/build/src/engine/modules.c | 431 + tools/build/src/engine/modules.h | 52 + tools/build/src/engine/modules/order.c | 160 + tools/build/src/engine/modules/path.c | 25 + tools/build/src/engine/modules/property-set.c | 331 + tools/build/src/engine/modules/readme.txt | 3 + tools/build/src/engine/modules/regex.c | 220 + tools/build/src/engine/modules/sequence.c | 97 + tools/build/src/engine/modules/set.c | 43 + tools/build/src/engine/native.c | 34 + tools/build/src/engine/native.h | 34 + tools/build/src/engine/object.c | 397 + tools/build/src/engine/object.h | 44 + tools/build/src/engine/option.c | 94 + tools/build/src/engine/option.h | 23 + tools/build/src/engine/output.c | 159 + tools/build/src/engine/output.h | 41 + tools/build/src/engine/parse.c | 148 + tools/build/src/engine/parse.h | 80 + tools/build/src/engine/patchlevel.h | 17 + tools/build/src/engine/pathnt.c | 409 + tools/build/src/engine/pathsys.c | 302 + tools/build/src/engine/pathsys.h | 86 + tools/build/src/engine/pathunix.c | 86 + tools/build/src/engine/pathvms.c | 254 + tools/build/src/engine/regexp.c | 1330 + tools/build/src/engine/regexp.h | 34 + tools/build/src/engine/rules.c | 739 + tools/build/src/engine/rules.h | 273 + tools/build/src/engine/scan.c | 744 + tools/build/src/engine/scan.h | 70 + tools/build/src/engine/search.c | 275 + tools/build/src/engine/search.h | 22 + tools/build/src/engine/strings.c | 251 + tools/build/src/engine/strings.h | 37 + tools/build/src/engine/subst.c | 116 + tools/build/src/engine/subst.h | 14 + tools/build/src/engine/timestamp.c | 281 + tools/build/src/engine/timestamp.h | 47 + tools/build/src/engine/variable.c | 393 + tools/build/src/engine/variable.h | 34 + .../src/engine/vswhere_usability_wrapper.cmd | 33 + tools/build/src/engine/w32_getreg.c | 201 + tools/build/src/engine/yyacc.c | 268 + tools/build/src/exceptions.py | 55 + tools/build/src/kernel/boost-build.jam | 5 + tools/build/src/kernel/bootstrap.jam | 265 + tools/build/src/kernel/bootstrap.py | 25 + tools/build/src/kernel/class.jam | 420 + tools/build/src/kernel/errors.jam | 287 + tools/build/src/kernel/modules.jam | 365 + tools/build/src/manager.py | 110 + tools/build/src/options/help.jam | 222 + tools/build/src/tools/__init__.py | 0 tools/build/src/tools/acc.jam | 118 + tools/build/src/tools/asciidoctor.jam | 212 + tools/build/src/tools/auto-index.jam | 204 + tools/build/src/tools/bison.jam | 26 + tools/build/src/tools/boostbook-config.jam | 13 + tools/build/src/tools/boostbook.jam | 740 + tools/build/src/tools/borland.jam | 221 + tools/build/src/tools/builtin.jam | 96 + tools/build/src/tools/builtin.py | 794 + tools/build/src/tools/bzip2.jam | 279 + tools/build/src/tools/cast.jam | 91 + tools/build/src/tools/cast.py | 76 + tools/build/src/tools/clang-darwin.jam | 173 + tools/build/src/tools/clang-linux.jam | 174 + tools/build/src/tools/clang-vxworks.jam | 128 + tools/build/src/tools/clang-win.jam | 175 + tools/build/src/tools/clang.jam | 60 + tools/build/src/tools/common.jam | 1076 + tools/build/src/tools/common.py | 858 + tools/build/src/tools/como-linux.jam | 103 + tools/build/src/tools/como-win.jam | 117 + tools/build/src/tools/como.jam | 29 + tools/build/src/tools/convert.jam | 62 + tools/build/src/tools/cray.jam | 125 + tools/build/src/tools/cw-config.jam | 34 + tools/build/src/tools/cw.jam | 246 + tools/build/src/tools/cygwin.jam | 12 + tools/build/src/tools/darwin.jam | 620 + tools/build/src/tools/darwin.py | 57 + tools/build/src/tools/diab.jam | 131 + tools/build/src/tools/dmc.jam | 134 + tools/build/src/tools/docutils.jam | 125 + tools/build/src/tools/doxproc.py | 859 + tools/build/src/tools/doxygen-config.jam | 11 + tools/build/src/tools/doxygen.jam | 782 + .../doxygen/windows-paths-check.doxyfile | 3 + .../src/tools/doxygen/windows-paths-check.hpp | 0 tools/build/src/tools/emscripten.jam | 113 + .../src/tools/features/__init_features__.jam | 23 + .../tools/features/address-model-feature.jam | 13 + .../src/tools/features/allow-feature.jam | 14 + .../tools/features/architecture-feature.jam | 40 + .../tools/features/archiveflags-feature.jam | 12 + .../src/tools/features/asmflags-feature.jam | 12 + .../src/tools/features/build-feature.jam | 12 + .../src/tools/features/cflags-feature.jam | 12 + .../tools/features/conditional-feature.jam | 12 + .../features/cxx-template-depth-feature.jam | 31 + .../src/tools/features/cxxabi-feature.jam | 12 + .../src/tools/features/cxxflags-feature.jam | 12 + .../src/tools/features/cxxstd-feature.jam | 35 + .../src/tools/features/debug-feature.jam | 16 + .../src/tools/features/define-feature.jam | 16 + .../src/tools/features/dependency-feature.jam | 32 + .../build/src/tools/features/dll-feature.jam | 33 + .../src/tools/features/exception-feature.jam | 22 + .../src/tools/features/fflags-feature.jam | 12 + .../build/src/tools/features/file-feature.jam | 12 + .../src/tools/features/find-lib-feature.jam | 20 + .../src/tools/features/flags-feature.jam | 12 + .../src/tools/features/include-feature.jam | 13 + .../features/instruction-set-feature.jam | 47 + .../src/tools/features/internal-feature.jam | 19 + .../src/tools/features/library-feature.jam | 12 + .../build/src/tools/features/link-feature.jam | 12 + .../src/tools/features/linkflags-feature.jam | 12 + .../src/tools/features/location-feature.jam | 12 + .../features/location-prefix-feature.jam | 12 + .../build/src/tools/features/name-feature.jam | 12 + .../src/tools/features/objcflags-feature.jam | 16 + .../tools/features/optimization-feature.jam | 20 + tools/build/src/tools/features/os-feature.jam | 78 + .../src/tools/features/relevant-feature.jam | 10 + .../build/src/tools/features/rtti-feature.jam | 12 + .../src/tools/features/runtime-feature.jam | 16 + .../src/tools/features/search-feature.jam | 13 + .../src/tools/features/source-feature.jam | 12 + .../src/tools/features/stdlib-feature.jam | 12 + .../src/tools/features/strip-feature.jam | 19 + .../build/src/tools/features/tag-feature.jam | 12 + .../src/tools/features/threadapi-feature.jam | 29 + .../src/tools/features/threading-feature.jam | 12 + .../src/tools/features/toolset-feature.jam | 12 + .../tools/features/user-interface-feature.jam | 13 + .../src/tools/features/variant-feature.jam | 82 + .../src/tools/features/version-feature.jam | 12 + .../src/tools/features/warnings-feature.jam | 21 + tools/build/src/tools/flags.jam | 152 + tools/build/src/tools/fop.jam | 69 + tools/build/src/tools/fortran.jam | 55 + tools/build/src/tools/gcc.jam | 1191 + tools/build/src/tools/gcc.py | 866 + tools/build/src/tools/generate.jam | 111 + .../tools/generators/__init_generators__.jam | 23 + .../tools/generators/archive-generator.jam | 74 + .../generators/c-compiling-generator.jam | 70 + .../src/tools/generators/dummy-generator.jam | 20 + .../src/tools/generators/lib-generator.jam | 119 + .../tools/generators/linking-generator.jam | 179 + .../generators/prebuilt-lib-generator.jam | 30 + .../generators/searched-lib-generator.jam | 97 + tools/build/src/tools/gettext.jam | 230 + tools/build/src/tools/gfortran.jam | 39 + tools/build/src/tools/hp_cxx.jam | 181 + tools/build/src/tools/hpfortran.jam | 35 + tools/build/src/tools/ifort.jam | 44 + tools/build/src/tools/intel-darwin.jam | 233 + tools/build/src/tools/intel-linux.jam | 232 + tools/build/src/tools/intel-vxworks.jam | 183 + tools/build/src/tools/intel-win.jam | 506 + tools/build/src/tools/intel.jam | 34 + tools/build/src/tools/lex.jam | 25 + tools/build/src/tools/libjpeg.jam | 234 + tools/build/src/tools/libpng.jam | 225 + tools/build/src/tools/libtiff.jam | 227 + tools/build/src/tools/link.jam | 547 + tools/build/src/tools/lzma.jam | 133 + tools/build/src/tools/make.jam | 69 + tools/build/src/tools/make.py | 59 + tools/build/src/tools/mc.jam | 44 + tools/build/src/tools/mc.py | 46 + tools/build/src/tools/message.jam | 62 + tools/build/src/tools/message.py | 54 + tools/build/src/tools/midl.jam | 142 + tools/build/src/tools/midl.py | 134 + tools/build/src/tools/mipspro.jam | 145 + tools/build/src/tools/mpi.jam | 638 + tools/build/src/tools/msvc-config.jam | 12 + tools/build/src/tools/msvc.jam | 1816 ++ tools/build/src/tools/msvc.py | 1313 + tools/build/src/tools/notfile.jam | 65 + tools/build/src/tools/notfile.py | 51 + tools/build/src/tools/package.jam | 165 + tools/build/src/tools/package.py | 168 + tools/build/src/tools/pathscale.jam | 178 + tools/build/src/tools/pch.jam | 95 + tools/build/src/tools/pch.py | 83 + tools/build/src/tools/pgi.jam | 126 + tools/build/src/tools/python-config.jam | 27 + tools/build/src/tools/python.jam | 1327 + tools/build/src/tools/qcc.jam | 237 + tools/build/src/tools/qt.jam | 17 + tools/build/src/tools/qt3.jam | 209 + tools/build/src/tools/qt4.jam | 755 + tools/build/src/tools/qt5.jam | 800 + tools/build/src/tools/quickbook-config.jam | 44 + tools/build/src/tools/quickbook.jam | 363 + tools/build/src/tools/rc.jam | 155 + tools/build/src/tools/rc.py | 197 + tools/build/src/tools/sass.jam | 193 + tools/build/src/tools/stage.jam | 519 + tools/build/src/tools/stage.py | 350 + tools/build/src/tools/stlport.jam | 312 + tools/build/src/tools/sun.jam | 165 + tools/build/src/tools/symlink.jam | 140 + tools/build/src/tools/symlink.py | 112 + tools/build/src/tools/testing-aux.jam | 344 + tools/build/src/tools/testing.jam | 847 + tools/build/src/tools/testing.py | 359 + tools/build/src/tools/types/__init__.py | 19 + tools/build/src/tools/types/adoc.jam | 26 + tools/build/src/tools/types/asm.jam | 4 + tools/build/src/tools/types/asm.py | 33 + tools/build/src/tools/types/cpp.jam | 90 + tools/build/src/tools/types/cpp.py | 10 + tools/build/src/tools/types/css.jam | 10 + tools/build/src/tools/types/docbook.jam | 8 + tools/build/src/tools/types/exe.jam | 9 + tools/build/src/tools/types/exe.py | 11 + tools/build/src/tools/types/html.jam | 4 + tools/build/src/tools/types/html.py | 10 + tools/build/src/tools/types/lib.jam | 74 + tools/build/src/tools/types/lib.py | 77 + tools/build/src/tools/types/man.jam | 8 + tools/build/src/tools/types/markdown.jam | 4 + tools/build/src/tools/types/markdown.py | 10 + tools/build/src/tools/types/obj.jam | 9 + tools/build/src/tools/types/obj.py | 11 + tools/build/src/tools/types/objc.jam | 26 + tools/build/src/tools/types/pdf.jam | 8 + tools/build/src/tools/types/preprocessed.jam | 9 + tools/build/src/tools/types/preprocessed.py | 11 + tools/build/src/tools/types/qt.jam | 12 + tools/build/src/tools/types/register.jam | 39 + tools/build/src/tools/types/rsp.jam | 4 + tools/build/src/tools/types/rsp.py | 10 + tools/build/src/tools/types/sass-type.jam | 49 + tools/build/src/tools/types/xml.jam | 49 + tools/build/src/tools/unix.jam | 224 + tools/build/src/tools/unix.py | 155 + tools/build/src/tools/vacpp.jam | 150 + tools/build/src/tools/vmsdecc.jam | 578 + tools/build/src/tools/whale.jam | 116 + tools/build/src/tools/xlcpp.jam | 151 + tools/build/src/tools/xlf.jam | 39 + tools/build/src/tools/xsltproc-config.jam | 36 + tools/build/src/tools/xsltproc.jam | 232 + tools/build/src/tools/xsltproc/included.xsl | 11 + tools/build/src/tools/xsltproc/test.xml | 2 + tools/build/src/tools/xsltproc/test.xsl | 12 + tools/build/src/tools/zlib.jam | 235 + tools/build/src/tools/zstd.jam | 98 + tools/build/src/util/__init__.py | 321 + tools/build/src/util/assert.jam | 346 + tools/build/src/util/container.jam | 339 + tools/build/src/util/doc.jam | 1076 + tools/build/src/util/indirect.jam | 124 + tools/build/src/util/indirect.py | 15 + tools/build/src/util/logger.py | 46 + tools/build/src/util/numbers.jam | 218 + tools/build/src/util/option.jam | 109 + tools/build/src/util/option.py | 35 + tools/build/src/util/order.jam | 173 + tools/build/src/util/order.py | 121 + tools/build/src/util/os.jam | 208 + tools/build/src/util/os_j.py | 24 + tools/build/src/util/param.jam | 54 + tools/build/src/util/path.jam | 947 + tools/build/src/util/path.py | 937 + tools/build/src/util/print.jam | 508 + tools/build/src/util/regex.jam | 203 + tools/build/src/util/regex.py | 63 + tools/build/src/util/sequence.jam | 378 + tools/build/src/util/sequence.py | 58 + tools/build/src/util/set.jam | 93 + tools/build/src/util/set.py | 48 + tools/build/src/util/string.jam | 189 + tools/build/src/util/utility.jam | 235 + tools/build/src/util/utility.py | 176 + tools/build/test/BoostBuild.py | 1362 + tools/build/test/Jamfile.jam | 29 + tools/build/test/MockToolset.py | 265 + tools/build/test/TestCmd.py | 605 + tools/build/test/TestToolset.py | 121 + tools/build/test/abs_workdir.py | 26 + tools/build/test/absolute_sources.py | 73 + tools/build/test/alias.py | 107 + tools/build/test/alternatives.py | 129 + tools/build/test/bad_dirname.py | 22 + tools/build/test/boost-build.jam | 14 + tools/build/test/boostbook.py | 23 + tools/build/test/boostbook/a.hpp | 16 + tools/build/test/boostbook/docs.xml | 36 + tools/build/test/boostbook/jamroot.jam | 3 + tools/build/test/build_dir.py | 107 + tools/build/test/build_file.py | 170 + tools/build/test/build_hooks.py | 39 + tools/build/test/build_no.py | 23 + tools/build/test/builtin_echo.py | 30 + tools/build/test/builtin_exit.py | 42 + tools/build/test/builtin_glob.py | 87 + tools/build/test/builtin_glob_archive.py | 214 + tools/build/test/builtin_readlink.py | 24 + .../build/test/builtin_split_by_characters.py | 57 + tools/build/test/bzip2.py | 119 + tools/build/test/c_file.py | 36 + tools/build/test/chain.py | 56 + tools/build/test/clean.py | 104 + tools/build/test/cli_property_expansion.py | 41 + tools/build/test/collect_debug_info.py | 341 + tools/build/test/command_line_properties.py | 166 + tools/build/test/composite.py | 25 + tools/build/test/conditionals.py | 48 + tools/build/test/conditionals2.py | 43 + tools/build/test/conditionals3.py | 30 + tools/build/test/conditionals_multiple.py | 312 + tools/build/test/configuration.py | 397 + tools/build/test/configure.py | 219 + tools/build/test/copy_time.py | 69 + tools/build/test/core-language/test.jam | 1563 + tools/build/test/core_action_output.py | 62 + tools/build/test/core_action_status.py | 27 + tools/build/test/core_actions_quietly.py | 61 + tools/build/test/core_arguments.py | 103 + tools/build/test/core_at_file.py | 63 + tools/build/test/core_bindrule.py | 45 + tools/build/test/core_d12.py | 32 + tools/build/test/core_delete_module.py | 51 + tools/build/test/core_dependencies.py | 157 + tools/build/test/core_fail_expected.py | 139 + tools/build/test/core_import_module.py | 82 + tools/build/test/core_jamshell.py | 54 + tools/build/test/core_language.py | 12 + tools/build/test/core_modifiers.py | 51 + tools/build/test/core_multifile_actions.py | 202 + tools/build/test/core_nt_cmd_line.py | 266 + tools/build/test/core_option_d2.py | 55 + tools/build/test/core_option_l.py | 44 + tools/build/test/core_option_n.py | 51 + tools/build/test/core_parallel_actions.py | 103 + .../test/core_parallel_multifile_actions_1.py | 78 + .../test/core_parallel_multifile_actions_2.py | 71 + tools/build/test/core_scanner.py | 36 + tools/build/test/core_source_line_tracking.py | 74 + tools/build/test/core_typecheck.py | 47 + tools/build/test/core_update_now.py | 377 + tools/build/test/core_variables_in_actions.py | 39 + tools/build/test/core_varnames.py | 38 + tools/build/test/custom_generator.py | 66 + tools/build/test/debugger-mi.py | 326 + tools/build/test/debugger.py | 674 + tools/build/test/default_build.py | 80 + tools/build/test/default_features.py | 50 + tools/build/test/default_toolset.py | 215 + tools/build/test/dependency_property.py | 38 + tools/build/test/dependency_test.py | 239 + tools/build/test/disambiguation.py | 32 + tools/build/test/dll_path.py | 163 + tools/build/test/double_loading.py | 31 + tools/build/test/duplicate.py | 38 + tools/build/test/example_customization.py | 21 + tools/build/test/example_gettext.py | 30 + tools/build/test/example_libraries.py | 21 + tools/build/test/example_make.py | 17 + tools/build/test/example_qt4.py | 26 + tools/build/test/exit_status.py | 26 + tools/build/test/expansion.py | 146 + tools/build/test/explicit.py | 58 + tools/build/test/feature_cxxflags.py | 37 + .../build/test/feature_implicit_dependency.py | 113 + tools/build/test/feature_relevant.py | 142 + .../build/test/feature_suppress_import_lib.py | 33 + tools/build/test/file_types.py | 44 + tools/build/test/flags.py | 74 + tools/build/test/gcc_runtime.py | 27 + tools/build/test/generator_selection.py | 157 + tools/build/test/generators_test.py | 433 + tools/build/test/implicit_dependency.py | 81 + tools/build/test/indirect_conditional.py | 105 + tools/build/test/inherit_toolset.py | 100 + tools/build/test/inherited_dependency.py | 237 + tools/build/test/inline.py | 62 + tools/build/test/lib_source_property.py | 45 + tools/build/test/lib_zlib.py | 184 + tools/build/test/libjpeg.py | 119 + tools/build/test/liblzma.py | 118 + tools/build/test/libpng.py | 119 + tools/build/test/library_chain.py | 152 + tools/build/test/library_order.py | 94 + tools/build/test/library_property.py | 56 + tools/build/test/libtiff.py | 119 + tools/build/test/libzstd.py | 118 + tools/build/test/link.py | 350 + tools/build/test/load_dir.py | 81 + tools/build/test/load_order.py | 71 + tools/build/test/loop.py | 24 + tools/build/test/make_rule.py | 54 + tools/build/test/message.py | 38 + tools/build/test/module_actions.py | 105 + tools/build/test/ndebug.py | 33 + tools/build/test/no_type.py | 19 + tools/build/test/notfile.py | 36 + tools/build/test/ordered_include.py | 251 + tools/build/test/ordered_properties.py | 33 + tools/build/test/out_of_tree.py | 29 + tools/build/test/param.py | 61 + tools/build/test/path_features.py | 163 + tools/build/test/pch.py | 56 + tools/build/test/prebuilt.py | 43 + tools/build/test/prebuilt/ext/a.cpp | 17 + tools/build/test/prebuilt/ext/debug/a.h | 13 + tools/build/test/prebuilt/ext/jamfile.jam | 13 + tools/build/test/prebuilt/ext/jamfile2.jam | 39 + tools/build/test/prebuilt/ext/jamfile3.jam | 46 + tools/build/test/prebuilt/ext/jamroot.jam | 5 + tools/build/test/prebuilt/ext/release/a.h | 13 + tools/build/test/prebuilt/hello.cpp | 20 + tools/build/test/prebuilt/jamfile.jam | 13 + tools/build/test/prebuilt/jamroot.jam | 4 + tools/build/test/preprocessor.py | 53 + tools/build/test/print.py | 48 + tools/build/test/project-test3/a.cpp | 8 + tools/build/test/project-test3/jamfile.jam | 13 + tools/build/test/project-test3/jamroot.jam | 67 + tools/build/test/project-test3/lib/b.cpp | 8 + .../build/test/project-test3/lib/jamfile.jam | 9 + tools/build/test/project-test3/lib2/c.cpp | 8 + tools/build/test/project-test3/lib2/d.cpp | 8 + .../test/project-test3/lib2/helper/e.cpp | 8 + .../project-test3/lib2/helper/jamfile.jam | 9 + .../build/test/project-test3/lib2/jamfile.jam | 11 + tools/build/test/project-test3/lib3/f.cpp | 8 + .../build/test/project-test3/lib3/jamfile.jam | 47 + .../build/test/project-test3/lib3/jamroot.jam | 5 + tools/build/test/project-test3/readme.txt | 7 + tools/build/test/project-test4/a.cpp | 8 + tools/build/test/project-test4/a_gcc.cpp | 8 + tools/build/test/project-test4/jamfile.jam | 11 + tools/build/test/project-test4/jamfile3.jam | 5 + tools/build/test/project-test4/jamfile4.jam | 4 + tools/build/test/project-test4/jamfile5.jam | 6 + tools/build/test/project-test4/jamroot.jam | 68 + tools/build/test/project-test4/lib/b.cpp | 8 + .../build/test/project-test4/lib/jamfile.jam | 6 + .../build/test/project-test4/lib/jamfile1.jam | 2 + .../build/test/project-test4/lib/jamfile2.jam | 4 + .../build/test/project-test4/lib/jamfile3.jam | 2 + .../build/test/project-test4/lib2/jamfile.jam | 8 + .../test/project-test4/lib2/jamfile2.jam | 4 + tools/build/test/project-test4/readme.txt | 6 + tools/build/test/project_dependencies.py | 51 + tools/build/test/project_glob.py | 212 + tools/build/test/project_id.py | 414 + tools/build/test/project_root_constants.py | 62 + tools/build/test/project_root_rule.py | 34 + tools/build/test/project_test3.py | 136 + tools/build/test/project_test4.py | 65 + tools/build/test/property_expansion.py | 28 + tools/build/test/qt4.py | 19 + tools/build/test/qt4/jamroot.jam | 82 + tools/build/test/qt4/mock.cpp | 26 + tools/build/test/qt4/mock.h | 21 + tools/build/test/qt4/phonon.cpp | 23 + tools/build/test/qt4/qt3support.cpp | 29 + tools/build/test/qt4/qtassistant.cpp | 21 + tools/build/test/qt4/qtcore.cpp | 22 + tools/build/test/qt4/qtcorefail.cpp | 23 + tools/build/test/qt4/qtdeclarative.cpp | 27 + tools/build/test/qt4/qtgui.cpp | 42 + tools/build/test/qt4/qthelp.cpp | 22 + tools/build/test/qt4/qtmultimedia.cpp | 25 + tools/build/test/qt4/qtnetwork.cpp | 33 + tools/build/test/qt4/qtscript.cpp | 37 + tools/build/test/qt4/qtscripttools.cpp | 47 + tools/build/test/qt4/qtsql.cpp | 37 + tools/build/test/qt4/qtsvg.cpp | 21 + tools/build/test/qt4/qttest.cpp | 30 + tools/build/test/qt4/qtwebkit.cpp | 24 + tools/build/test/qt4/qtxml.cpp | 29 + tools/build/test/qt4/qtxmlpatterns.cpp | 76 + tools/build/test/qt4/rcc.cpp | 20 + tools/build/test/qt4/rcc.qrc | 5 + tools/build/test/qt5.py | 19 + tools/build/test/qt5/jamroot.jam | 104 + tools/build/test/qt5/mock.cpp | 26 + tools/build/test/qt5/mock.h | 21 + tools/build/test/qt5/qt3dcore.cpp | 21 + tools/build/test/qt5/qt3dinput.cpp | 24 + tools/build/test/qt5/qt3dlogic.cpp | 20 + tools/build/test/qt5/qt3drender.cpp | 21 + tools/build/test/qt5/qtassistant.cpp | 21 + tools/build/test/qt5/qtbluetooth.cpp | 34 + tools/build/test/qt5/qtcharts.cpp | 15 + tools/build/test/qt5/qtcore.cpp | 22 + tools/build/test/qt5/qtcorefail.cpp | 23 + tools/build/test/qt5/qtdatavisualization.cpp | 31 + tools/build/test/qt5/qtdeclarative.cpp | 26 + tools/build/test/qt5/qtgamepad.cpp | 29 + tools/build/test/qt5/qthelp.cpp | 22 + tools/build/test/qt5/qtlocation.cpp | 30 + tools/build/test/qt5/qtmultimedia.cpp | 25 + tools/build/test/qt5/qtnetwork.cpp | 33 + tools/build/test/qt5/qtnfc.cpp | 28 + tools/build/test/qt5/qtpositioning.cpp | 23 + tools/build/test/qt5/qtpurchasing.cpp | 44 + tools/build/test/qt5/qtquick.cpp | 43 + tools/build/test/qt5/qtquick.qml | 20 + tools/build/test/qt5/qtscript.cpp | 37 + tools/build/test/qt5/qtscripttools.cpp | 47 + tools/build/test/qt5/qtscxml.cpp | 33 + tools/build/test/qt5/qtserialbus.cpp | 25 + tools/build/test/qt5/qtserialport.cpp | 22 + tools/build/test/qt5/qtsql.cpp | 37 + tools/build/test/qt5/qtsvg.cpp | 21 + tools/build/test/qt5/qttest.cpp | 30 + tools/build/test/qt5/qtwebchannel.cpp | 29 + tools/build/test/qt5/qtwebengine.cpp | 30 + tools/build/test/qt5/qtwebenginewidgets.cpp | 40 + tools/build/test/qt5/qtwebkit.cpp | 22 + tools/build/test/qt5/qtwebkitwidgets.cpp | 23 + tools/build/test/qt5/qtwebsocket.cpp | 26 + tools/build/test/qt5/qtwebsockets.cpp | 24 + tools/build/test/qt5/qtwebview.cpp | 31 + tools/build/test/qt5/qtwidgets.cpp | 43 + tools/build/test/qt5/qtxml.cpp | 29 + tools/build/test/qt5/qtxmlpatterns.cpp | 76 + tools/build/test/qt5/rcc.cpp | 20 + tools/build/test/qt5/rcc.qrc | 5 + tools/build/test/railsys.py | 14 + .../test/railsys/libx/include/test_libx.h | 25 + tools/build/test/railsys/libx/jamroot.jam | 13 + tools/build/test/railsys/libx/src/jamfile.jam | 19 + .../build/test/railsys/libx/src/test_libx.cpp | 15 + .../test/railsys/program/include/test_a.h | 22 + tools/build/test/railsys/program/jamfile.jam | 45 + tools/build/test/railsys/program/jamroot.jam | 14 + .../test/railsys/program/liba/jamfile.jam | 14 + .../test/railsys/program/liba/test_a.cpp | 17 + .../test/railsys/program/main/jamfile.jam | 12 + .../build/test/railsys/program/main/main.cpp | 19 + tools/build/test/readme.txt | 6 + tools/build/test/rebuilds.py | 68 + tools/build/test/relative_sources.py | 38 + tools/build/test/remove_requirement.py | 91 + tools/build/test/rescan_header.py | 265 + tools/build/test/resolution.py | 35 + tools/build/test/results-python.txt | 132 + tools/build/test/scanner_causing_rebuilds.py | 132 + tools/build/test/searched_lib.py | 186 + tools/build/test/skipping.py | 27 + tools/build/test/sort_rule.py | 96 + tools/build/test/source_locations.py | 42 + tools/build/test/source_order.py | 84 + tools/build/test/space_in_path.py | 51 + tools/build/test/stage.py | 207 + tools/build/test/standalone.py | 53 + .../test/startup/boost-root/boost-build.jam | 7 + .../startup/boost-root/build/boost-build.jam | 6 + .../startup/boost-root/build/bootstrap.jam | 7 + .../startup/bootstrap-env/boost-build.jam | 5 + .../bootstrap-explicit/boost-build.jam | 6 + .../startup/bootstrap-implicit/readme.txt | 5 + .../startup/no-bootstrap1/boost-build.jam | 6 + .../startup/no-bootstrap1/subdir/readme.txt | 5 + .../startup/no-bootstrap2/boost-build.jam | 6 + .../startup/no-bootstrap3/boost-build.jam | 5 + tools/build/test/startup_v2.py | 94 + tools/build/test/static_and_shared_library.py | 38 + tools/build/test/suffix.py | 78 + tools/build/test/symlink.py | 41 + tools/build/test/tag.py | 122 + tools/build/test/template.py | 42 + tools/build/test/test-config-example.jam | 19 + tools/build/test/test.jam | 39 + tools/build/test/test1.py | 18 + tools/build/test/test2.py | 25 + tools/build/test/test2/foo.cpp | 10 + tools/build/test/test2/jamroot.jam | 5 + tools/build/test/test_all.py | 337 + tools/build/test/test_rc.py | 148 + tools/build/test/test_system.html | 618 + tools/build/test/testing.py | 535 + tools/build/test/timedata.py | 178 + tools/build/test/toolset-mock/Jamroot.jam | 8 + tools/build/test/toolset-mock/lib.cpp | 7 + tools/build/test/toolset-mock/main.cpp | 7 + .../test/toolset-mock/project-config.jam | 40 + tools/build/test/toolset-mock/src/Jamroot.jam | 61 + .../test/toolset-mock/src/MockProgram.py | 260 + tools/build/test/toolset-mock/src/ar.py | 24 + .../toolset-mock/src/clang-3.9.0-darwin.py | 49 + .../toolset-mock/src/clang-linux-3.9.0.py | 48 + .../toolset-mock/src/clang-vxworks-4.0.1.py | 42 + .../test/toolset-mock/src/darwin-4.2.1.py | 38 + .../test/toolset-mock/src/gcc-4.2.1-darwin.py | 37 + .../test/toolset-mock/src/gcc-4.8.3-linux.py | 50 + .../toolset-mock/src/intel-darwin-10.2.py | 43 + tools/build/test/toolset-mock/src/ld.py | 33 + tools/build/test/toolset-mock/src/libtool.py | 14 + .../test/toolset-mock/src/mock-program.cpp | 42 + .../test/toolset-mock/src/project-config.jam | 5 + tools/build/test/toolset-mock/src/ranlib.py | 22 + tools/build/test/toolset-mock/src/strip.py | 13 + tools/build/test/toolset-mock/src/verify.py | 9 + tools/build/test/toolset_clang_darwin.py | 20 + tools/build/test/toolset_clang_linux.py | 19 + tools/build/test/toolset_clang_vxworks.py | 20 + tools/build/test/toolset_darwin.py | 21 + tools/build/test/toolset_defaults.py | 60 + tools/build/test/toolset_gcc.py | 26 + tools/build/test/toolset_intel_darwin.py | 19 + tools/build/test/toolset_requirements.py | 44 + tools/build/test/tree.py | 243 + tools/build/test/unit_test.py | 36 + tools/build/test/unit_tests.py | 11 + tools/build/test/unused.py | 81 + tools/build/test/use_requirements.py | 283 + tools/build/test/using.py | 32 + tools/build/test/wrapper.py | 38 + tools/build/test/wrong_project.py | 39 + tools/build/tutorial.html | 1522 + tools/build/website/boost.css | 63 + tools/build/website/boost_build.png | Bin 0 -> 7437 bytes tools/build/website/boost_build.svg | 174 + .../website/bootstrap/css/bootstrap-theme.css | 397 + .../bootstrap/css/bootstrap-theme.min.css | 7 + .../build/website/bootstrap/css/bootstrap.css | 7118 +++++ .../website/bootstrap/css/bootstrap.min.css | 7 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20290 bytes .../fonts/glyphicons-halflings-regular.svg | 229 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41236 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23292 bytes tools/build/website/bootstrap/js/bootstrap.js | 2006 ++ .../website/bootstrap/js/bootstrap.min.js | 7 + tools/build/website/index.css | 61 + 4556 files changed, 810544 insertions(+) create mode 100644 Jamroot create mode 100644 LICENSE_1_0.txt create mode 100644 README.md create mode 100644 b2.exe create mode 100644 bcp.exe create mode 100644 bjam.exe create mode 100644 boost-build.jam create mode 100644 boost.png create mode 100644 boost/algorithm/cxx11/all_of.hpp create mode 100644 boost/algorithm/string/classification.hpp create mode 100644 boost/algorithm/string/compare.hpp create mode 100644 boost/algorithm/string/concept.hpp create mode 100644 boost/algorithm/string/config.hpp create mode 100644 boost/algorithm/string/constants.hpp create mode 100644 boost/algorithm/string/detail/classification.hpp create mode 100644 boost/algorithm/string/detail/find_iterator.hpp create mode 100644 boost/algorithm/string/detail/finder.hpp create mode 100644 boost/algorithm/string/detail/trim.hpp create mode 100644 boost/algorithm/string/detail/util.hpp create mode 100644 boost/algorithm/string/find_iterator.hpp create mode 100644 boost/algorithm/string/finder.hpp create mode 100644 boost/algorithm/string/iter_find.hpp create mode 100644 boost/algorithm/string/predicate_facade.hpp create mode 100644 boost/algorithm/string/split.hpp create mode 100644 boost/algorithm/string/trim.hpp create mode 100644 boost/aligned_storage.hpp create mode 100644 boost/any.hpp create mode 100644 boost/array.hpp create mode 100644 boost/assert.hpp create mode 100644 boost/atomic.hpp create mode 100644 boost/atomic/atomic.hpp create mode 100644 boost/atomic/atomic_flag.hpp create mode 100644 boost/atomic/capabilities.hpp create mode 100644 boost/atomic/detail/addressof.hpp create mode 100644 boost/atomic/detail/atomic_flag.hpp create mode 100644 boost/atomic/detail/atomic_template.hpp create mode 100644 boost/atomic/detail/bitwise_cast.hpp create mode 100644 boost/atomic/detail/bitwise_fp_cast.hpp create mode 100644 boost/atomic/detail/caps_gcc_alpha.hpp create mode 100644 boost/atomic/detail/caps_gcc_arm.hpp create mode 100644 boost/atomic/detail/caps_gcc_atomic.hpp create mode 100644 boost/atomic/detail/caps_gcc_ppc.hpp create mode 100644 boost/atomic/detail/caps_gcc_sparc.hpp create mode 100644 boost/atomic/detail/caps_gcc_sync.hpp create mode 100644 boost/atomic/detail/caps_gcc_x86.hpp create mode 100644 boost/atomic/detail/caps_linux_arm.hpp create mode 100644 boost/atomic/detail/caps_msvc_arm.hpp create mode 100644 boost/atomic/detail/caps_msvc_x86.hpp create mode 100644 boost/atomic/detail/caps_windows.hpp create mode 100644 boost/atomic/detail/config.hpp create mode 100644 boost/atomic/detail/extra_fp_operations.hpp create mode 100644 boost/atomic/detail/extra_fp_operations_fwd.hpp create mode 100644 boost/atomic/detail/extra_fp_ops_emulated.hpp create mode 100644 boost/atomic/detail/extra_fp_ops_generic.hpp create mode 100644 boost/atomic/detail/extra_operations.hpp create mode 100644 boost/atomic/detail/extra_operations_fwd.hpp create mode 100644 boost/atomic/detail/extra_ops_emulated.hpp create mode 100644 boost/atomic/detail/extra_ops_gcc_arm.hpp create mode 100644 boost/atomic/detail/extra_ops_gcc_ppc.hpp create mode 100644 boost/atomic/detail/extra_ops_gcc_x86.hpp create mode 100644 boost/atomic/detail/extra_ops_generic.hpp create mode 100644 boost/atomic/detail/extra_ops_msvc_arm.hpp create mode 100644 boost/atomic/detail/extra_ops_msvc_x86.hpp create mode 100644 boost/atomic/detail/float_sizes.hpp create mode 100644 boost/atomic/detail/fp_operations.hpp create mode 100644 boost/atomic/detail/fp_operations_fwd.hpp create mode 100644 boost/atomic/detail/fp_ops_emulated.hpp create mode 100644 boost/atomic/detail/fp_ops_generic.hpp create mode 100644 boost/atomic/detail/hwcaps_gcc_arm.hpp create mode 100644 boost/atomic/detail/hwcaps_gcc_ppc.hpp create mode 100644 boost/atomic/detail/hwcaps_gcc_x86.hpp create mode 100644 boost/atomic/detail/int_sizes.hpp create mode 100644 boost/atomic/detail/integral_extend.hpp create mode 100644 boost/atomic/detail/interlocked.hpp create mode 100644 boost/atomic/detail/link.hpp create mode 100644 boost/atomic/detail/lockpool.hpp create mode 100644 boost/atomic/detail/operations.hpp create mode 100644 boost/atomic/detail/operations_fwd.hpp create mode 100644 boost/atomic/detail/operations_lockfree.hpp create mode 100644 boost/atomic/detail/ops_cas_based.hpp create mode 100644 boost/atomic/detail/ops_emulated.hpp create mode 100644 boost/atomic/detail/ops_extending_cas_based.hpp create mode 100644 boost/atomic/detail/ops_gcc_alpha.hpp create mode 100644 boost/atomic/detail/ops_gcc_arm.hpp create mode 100644 boost/atomic/detail/ops_gcc_arm_common.hpp create mode 100644 boost/atomic/detail/ops_gcc_atomic.hpp create mode 100644 boost/atomic/detail/ops_gcc_ppc.hpp create mode 100644 boost/atomic/detail/ops_gcc_ppc_common.hpp create mode 100644 boost/atomic/detail/ops_gcc_sparc.hpp create mode 100644 boost/atomic/detail/ops_gcc_sync.hpp create mode 100644 boost/atomic/detail/ops_gcc_x86.hpp create mode 100644 boost/atomic/detail/ops_gcc_x86_dcas.hpp create mode 100644 boost/atomic/detail/ops_linux_arm.hpp create mode 100644 boost/atomic/detail/ops_msvc_arm.hpp create mode 100644 boost/atomic/detail/ops_msvc_common.hpp create mode 100644 boost/atomic/detail/ops_msvc_x86.hpp create mode 100644 boost/atomic/detail/ops_windows.hpp create mode 100644 boost/atomic/detail/pause.hpp create mode 100644 boost/atomic/detail/platform.hpp create mode 100644 boost/atomic/detail/storage_type.hpp create mode 100644 boost/atomic/detail/string_ops.hpp create mode 100644 boost/atomic/detail/type_traits/conditional.hpp create mode 100644 boost/atomic/detail/type_traits/integral_constant.hpp create mode 100644 boost/atomic/detail/type_traits/is_floating_point.hpp create mode 100644 boost/atomic/detail/type_traits/is_function.hpp create mode 100644 boost/atomic/detail/type_traits/is_iec559.hpp create mode 100644 boost/atomic/detail/type_traits/is_integral.hpp create mode 100644 boost/atomic/detail/type_traits/is_signed.hpp create mode 100644 boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp create mode 100644 boost/atomic/detail/type_traits/make_signed.hpp create mode 100644 boost/atomic/detail/type_traits/make_unsigned.hpp create mode 100644 boost/atomic/fences.hpp create mode 100644 boost/bind.hpp create mode 100644 boost/bind/arg.hpp create mode 100644 boost/bind/bind.hpp create mode 100644 boost/bind/bind_cc.hpp create mode 100644 boost/bind/bind_mf2_cc.hpp create mode 100644 boost/bind/bind_mf_cc.hpp create mode 100644 boost/bind/bind_template.hpp create mode 100644 boost/bind/mem_fn.hpp create mode 100644 boost/bind/mem_fn_cc.hpp create mode 100644 boost/bind/mem_fn_template.hpp create mode 100644 boost/bind/mem_fn_vw.hpp create mode 100644 boost/bind/placeholders.hpp create mode 100644 boost/bind/storage.hpp create mode 100644 boost/call_traits.hpp create mode 100644 boost/cerrno.hpp create mode 100644 boost/checked_delete.hpp create mode 100644 boost/chrono.hpp create mode 100644 boost/chrono/ceil.hpp create mode 100644 boost/chrono/chrono.hpp create mode 100644 boost/chrono/chrono_io.hpp create mode 100644 boost/chrono/clock_string.hpp create mode 100644 boost/chrono/config.hpp create mode 100644 boost/chrono/detail/inlined/chrono.hpp create mode 100644 boost/chrono/detail/inlined/mac/chrono.hpp create mode 100644 boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp create mode 100644 boost/chrono/detail/inlined/mac/thread_clock.hpp create mode 100644 boost/chrono/detail/inlined/posix/chrono.hpp create mode 100644 boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp create mode 100644 boost/chrono/detail/inlined/posix/thread_clock.hpp create mode 100644 boost/chrono/detail/inlined/process_cpu_clocks.hpp create mode 100644 boost/chrono/detail/inlined/thread_clock.hpp create mode 100644 boost/chrono/detail/inlined/win/chrono.hpp create mode 100644 boost/chrono/detail/inlined/win/process_cpu_clocks.hpp create mode 100644 boost/chrono/detail/inlined/win/thread_clock.hpp create mode 100644 boost/chrono/detail/is_evenly_divisible_by.hpp create mode 100644 boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp create mode 100644 boost/chrono/detail/scan_keyword.hpp create mode 100644 boost/chrono/detail/static_assert.hpp create mode 100644 boost/chrono/detail/system.hpp create mode 100644 boost/chrono/duration.hpp create mode 100644 boost/chrono/floor.hpp create mode 100644 boost/chrono/include.hpp create mode 100644 boost/chrono/io/duration_get.hpp create mode 100644 boost/chrono/io/duration_io.hpp create mode 100644 boost/chrono/io/duration_put.hpp create mode 100644 boost/chrono/io/duration_style.hpp create mode 100644 boost/chrono/io/duration_units.hpp create mode 100644 boost/chrono/io/ios_base_state.hpp create mode 100644 boost/chrono/io/time_point_get.hpp create mode 100644 boost/chrono/io/time_point_io.hpp create mode 100644 boost/chrono/io/time_point_put.hpp create mode 100644 boost/chrono/io/time_point_units.hpp create mode 100644 boost/chrono/io/timezone.hpp create mode 100644 boost/chrono/io/utility/ios_base_state_ptr.hpp create mode 100644 boost/chrono/io/utility/manip_base.hpp create mode 100644 boost/chrono/io/utility/to_string.hpp create mode 100644 boost/chrono/io_v1/chrono_io.hpp create mode 100644 boost/chrono/process_cpu_clocks.hpp create mode 100644 boost/chrono/round.hpp create mode 100644 boost/chrono/system_clocks.hpp create mode 100644 boost/chrono/thread_clock.hpp create mode 100644 boost/chrono/time_point.hpp create mode 100644 boost/concept/assert.hpp create mode 100644 boost/concept/detail/backward_compatibility.hpp create mode 100644 boost/concept/detail/borland.hpp create mode 100644 boost/concept/detail/concept_def.hpp create mode 100644 boost/concept/detail/concept_undef.hpp create mode 100644 boost/concept/detail/general.hpp create mode 100644 boost/concept/detail/has_constraints.hpp create mode 100644 boost/concept/detail/msvc.hpp create mode 100644 boost/concept/usage.hpp create mode 100644 boost/concept_check.hpp create mode 100644 boost/config.hpp create mode 100644 boost/config/abi/borland_prefix.hpp create mode 100644 boost/config/abi/borland_suffix.hpp create mode 100644 boost/config/abi/msvc_prefix.hpp create mode 100644 boost/config/abi/msvc_suffix.hpp create mode 100644 boost/config/abi_prefix.hpp create mode 100644 boost/config/abi_suffix.hpp create mode 100644 boost/config/auto_link.hpp create mode 100644 boost/config/compiler/borland.hpp create mode 100644 boost/config/compiler/clang.hpp create mode 100644 boost/config/compiler/codegear.hpp create mode 100644 boost/config/compiler/comeau.hpp create mode 100644 boost/config/compiler/common_edg.hpp create mode 100644 boost/config/compiler/compaq_cxx.hpp create mode 100644 boost/config/compiler/cray.hpp create mode 100644 boost/config/compiler/diab.hpp create mode 100644 boost/config/compiler/digitalmars.hpp create mode 100644 boost/config/compiler/gcc.hpp create mode 100644 boost/config/compiler/gcc_xml.hpp create mode 100644 boost/config/compiler/greenhills.hpp create mode 100644 boost/config/compiler/hp_acc.hpp create mode 100644 boost/config/compiler/intel.hpp create mode 100644 boost/config/compiler/kai.hpp create mode 100644 boost/config/compiler/metrowerks.hpp create mode 100644 boost/config/compiler/mpw.hpp create mode 100644 boost/config/compiler/nvcc.hpp create mode 100644 boost/config/compiler/pathscale.hpp create mode 100644 boost/config/compiler/pgi.hpp create mode 100644 boost/config/compiler/sgi_mipspro.hpp create mode 100644 boost/config/compiler/sunpro_cc.hpp create mode 100644 boost/config/compiler/vacpp.hpp create mode 100644 boost/config/compiler/visualc.hpp create mode 100644 boost/config/compiler/xlcpp.hpp create mode 100644 boost/config/compiler/xlcpp_zos.hpp create mode 100644 boost/config/detail/posix_features.hpp create mode 100644 boost/config/detail/select_compiler_config.hpp create mode 100644 boost/config/detail/select_platform_config.hpp create mode 100644 boost/config/detail/select_stdlib_config.hpp create mode 100644 boost/config/detail/suffix.hpp create mode 100644 boost/config/header_deprecated.hpp create mode 100644 boost/config/helper_macros.hpp create mode 100644 boost/config/no_tr1/cmath.hpp create mode 100644 boost/config/no_tr1/complex.hpp create mode 100644 boost/config/no_tr1/functional.hpp create mode 100644 boost/config/no_tr1/memory.hpp create mode 100644 boost/config/no_tr1/utility.hpp create mode 100644 boost/config/platform/aix.hpp create mode 100644 boost/config/platform/amigaos.hpp create mode 100644 boost/config/platform/beos.hpp create mode 100644 boost/config/platform/bsd.hpp create mode 100644 boost/config/platform/cloudabi.hpp create mode 100644 boost/config/platform/cray.hpp create mode 100644 boost/config/platform/cygwin.hpp create mode 100644 boost/config/platform/haiku.hpp create mode 100644 boost/config/platform/hpux.hpp create mode 100644 boost/config/platform/irix.hpp create mode 100644 boost/config/platform/linux.hpp create mode 100644 boost/config/platform/macos.hpp create mode 100644 boost/config/platform/qnxnto.hpp create mode 100644 boost/config/platform/solaris.hpp create mode 100644 boost/config/platform/symbian.hpp create mode 100644 boost/config/platform/vms.hpp create mode 100644 boost/config/platform/vxworks.hpp create mode 100644 boost/config/platform/win32.hpp create mode 100644 boost/config/platform/zos.hpp create mode 100644 boost/config/pragma_message.hpp create mode 100644 boost/config/requires_threads.hpp create mode 100644 boost/config/stdlib/dinkumware.hpp create mode 100644 boost/config/stdlib/libcomo.hpp create mode 100644 boost/config/stdlib/libcpp.hpp create mode 100644 boost/config/stdlib/libstdcpp3.hpp create mode 100644 boost/config/stdlib/modena.hpp create mode 100644 boost/config/stdlib/msl.hpp create mode 100644 boost/config/stdlib/roguewave.hpp create mode 100644 boost/config/stdlib/sgi.hpp create mode 100644 boost/config/stdlib/stlport.hpp create mode 100644 boost/config/stdlib/vacpp.hpp create mode 100644 boost/config/stdlib/xlcpp_zos.hpp create mode 100644 boost/config/user.hpp create mode 100644 boost/config/warning_disable.hpp create mode 100644 boost/config/workaround.hpp create mode 100644 boost/container/allocator_traits.hpp create mode 100644 boost/container/container_fwd.hpp create mode 100644 boost/container/detail/addressof.hpp create mode 100644 boost/container/detail/advanced_insert_int.hpp create mode 100644 boost/container/detail/algorithm.hpp create mode 100644 boost/container/detail/alloc_helpers.hpp create mode 100644 boost/container/detail/allocation_type.hpp create mode 100644 boost/container/detail/config_begin.hpp create mode 100644 boost/container/detail/config_end.hpp create mode 100644 boost/container/detail/construct_in_place.hpp create mode 100644 boost/container/detail/copy_move_algo.hpp create mode 100644 boost/container/detail/destroyers.hpp create mode 100644 boost/container/detail/dispatch_uses_allocator.hpp create mode 100644 boost/container/detail/iterator.hpp create mode 100644 boost/container/detail/iterators.hpp create mode 100644 boost/container/detail/min_max.hpp create mode 100644 boost/container/detail/mpl.hpp create mode 100644 boost/container/detail/next_capacity.hpp create mode 100644 boost/container/detail/pair.hpp create mode 100644 boost/container/detail/placement_new.hpp create mode 100644 boost/container/detail/std_fwd.hpp create mode 100644 boost/container/detail/type_traits.hpp create mode 100644 boost/container/detail/value_functors.hpp create mode 100644 boost/container/detail/value_init.hpp create mode 100644 boost/container/detail/variadic_templates_tools.hpp create mode 100644 boost/container/detail/version_type.hpp create mode 100644 boost/container/detail/workaround.hpp create mode 100644 boost/container/new_allocator.hpp create mode 100644 boost/container/options.hpp create mode 100644 boost/container/scoped_allocator.hpp create mode 100644 boost/container/scoped_allocator_fwd.hpp create mode 100644 boost/container/throw_exception.hpp create mode 100644 boost/container/uses_allocator.hpp create mode 100644 boost/container/uses_allocator_fwd.hpp create mode 100644 boost/container/vector.hpp create mode 100644 boost/container_hash/detail/float_functions.hpp create mode 100644 boost/container_hash/detail/hash_float.hpp create mode 100644 boost/container_hash/detail/limits.hpp create mode 100644 boost/container_hash/extensions.hpp create mode 100644 boost/container_hash/hash.hpp create mode 100644 boost/container_hash/hash_fwd.hpp create mode 100644 boost/core/addressof.hpp create mode 100644 boost/core/checked_delete.hpp create mode 100644 boost/core/demangle.hpp create mode 100644 boost/core/enable_if.hpp create mode 100644 boost/core/explicit_operator_bool.hpp create mode 100644 boost/core/ignore_unused.hpp create mode 100644 boost/core/is_same.hpp create mode 100644 boost/core/lightweight_test.hpp create mode 100644 boost/core/no_exceptions_support.hpp create mode 100644 boost/core/noncopyable.hpp create mode 100644 boost/core/ref.hpp create mode 100644 boost/core/scoped_enum.hpp create mode 100644 boost/core/swap.hpp create mode 100644 boost/core/typeinfo.hpp create mode 100644 boost/cregex.hpp create mode 100644 boost/cstdint.hpp create mode 100644 boost/cstdlib.hpp create mode 100644 boost/current_function.hpp create mode 100644 boost/date_time/adjust_functors.hpp create mode 100644 boost/date_time/c_time.hpp create mode 100644 boost/date_time/compiler_config.hpp create mode 100644 boost/date_time/constrained_value.hpp create mode 100644 boost/date_time/date.hpp create mode 100644 boost/date_time/date_clock_device.hpp create mode 100644 boost/date_time/date_defs.hpp create mode 100644 boost/date_time/date_duration.hpp create mode 100644 boost/date_time/date_duration_types.hpp create mode 100644 boost/date_time/date_format_simple.hpp create mode 100644 boost/date_time/date_formatting.hpp create mode 100644 boost/date_time/date_formatting_limited.hpp create mode 100644 boost/date_time/date_formatting_locales.hpp create mode 100644 boost/date_time/date_generators.hpp create mode 100644 boost/date_time/date_iterator.hpp create mode 100644 boost/date_time/date_names_put.hpp create mode 100644 boost/date_time/date_parsing.hpp create mode 100644 boost/date_time/dst_rules.hpp create mode 100644 boost/date_time/filetime_functions.hpp create mode 100644 boost/date_time/gregorian/conversion.hpp create mode 100644 boost/date_time/gregorian/formatters.hpp create mode 100644 boost/date_time/gregorian/formatters_limited.hpp create mode 100644 boost/date_time/gregorian/greg_calendar.hpp create mode 100644 boost/date_time/gregorian/greg_date.hpp create mode 100644 boost/date_time/gregorian/greg_day.hpp create mode 100644 boost/date_time/gregorian/greg_day_of_year.hpp create mode 100644 boost/date_time/gregorian/greg_duration.hpp create mode 100644 boost/date_time/gregorian/greg_duration_types.hpp create mode 100644 boost/date_time/gregorian/greg_facet.hpp create mode 100644 boost/date_time/gregorian/greg_month.hpp create mode 100644 boost/date_time/gregorian/greg_weekday.hpp create mode 100644 boost/date_time/gregorian/greg_year.hpp create mode 100644 boost/date_time/gregorian/greg_ymd.hpp create mode 100644 boost/date_time/gregorian/gregorian_types.hpp create mode 100644 boost/date_time/gregorian/parsers.hpp create mode 100644 boost/date_time/gregorian_calendar.hpp create mode 100644 boost/date_time/gregorian_calendar.ipp create mode 100644 boost/date_time/int_adapter.hpp create mode 100644 boost/date_time/iso_format.hpp create mode 100644 boost/date_time/locale_config.hpp create mode 100644 boost/date_time/microsec_time_clock.hpp create mode 100644 boost/date_time/parse_format_base.hpp create mode 100644 boost/date_time/period.hpp create mode 100644 boost/date_time/posix_time/conversion.hpp create mode 100644 boost/date_time/posix_time/date_duration_operators.hpp create mode 100644 boost/date_time/posix_time/posix_time_config.hpp create mode 100644 boost/date_time/posix_time/posix_time_duration.hpp create mode 100644 boost/date_time/posix_time/posix_time_system.hpp create mode 100644 boost/date_time/posix_time/posix_time_types.hpp create mode 100644 boost/date_time/posix_time/ptime.hpp create mode 100644 boost/date_time/posix_time/time_period.hpp create mode 100644 boost/date_time/special_defs.hpp create mode 100644 boost/date_time/time.hpp create mode 100644 boost/date_time/time_clock.hpp create mode 100644 boost/date_time/time_defs.hpp create mode 100644 boost/date_time/time_duration.hpp create mode 100644 boost/date_time/time_iterator.hpp create mode 100644 boost/date_time/time_resolution_traits.hpp create mode 100644 boost/date_time/time_system_counted.hpp create mode 100644 boost/date_time/time_system_split.hpp create mode 100644 boost/date_time/wrapping_int.hpp create mode 100644 boost/date_time/year_month_day.hpp create mode 100644 boost/detail/basic_pointerbuf.hpp create mode 100644 boost/detail/bitmask.hpp create mode 100644 boost/detail/call_traits.hpp create mode 100644 boost/detail/container_fwd.hpp create mode 100644 boost/detail/endian.hpp create mode 100644 boost/detail/fenv.hpp create mode 100644 boost/detail/indirect_traits.hpp create mode 100644 boost/detail/interlocked.hpp create mode 100644 boost/detail/is_incrementable.hpp create mode 100644 boost/detail/iterator.hpp create mode 100644 boost/detail/lcast_precision.hpp create mode 100644 boost/detail/lightweight_main.hpp create mode 100644 boost/detail/lightweight_test.hpp create mode 100644 boost/detail/lightweight_test_report.hpp create mode 100644 boost/detail/no_exceptions_support.hpp create mode 100644 boost/detail/reference_content.hpp create mode 100644 boost/detail/scoped_enum_emulation.hpp create mode 100644 boost/detail/sp_typeinfo.hpp create mode 100644 boost/detail/utf8_codecvt_facet.hpp create mode 100644 boost/detail/utf8_codecvt_facet.ipp create mode 100644 boost/detail/winapi/detail/deprecated_namespace.hpp create mode 100644 boost/detail/winapi/get_current_process.hpp create mode 100644 boost/detail/winapi/get_current_thread.hpp create mode 100644 boost/detail/winapi/get_last_error.hpp create mode 100644 boost/detail/winapi/get_process_times.hpp create mode 100644 boost/detail/winapi/get_thread_times.hpp create mode 100644 boost/detail/winapi/time.hpp create mode 100644 boost/detail/winapi/timers.hpp create mode 100644 boost/detail/workaround.hpp create mode 100644 boost/enable_shared_from_this.hpp create mode 100644 boost/exception/current_exception_cast.hpp create mode 100644 boost/exception/detail/clone_current_exception.hpp create mode 100644 boost/exception/detail/error_info_impl.hpp create mode 100644 boost/exception/detail/exception_ptr.hpp create mode 100644 boost/exception/detail/is_output_streamable.hpp create mode 100644 boost/exception/detail/object_hex_dump.hpp create mode 100644 boost/exception/detail/shared_ptr.hpp create mode 100644 boost/exception/detail/type_info.hpp create mode 100644 boost/exception/diagnostic_information.hpp create mode 100644 boost/exception/exception.hpp create mode 100644 boost/exception/get_error_info.hpp create mode 100644 boost/exception/info.hpp create mode 100644 boost/exception/to_string.hpp create mode 100644 boost/exception/to_string_stub.hpp create mode 100644 boost/exception_ptr.hpp create mode 100644 boost/filesystem.hpp create mode 100644 boost/filesystem/config.hpp create mode 100644 boost/filesystem/convenience.hpp create mode 100644 boost/filesystem/detail/macro_value.hpp create mode 100644 boost/filesystem/detail/utf8_codecvt_facet.hpp create mode 100644 boost/filesystem/exception.hpp create mode 100644 boost/filesystem/fstream.hpp create mode 100644 boost/filesystem/operations.hpp create mode 100644 boost/filesystem/path.hpp create mode 100644 boost/filesystem/path_traits.hpp create mode 100644 boost/filesystem/string_file.hpp create mode 100644 boost/function.hpp create mode 100644 boost/function/detail/function_iterate.hpp create mode 100644 boost/function/detail/gen_maybe_include.pl create mode 100644 boost/function/detail/maybe_include.hpp create mode 100644 boost/function/detail/prologue.hpp create mode 100644 boost/function/function0.hpp create mode 100644 boost/function/function1.hpp create mode 100644 boost/function/function10.hpp create mode 100644 boost/function/function2.hpp create mode 100644 boost/function/function3.hpp create mode 100644 boost/function/function4.hpp create mode 100644 boost/function/function5.hpp create mode 100644 boost/function/function6.hpp create mode 100644 boost/function/function7.hpp create mode 100644 boost/function/function8.hpp create mode 100644 boost/function/function9.hpp create mode 100644 boost/function/function_base.hpp create mode 100644 boost/function/function_fwd.hpp create mode 100644 boost/function/function_template.hpp create mode 100644 boost/function_equal.hpp create mode 100644 boost/functional/hash.hpp create mode 100644 boost/functional/hash_fwd.hpp create mode 100644 boost/get_pointer.hpp create mode 100644 boost/indirect_reference.hpp create mode 100644 boost/integer.hpp create mode 100644 boost/integer/common_factor_rt.hpp create mode 100644 boost/integer/static_log2.hpp create mode 100644 boost/integer_fwd.hpp create mode 100644 boost/integer_traits.hpp create mode 100644 boost/intrusive/detail/algorithm.hpp create mode 100644 boost/intrusive/detail/config_begin.hpp create mode 100644 boost/intrusive/detail/config_end.hpp create mode 100644 boost/intrusive/detail/has_member_function_callable_with.hpp create mode 100644 boost/intrusive/detail/iterator.hpp create mode 100644 boost/intrusive/detail/minimal_pair_header.hpp create mode 100644 boost/intrusive/detail/mpl.hpp create mode 100644 boost/intrusive/detail/reverse_iterator.hpp create mode 100644 boost/intrusive/detail/std_fwd.hpp create mode 100644 boost/intrusive/detail/workaround.hpp create mode 100644 boost/intrusive/pack_options.hpp create mode 100644 boost/intrusive/pointer_rebind.hpp create mode 100644 boost/intrusive/pointer_traits.hpp create mode 100644 boost/intrusive_ptr.hpp create mode 100644 boost/io/detail/quoted_manip.hpp create mode 100644 boost/io/ios_state.hpp create mode 100644 boost/io_fwd.hpp create mode 100644 boost/is_placeholder.hpp create mode 100644 boost/iterator/advance.hpp create mode 100644 boost/iterator/detail/config_def.hpp create mode 100644 boost/iterator/detail/config_undef.hpp create mode 100644 boost/iterator/detail/enable_if.hpp create mode 100644 boost/iterator/detail/facade_iterator_category.hpp create mode 100644 boost/iterator/filter_iterator.hpp create mode 100644 boost/iterator/indirect_iterator.hpp create mode 100644 boost/iterator/interoperable.hpp create mode 100644 boost/iterator/iterator_adaptor.hpp create mode 100644 boost/iterator/iterator_categories.hpp create mode 100644 boost/iterator/iterator_concepts.hpp create mode 100644 boost/iterator/iterator_facade.hpp create mode 100644 boost/iterator/iterator_traits.hpp create mode 100644 boost/iterator/minimum_category.hpp create mode 100644 boost/iterator/reverse_iterator.hpp create mode 100644 boost/iterator/transform_iterator.hpp create mode 100644 boost/lexical_cast.hpp create mode 100644 boost/lexical_cast/bad_lexical_cast.hpp create mode 100644 boost/lexical_cast/detail/converter_lexical.hpp create mode 100644 boost/lexical_cast/detail/converter_lexical_streams.hpp create mode 100644 boost/lexical_cast/detail/converter_numeric.hpp create mode 100644 boost/lexical_cast/detail/inf_nan.hpp create mode 100644 boost/lexical_cast/detail/is_character.hpp create mode 100644 boost/lexical_cast/detail/lcast_char_constants.hpp create mode 100644 boost/lexical_cast/detail/lcast_unsigned_converters.hpp create mode 100644 boost/lexical_cast/detail/widest_char.hpp create mode 100644 boost/lexical_cast/try_lexical_convert.hpp create mode 100644 boost/limits.hpp create mode 100644 boost/make_shared.hpp create mode 100644 boost/math/policies/policy.hpp create mode 100644 boost/math/special_functions/detail/fp_traits.hpp create mode 100644 boost/math/special_functions/detail/round_fwd.hpp create mode 100644 boost/math/special_functions/fpclassify.hpp create mode 100644 boost/math/special_functions/math_fwd.hpp create mode 100644 boost/math/special_functions/sign.hpp create mode 100644 boost/math/tools/config.hpp create mode 100644 boost/math/tools/promotion.hpp create mode 100644 boost/math/tools/real_cast.hpp create mode 100644 boost/math/tools/user.hpp create mode 100644 boost/mem_fn.hpp create mode 100644 boost/memory_order.hpp create mode 100644 boost/move/adl_move_swap.hpp create mode 100644 boost/move/algo/adaptive_merge.hpp create mode 100644 boost/move/algo/detail/adaptive_sort_merge.hpp create mode 100644 boost/move/algo/detail/basic_op.hpp create mode 100644 boost/move/algo/detail/heap_sort.hpp create mode 100644 boost/move/algo/detail/insertion_sort.hpp create mode 100644 boost/move/algo/detail/is_sorted.hpp create mode 100644 boost/move/algo/detail/merge.hpp create mode 100644 boost/move/algo/detail/merge_sort.hpp create mode 100644 boost/move/algo/detail/set_difference.hpp create mode 100644 boost/move/algo/move.hpp create mode 100644 boost/move/algo/predicate.hpp create mode 100644 boost/move/algo/unique.hpp create mode 100644 boost/move/core.hpp create mode 100644 boost/move/default_delete.hpp create mode 100644 boost/move/detail/config_begin.hpp create mode 100644 boost/move/detail/config_end.hpp create mode 100644 boost/move/detail/destruct_n.hpp create mode 100644 boost/move/detail/fwd_macros.hpp create mode 100644 boost/move/detail/iterator_to_raw_pointer.hpp create mode 100644 boost/move/detail/iterator_traits.hpp create mode 100644 boost/move/detail/meta_utils.hpp create mode 100644 boost/move/detail/meta_utils_core.hpp create mode 100644 boost/move/detail/move_helpers.hpp create mode 100644 boost/move/detail/placement_new.hpp create mode 100644 boost/move/detail/pointer_element.hpp create mode 100644 boost/move/detail/reverse_iterator.hpp create mode 100644 boost/move/detail/std_ns_begin.hpp create mode 100644 boost/move/detail/std_ns_end.hpp create mode 100644 boost/move/detail/to_raw_pointer.hpp create mode 100644 boost/move/detail/type_traits.hpp create mode 100644 boost/move/detail/unique_ptr_meta_utils.hpp create mode 100644 boost/move/detail/workaround.hpp create mode 100644 boost/move/iterator.hpp create mode 100644 boost/move/make_unique.hpp create mode 100644 boost/move/traits.hpp create mode 100644 boost/move/unique_ptr.hpp create mode 100644 boost/move/utility.hpp create mode 100644 boost/move/utility_core.hpp create mode 100644 boost/mpl/O1_size.hpp create mode 100644 boost/mpl/O1_size_fwd.hpp create mode 100644 boost/mpl/advance.hpp create mode 100644 boost/mpl/advance_fwd.hpp create mode 100644 boost/mpl/always.hpp create mode 100644 boost/mpl/and.hpp create mode 100644 boost/mpl/apply.hpp create mode 100644 boost/mpl/apply_fwd.hpp create mode 100644 boost/mpl/apply_wrap.hpp create mode 100644 boost/mpl/arg.hpp create mode 100644 boost/mpl/arg_fwd.hpp create mode 100644 boost/mpl/assert.hpp create mode 100644 boost/mpl/at.hpp create mode 100644 boost/mpl/at_fwd.hpp create mode 100644 boost/mpl/aux_/O1_size_impl.hpp create mode 100644 boost/mpl/aux_/adl_barrier.hpp create mode 100644 boost/mpl/aux_/advance_backward.hpp create mode 100644 boost/mpl/aux_/advance_forward.hpp create mode 100644 boost/mpl/aux_/arg_typedef.hpp create mode 100644 boost/mpl/aux_/arithmetic_op.hpp create mode 100644 boost/mpl/aux_/arity.hpp create mode 100644 boost/mpl/aux_/arity_spec.hpp create mode 100644 boost/mpl/aux_/at_impl.hpp create mode 100644 boost/mpl/aux_/begin_end_impl.hpp create mode 100644 boost/mpl/aux_/clear_impl.hpp create mode 100644 boost/mpl/aux_/common_name_wknd.hpp create mode 100644 boost/mpl/aux_/comparison_op.hpp create mode 100644 boost/mpl/aux_/config/adl.hpp create mode 100644 boost/mpl/aux_/config/arrays.hpp create mode 100644 boost/mpl/aux_/config/bcc.hpp create mode 100644 boost/mpl/aux_/config/bind.hpp create mode 100644 boost/mpl/aux_/config/compiler.hpp create mode 100644 boost/mpl/aux_/config/ctps.hpp create mode 100644 boost/mpl/aux_/config/dependent_nttp.hpp create mode 100644 boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp create mode 100644 boost/mpl/aux_/config/dtp.hpp create mode 100644 boost/mpl/aux_/config/eti.hpp create mode 100644 boost/mpl/aux_/config/forwarding.hpp create mode 100644 boost/mpl/aux_/config/gcc.hpp create mode 100644 boost/mpl/aux_/config/gpu.hpp create mode 100644 boost/mpl/aux_/config/has_apply.hpp create mode 100644 boost/mpl/aux_/config/has_xxx.hpp create mode 100644 boost/mpl/aux_/config/integral.hpp create mode 100644 boost/mpl/aux_/config/intel.hpp create mode 100644 boost/mpl/aux_/config/lambda.hpp create mode 100644 boost/mpl/aux_/config/msvc.hpp create mode 100644 boost/mpl/aux_/config/msvc_typename.hpp create mode 100644 boost/mpl/aux_/config/nttp.hpp create mode 100644 boost/mpl/aux_/config/overload_resolution.hpp create mode 100644 boost/mpl/aux_/config/pp_counter.hpp create mode 100644 boost/mpl/aux_/config/preprocessor.hpp create mode 100644 boost/mpl/aux_/config/static_constant.hpp create mode 100644 boost/mpl/aux_/config/ttp.hpp create mode 100644 boost/mpl/aux_/config/typeof.hpp create mode 100644 boost/mpl/aux_/config/use_preprocessed.hpp create mode 100644 boost/mpl/aux_/config/workaround.hpp create mode 100644 boost/mpl/aux_/contains_impl.hpp create mode 100644 boost/mpl/aux_/count_args.hpp create mode 100644 boost/mpl/aux_/find_if_pred.hpp create mode 100644 boost/mpl/aux_/fold_impl.hpp create mode 100644 boost/mpl/aux_/fold_impl_body.hpp create mode 100644 boost/mpl/aux_/full_lambda.hpp create mode 100644 boost/mpl/aux_/has_apply.hpp create mode 100644 boost/mpl/aux_/has_begin.hpp create mode 100644 boost/mpl/aux_/has_rebind.hpp create mode 100644 boost/mpl/aux_/has_size.hpp create mode 100644 boost/mpl/aux_/has_tag.hpp create mode 100644 boost/mpl/aux_/has_type.hpp create mode 100644 boost/mpl/aux_/include_preprocessed.hpp create mode 100644 boost/mpl/aux_/inserter_algorithm.hpp create mode 100644 boost/mpl/aux_/integral_wrapper.hpp create mode 100644 boost/mpl/aux_/is_msvc_eti_arg.hpp create mode 100644 boost/mpl/aux_/iter_apply.hpp create mode 100644 boost/mpl/aux_/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/lambda_arity_param.hpp create mode 100644 boost/mpl/aux_/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/lambda_spec.hpp create mode 100644 boost/mpl/aux_/lambda_support.hpp create mode 100644 boost/mpl/aux_/largest_int.hpp create mode 100644 boost/mpl/aux_/logical_op.hpp create mode 100644 boost/mpl/aux_/msvc_dtw.hpp create mode 100644 boost/mpl/aux_/msvc_eti_base.hpp create mode 100644 boost/mpl/aux_/msvc_is_class.hpp create mode 100644 boost/mpl/aux_/msvc_never_true.hpp create mode 100644 boost/mpl/aux_/msvc_type.hpp create mode 100644 boost/mpl/aux_/na.hpp create mode 100644 boost/mpl/aux_/na_assert.hpp create mode 100644 boost/mpl/aux_/na_fwd.hpp create mode 100644 boost/mpl/aux_/na_spec.hpp create mode 100644 boost/mpl/aux_/nested_type_wknd.hpp create mode 100644 boost/mpl/aux_/nttp_decl.hpp create mode 100644 boost/mpl/aux_/numeric_cast_utils.hpp create mode 100644 boost/mpl/aux_/numeric_op.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc551/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/bcc_pre590/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/dmc/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/gcc/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc60/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/msvc70/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/mwcw/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ctps/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/no_ttp/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/advance_backward.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/advance_forward.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/and.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/apply.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/apply_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/apply_wrap.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/arg.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/basic_bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/bind.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/bind_fwd.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/bitand.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/bitor.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/bitxor.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/deque.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/divides.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/full_lambda.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/greater.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/greater_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/inherit.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/lambda_no_ctps.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/less.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/less_equal.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/list.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/list_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/map.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/minus.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/modulus.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/not_equal_to.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/or.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/placeholders.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/plus.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/quote.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/reverse_iter_fold_impl.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/set.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/set_c.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/shift_left.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/shift_right.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/template_arity.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/times.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/unpack_args.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/vector.hpp create mode 100644 boost/mpl/aux_/preprocessed/plain/vector_c.hpp create mode 100644 boost/mpl/aux_/preprocessor/add.hpp create mode 100644 boost/mpl/aux_/preprocessor/def_params_tail.hpp create mode 100644 boost/mpl/aux_/preprocessor/default_params.hpp create mode 100644 boost/mpl/aux_/preprocessor/enum.hpp create mode 100644 boost/mpl/aux_/preprocessor/ext_params.hpp create mode 100644 boost/mpl/aux_/preprocessor/filter_params.hpp create mode 100644 boost/mpl/aux_/preprocessor/params.hpp create mode 100644 boost/mpl/aux_/preprocessor/partial_spec_params.hpp create mode 100644 boost/mpl/aux_/preprocessor/range.hpp create mode 100644 boost/mpl/aux_/preprocessor/repeat.hpp create mode 100644 boost/mpl/aux_/preprocessor/sub.hpp create mode 100644 boost/mpl/aux_/preprocessor/tuple.hpp create mode 100644 boost/mpl/aux_/push_back_impl.hpp create mode 100644 boost/mpl/aux_/push_front_impl.hpp create mode 100644 boost/mpl/aux_/reverse_fold_impl.hpp create mode 100644 boost/mpl/aux_/reverse_fold_impl_body.hpp create mode 100644 boost/mpl/aux_/sequence_wrapper.hpp create mode 100644 boost/mpl/aux_/size_impl.hpp create mode 100644 boost/mpl/aux_/static_cast.hpp create mode 100644 boost/mpl/aux_/template_arity.hpp create mode 100644 boost/mpl/aux_/template_arity_fwd.hpp create mode 100644 boost/mpl/aux_/traits_lambda_spec.hpp create mode 100644 boost/mpl/aux_/type_wrapper.hpp create mode 100644 boost/mpl/aux_/unwrap.hpp create mode 100644 boost/mpl/aux_/value_wknd.hpp create mode 100644 boost/mpl/aux_/yes_no.hpp create mode 100644 boost/mpl/back_fwd.hpp create mode 100644 boost/mpl/back_inserter.hpp create mode 100644 boost/mpl/begin_end.hpp create mode 100644 boost/mpl/begin_end_fwd.hpp create mode 100644 boost/mpl/bind.hpp create mode 100644 boost/mpl/bind_fwd.hpp create mode 100644 boost/mpl/bool.hpp create mode 100644 boost/mpl/bool_fwd.hpp create mode 100644 boost/mpl/clear.hpp create mode 100644 boost/mpl/clear_fwd.hpp create mode 100644 boost/mpl/comparison.hpp create mode 100644 boost/mpl/contains.hpp create mode 100644 boost/mpl/contains_fwd.hpp create mode 100644 boost/mpl/deref.hpp create mode 100644 boost/mpl/distance.hpp create mode 100644 boost/mpl/distance_fwd.hpp create mode 100644 boost/mpl/empty_fwd.hpp create mode 100644 boost/mpl/equal_to.hpp create mode 100644 boost/mpl/eval_if.hpp create mode 100644 boost/mpl/find.hpp create mode 100644 boost/mpl/find_if.hpp create mode 100644 boost/mpl/fold.hpp create mode 100644 boost/mpl/for_each.hpp create mode 100644 boost/mpl/front_fwd.hpp create mode 100644 boost/mpl/front_inserter.hpp create mode 100644 boost/mpl/greater.hpp create mode 100644 boost/mpl/greater_equal.hpp create mode 100644 boost/mpl/has_xxx.hpp create mode 100644 boost/mpl/identity.hpp create mode 100644 boost/mpl/if.hpp create mode 100644 boost/mpl/inserter.hpp create mode 100644 boost/mpl/int.hpp create mode 100644 boost/mpl/int_fwd.hpp create mode 100644 boost/mpl/integral_c.hpp create mode 100644 boost/mpl/integral_c_fwd.hpp create mode 100644 boost/mpl/integral_c_tag.hpp create mode 100644 boost/mpl/is_placeholder.hpp create mode 100644 boost/mpl/is_sequence.hpp create mode 100644 boost/mpl/iter_fold.hpp create mode 100644 boost/mpl/iter_fold_if.hpp create mode 100644 boost/mpl/iterator_range.hpp create mode 100644 boost/mpl/iterator_tags.hpp create mode 100644 boost/mpl/lambda.hpp create mode 100644 boost/mpl/lambda_fwd.hpp create mode 100644 boost/mpl/less.hpp create mode 100644 boost/mpl/less_equal.hpp create mode 100644 boost/mpl/limits/arity.hpp create mode 100644 boost/mpl/limits/list.hpp create mode 100644 boost/mpl/limits/unrolling.hpp create mode 100644 boost/mpl/limits/vector.hpp create mode 100644 boost/mpl/list.hpp create mode 100644 boost/mpl/list/aux_/O1_size.hpp create mode 100644 boost/mpl/list/aux_/begin_end.hpp create mode 100644 boost/mpl/list/aux_/clear.hpp create mode 100644 boost/mpl/list/aux_/empty.hpp create mode 100644 boost/mpl/list/aux_/front.hpp create mode 100644 boost/mpl/list/aux_/include_preprocessed.hpp create mode 100644 boost/mpl/list/aux_/item.hpp create mode 100644 boost/mpl/list/aux_/iterator.hpp create mode 100644 boost/mpl/list/aux_/numbered.hpp create mode 100644 boost/mpl/list/aux_/numbered_c.hpp create mode 100644 boost/mpl/list/aux_/pop_front.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list10.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list10_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list20.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list20_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list30.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list30_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list40.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list40_c.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list50.hpp create mode 100644 boost/mpl/list/aux_/preprocessed/plain/list50_c.hpp create mode 100644 boost/mpl/list/aux_/push_back.hpp create mode 100644 boost/mpl/list/aux_/push_front.hpp create mode 100644 boost/mpl/list/aux_/size.hpp create mode 100644 boost/mpl/list/aux_/tag.hpp create mode 100644 boost/mpl/list/list0.hpp create mode 100644 boost/mpl/list/list0_c.hpp create mode 100644 boost/mpl/list/list10.hpp create mode 100644 boost/mpl/list/list10_c.hpp create mode 100644 boost/mpl/list/list20.hpp create mode 100644 boost/mpl/list/list20_c.hpp create mode 100644 boost/mpl/list/list30.hpp create mode 100644 boost/mpl/list/list30_c.hpp create mode 100644 boost/mpl/list/list40.hpp create mode 100644 boost/mpl/list/list40_c.hpp create mode 100644 boost/mpl/list/list50.hpp create mode 100644 boost/mpl/list/list50_c.hpp create mode 100644 boost/mpl/logical.hpp create mode 100644 boost/mpl/long.hpp create mode 100644 boost/mpl/long_fwd.hpp create mode 100644 boost/mpl/minus.hpp create mode 100644 boost/mpl/multiplies.hpp create mode 100644 boost/mpl/negate.hpp create mode 100644 boost/mpl/next.hpp create mode 100644 boost/mpl/next_prior.hpp create mode 100644 boost/mpl/not.hpp create mode 100644 boost/mpl/not_equal_to.hpp create mode 100644 boost/mpl/numeric_cast.hpp create mode 100644 boost/mpl/or.hpp create mode 100644 boost/mpl/pair.hpp create mode 100644 boost/mpl/placeholders.hpp create mode 100644 boost/mpl/plus.hpp create mode 100644 boost/mpl/pop_back_fwd.hpp create mode 100644 boost/mpl/pop_front_fwd.hpp create mode 100644 boost/mpl/prior.hpp create mode 100644 boost/mpl/protect.hpp create mode 100644 boost/mpl/push_back.hpp create mode 100644 boost/mpl/push_back_fwd.hpp create mode 100644 boost/mpl/push_front.hpp create mode 100644 boost/mpl/push_front_fwd.hpp create mode 100644 boost/mpl/quote.hpp create mode 100644 boost/mpl/remove_if.hpp create mode 100644 boost/mpl/reverse_fold.hpp create mode 100644 boost/mpl/same_as.hpp create mode 100644 boost/mpl/sequence_tag.hpp create mode 100644 boost/mpl/sequence_tag_fwd.hpp create mode 100644 boost/mpl/size.hpp create mode 100644 boost/mpl/size_fwd.hpp create mode 100644 boost/mpl/tag.hpp create mode 100644 boost/mpl/times.hpp create mode 100644 boost/mpl/vector.hpp create mode 100644 boost/mpl/vector/aux_/O1_size.hpp create mode 100644 boost/mpl/vector/aux_/at.hpp create mode 100644 boost/mpl/vector/aux_/back.hpp create mode 100644 boost/mpl/vector/aux_/begin_end.hpp create mode 100644 boost/mpl/vector/aux_/clear.hpp create mode 100644 boost/mpl/vector/aux_/empty.hpp create mode 100644 boost/mpl/vector/aux_/front.hpp create mode 100644 boost/mpl/vector/aux_/include_preprocessed.hpp create mode 100644 boost/mpl/vector/aux_/item.hpp create mode 100644 boost/mpl/vector/aux_/iterator.hpp create mode 100644 boost/mpl/vector/aux_/numbered.hpp create mode 100644 boost/mpl/vector/aux_/numbered_c.hpp create mode 100644 boost/mpl/vector/aux_/pop_back.hpp create mode 100644 boost/mpl/vector/aux_/pop_front.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector10.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector10_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector20.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector20_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector30.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector30_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector40.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector40_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector50.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/no_ctps/vector50_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector10_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector20_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector30.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector30_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector40.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector40_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector50.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/plain/vector50_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector10_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector20_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector30.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector30_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector40.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector40_c.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector50.hpp create mode 100644 boost/mpl/vector/aux_/preprocessed/typeof_based/vector50_c.hpp create mode 100644 boost/mpl/vector/aux_/push_back.hpp create mode 100644 boost/mpl/vector/aux_/push_front.hpp create mode 100644 boost/mpl/vector/aux_/size.hpp create mode 100644 boost/mpl/vector/aux_/tag.hpp create mode 100644 boost/mpl/vector/aux_/vector0.hpp create mode 100644 boost/mpl/vector/vector0.hpp create mode 100644 boost/mpl/vector/vector0_c.hpp create mode 100644 boost/mpl/vector/vector10.hpp create mode 100644 boost/mpl/vector/vector10_c.hpp create mode 100644 boost/mpl/vector/vector20.hpp create mode 100644 boost/mpl/vector/vector20_c.hpp create mode 100644 boost/mpl/vector/vector30.hpp create mode 100644 boost/mpl/vector/vector30_c.hpp create mode 100644 boost/mpl/vector/vector40.hpp create mode 100644 boost/mpl/vector/vector40_c.hpp create mode 100644 boost/mpl/vector/vector50.hpp create mode 100644 boost/mpl/vector/vector50_c.hpp create mode 100644 boost/mpl/void.hpp create mode 100644 boost/mpl/void_fwd.hpp create mode 100644 boost/next_prior.hpp create mode 100644 boost/non_type.hpp create mode 100644 boost/noncopyable.hpp create mode 100644 boost/none.hpp create mode 100644 boost/none_t.hpp create mode 100644 boost/numeric/conversion/bounds.hpp create mode 100644 boost/numeric/conversion/cast.hpp create mode 100644 boost/numeric/conversion/conversion_traits.hpp create mode 100644 boost/numeric/conversion/converter.hpp create mode 100644 boost/numeric/conversion/converter_policies.hpp create mode 100644 boost/numeric/conversion/detail/bounds.hpp create mode 100644 boost/numeric/conversion/detail/conversion_traits.hpp create mode 100644 boost/numeric/conversion/detail/converter.hpp create mode 100644 boost/numeric/conversion/detail/int_float_mixture.hpp create mode 100644 boost/numeric/conversion/detail/is_subranged.hpp create mode 100644 boost/numeric/conversion/detail/meta.hpp create mode 100644 boost/numeric/conversion/detail/numeric_cast_traits.hpp create mode 100644 boost/numeric/conversion/detail/old_numeric_cast.hpp create mode 100644 boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp create mode 100644 boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp create mode 100644 boost/numeric/conversion/detail/sign_mixture.hpp create mode 100644 boost/numeric/conversion/detail/udt_builtin_mixture.hpp create mode 100644 boost/numeric/conversion/int_float_mixture_enum.hpp create mode 100644 boost/numeric/conversion/numeric_cast_traits.hpp create mode 100644 boost/numeric/conversion/sign_mixture_enum.hpp create mode 100644 boost/numeric/conversion/udt_builtin_mixture_enum.hpp create mode 100644 boost/operators.hpp create mode 100644 boost/optional.hpp create mode 100644 boost/optional/bad_optional_access.hpp create mode 100644 boost/optional/detail/old_optional_implementation.hpp create mode 100644 boost/optional/detail/optional_aligned_storage.hpp create mode 100644 boost/optional/detail/optional_config.hpp create mode 100644 boost/optional/detail/optional_factory_support.hpp create mode 100644 boost/optional/detail/optional_reference_spec.hpp create mode 100644 boost/optional/detail/optional_relops.hpp create mode 100644 boost/optional/detail/optional_swap.hpp create mode 100644 boost/optional/detail/optional_trivially_copyable_base.hpp create mode 100644 boost/optional/optional.hpp create mode 100644 boost/optional/optional_fwd.hpp create mode 100644 boost/pointee.hpp create mode 100644 boost/predef.h create mode 100644 boost/predef/architecture.h create mode 100644 boost/predef/architecture/alpha.h create mode 100644 boost/predef/architecture/arm.h create mode 100644 boost/predef/architecture/blackfin.h create mode 100644 boost/predef/architecture/convex.h create mode 100644 boost/predef/architecture/ia64.h create mode 100644 boost/predef/architecture/m68k.h create mode 100644 boost/predef/architecture/mips.h create mode 100644 boost/predef/architecture/parisc.h create mode 100644 boost/predef/architecture/ppc.h create mode 100644 boost/predef/architecture/pyramid.h create mode 100644 boost/predef/architecture/rs6k.h create mode 100644 boost/predef/architecture/sparc.h create mode 100644 boost/predef/architecture/superh.h create mode 100644 boost/predef/architecture/sys370.h create mode 100644 boost/predef/architecture/sys390.h create mode 100644 boost/predef/architecture/x86.h create mode 100644 boost/predef/architecture/x86/32.h create mode 100644 boost/predef/architecture/x86/64.h create mode 100644 boost/predef/architecture/z.h create mode 100644 boost/predef/compiler.h create mode 100644 boost/predef/compiler/borland.h create mode 100644 boost/predef/compiler/clang.h create mode 100644 boost/predef/compiler/comeau.h create mode 100644 boost/predef/compiler/compaq.h create mode 100644 boost/predef/compiler/diab.h create mode 100644 boost/predef/compiler/digitalmars.h create mode 100644 boost/predef/compiler/dignus.h create mode 100644 boost/predef/compiler/edg.h create mode 100644 boost/predef/compiler/ekopath.h create mode 100644 boost/predef/compiler/gcc.h create mode 100644 boost/predef/compiler/gcc_xml.h create mode 100644 boost/predef/compiler/greenhills.h create mode 100644 boost/predef/compiler/hp_acc.h create mode 100644 boost/predef/compiler/iar.h create mode 100644 boost/predef/compiler/ibm.h create mode 100644 boost/predef/compiler/intel.h create mode 100644 boost/predef/compiler/kai.h create mode 100644 boost/predef/compiler/llvm.h create mode 100644 boost/predef/compiler/metaware.h create mode 100644 boost/predef/compiler/metrowerks.h create mode 100644 boost/predef/compiler/microtec.h create mode 100644 boost/predef/compiler/mpw.h create mode 100644 boost/predef/compiler/palm.h create mode 100644 boost/predef/compiler/pgi.h create mode 100644 boost/predef/compiler/sgi_mipspro.h create mode 100644 boost/predef/compiler/sunpro.h create mode 100644 boost/predef/compiler/tendra.h create mode 100644 boost/predef/compiler/visualc.h create mode 100644 boost/predef/compiler/watcom.h create mode 100644 boost/predef/detail/_cassert.h create mode 100644 boost/predef/detail/_exception.h create mode 100644 boost/predef/detail/comp_detected.h create mode 100644 boost/predef/detail/endian_compat.h create mode 100644 boost/predef/detail/os_detected.h create mode 100644 boost/predef/detail/platform_detected.h create mode 100644 boost/predef/detail/test.h create mode 100644 boost/predef/detail/test_def.h create mode 100644 boost/predef/hardware.h create mode 100644 boost/predef/hardware/simd.h create mode 100644 boost/predef/hardware/simd/arm.h create mode 100644 boost/predef/hardware/simd/arm/versions.h create mode 100644 boost/predef/hardware/simd/ppc.h create mode 100644 boost/predef/hardware/simd/ppc/versions.h create mode 100644 boost/predef/hardware/simd/x86.h create mode 100644 boost/predef/hardware/simd/x86/versions.h create mode 100644 boost/predef/hardware/simd/x86_amd.h create mode 100644 boost/predef/hardware/simd/x86_amd/versions.h create mode 100644 boost/predef/language.h create mode 100644 boost/predef/language/objc.h create mode 100644 boost/predef/language/stdc.h create mode 100644 boost/predef/language/stdcpp.h create mode 100644 boost/predef/library.h create mode 100644 boost/predef/library/c.h create mode 100644 boost/predef/library/c/_prefix.h create mode 100644 boost/predef/library/c/cloudabi.h create mode 100644 boost/predef/library/c/gnu.h create mode 100644 boost/predef/library/c/uc.h create mode 100644 boost/predef/library/c/vms.h create mode 100644 boost/predef/library/c/zos.h create mode 100644 boost/predef/library/std.h create mode 100644 boost/predef/library/std/_prefix.h create mode 100644 boost/predef/library/std/cxx.h create mode 100644 boost/predef/library/std/dinkumware.h create mode 100644 boost/predef/library/std/libcomo.h create mode 100644 boost/predef/library/std/modena.h create mode 100644 boost/predef/library/std/msl.h create mode 100644 boost/predef/library/std/roguewave.h create mode 100644 boost/predef/library/std/sgi.h create mode 100644 boost/predef/library/std/stdcpp3.h create mode 100644 boost/predef/library/std/stlport.h create mode 100644 boost/predef/library/std/vacpp.h create mode 100644 boost/predef/make.h create mode 100644 boost/predef/os.h create mode 100644 boost/predef/os/aix.h create mode 100644 boost/predef/os/amigaos.h create mode 100644 boost/predef/os/android.h create mode 100644 boost/predef/os/beos.h create mode 100644 boost/predef/os/bsd.h create mode 100644 boost/predef/os/bsd/bsdi.h create mode 100644 boost/predef/os/bsd/dragonfly.h create mode 100644 boost/predef/os/bsd/free.h create mode 100644 boost/predef/os/bsd/net.h create mode 100644 boost/predef/os/bsd/open.h create mode 100644 boost/predef/os/cygwin.h create mode 100644 boost/predef/os/haiku.h create mode 100644 boost/predef/os/hpux.h create mode 100644 boost/predef/os/ios.h create mode 100644 boost/predef/os/irix.h create mode 100644 boost/predef/os/linux.h create mode 100644 boost/predef/os/macos.h create mode 100644 boost/predef/os/os400.h create mode 100644 boost/predef/os/qnxnto.h create mode 100644 boost/predef/os/solaris.h create mode 100644 boost/predef/os/unix.h create mode 100644 boost/predef/os/vms.h create mode 100644 boost/predef/os/windows.h create mode 100644 boost/predef/other.h create mode 100644 boost/predef/other/endian.h create mode 100644 boost/predef/other/workaround.h create mode 100644 boost/predef/platform.h create mode 100644 boost/predef/platform/cloudabi.h create mode 100644 boost/predef/platform/ios.h create mode 100644 boost/predef/platform/mingw.h create mode 100644 boost/predef/platform/mingw32.h create mode 100644 boost/predef/platform/mingw64.h create mode 100644 boost/predef/platform/windows_desktop.h create mode 100644 boost/predef/platform/windows_phone.h create mode 100644 boost/predef/platform/windows_runtime.h create mode 100644 boost/predef/platform/windows_server.h create mode 100644 boost/predef/platform/windows_store.h create mode 100644 boost/predef/platform/windows_system.h create mode 100644 boost/predef/platform/windows_uwp.h create mode 100644 boost/predef/version.h create mode 100644 boost/predef/version_number.h create mode 100644 boost/preprocessor/arithmetic/add.hpp create mode 100644 boost/preprocessor/arithmetic/dec.hpp create mode 100644 boost/preprocessor/arithmetic/detail/div_base.hpp create mode 100644 boost/preprocessor/arithmetic/inc.hpp create mode 100644 boost/preprocessor/arithmetic/mod.hpp create mode 100644 boost/preprocessor/arithmetic/sub.hpp create mode 100644 boost/preprocessor/array/data.hpp create mode 100644 boost/preprocessor/array/elem.hpp create mode 100644 boost/preprocessor/array/size.hpp create mode 100644 boost/preprocessor/cat.hpp create mode 100644 boost/preprocessor/comma_if.hpp create mode 100644 boost/preprocessor/comparison/equal.hpp create mode 100644 boost/preprocessor/comparison/less_equal.hpp create mode 100644 boost/preprocessor/comparison/not_equal.hpp create mode 100644 boost/preprocessor/config/config.hpp create mode 100644 boost/preprocessor/control/deduce_d.hpp create mode 100644 boost/preprocessor/control/detail/dmc/while.hpp create mode 100644 boost/preprocessor/control/detail/edg/while.hpp create mode 100644 boost/preprocessor/control/detail/msvc/while.hpp create mode 100644 boost/preprocessor/control/detail/while.hpp create mode 100644 boost/preprocessor/control/expr_if.hpp create mode 100644 boost/preprocessor/control/expr_iif.hpp create mode 100644 boost/preprocessor/control/if.hpp create mode 100644 boost/preprocessor/control/iif.hpp create mode 100644 boost/preprocessor/control/while.hpp create mode 100644 boost/preprocessor/debug/error.hpp create mode 100644 boost/preprocessor/dec.hpp create mode 100644 boost/preprocessor/detail/auto_rec.hpp create mode 100644 boost/preprocessor/detail/check.hpp create mode 100644 boost/preprocessor/detail/dmc/auto_rec.hpp create mode 100644 boost/preprocessor/detail/is_binary.hpp create mode 100644 boost/preprocessor/detail/split.hpp create mode 100644 boost/preprocessor/empty.hpp create mode 100644 boost/preprocessor/enum.hpp create mode 100644 boost/preprocessor/enum_params.hpp create mode 100644 boost/preprocessor/enum_params_with_a_default.hpp create mode 100644 boost/preprocessor/enum_shifted_params.hpp create mode 100644 boost/preprocessor/expr_if.hpp create mode 100644 boost/preprocessor/facilities/detail/is_empty.hpp create mode 100644 boost/preprocessor/facilities/empty.hpp create mode 100644 boost/preprocessor/facilities/expand.hpp create mode 100644 boost/preprocessor/facilities/identity.hpp create mode 100644 boost/preprocessor/facilities/intercept.hpp create mode 100644 boost/preprocessor/facilities/is_1.hpp create mode 100644 boost/preprocessor/facilities/is_empty.hpp create mode 100644 boost/preprocessor/facilities/is_empty_variadic.hpp create mode 100644 boost/preprocessor/facilities/overload.hpp create mode 100644 boost/preprocessor/identity.hpp create mode 100644 boost/preprocessor/inc.hpp create mode 100644 boost/preprocessor/iterate.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/lower1.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/lower2.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/lower3.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/lower4.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/lower5.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/upper1.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/upper2.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/upper3.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/upper4.hpp create mode 100644 boost/preprocessor/iteration/detail/bounds/upper5.hpp create mode 100644 boost/preprocessor/iteration/detail/finish.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/forward1.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/forward2.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/forward3.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/forward4.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/forward5.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/reverse1.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/reverse2.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/reverse3.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/reverse4.hpp create mode 100644 boost/preprocessor/iteration/detail/iter/reverse5.hpp create mode 100644 boost/preprocessor/iteration/detail/local.hpp create mode 100644 boost/preprocessor/iteration/detail/rlocal.hpp create mode 100644 boost/preprocessor/iteration/detail/self.hpp create mode 100644 boost/preprocessor/iteration/detail/start.hpp create mode 100644 boost/preprocessor/iteration/iterate.hpp create mode 100644 boost/preprocessor/iteration/local.hpp create mode 100644 boost/preprocessor/iteration/self.hpp create mode 100644 boost/preprocessor/list/adt.hpp create mode 100644 boost/preprocessor/list/detail/dmc/fold_left.hpp create mode 100644 boost/preprocessor/list/detail/edg/fold_left.hpp create mode 100644 boost/preprocessor/list/detail/edg/fold_right.hpp create mode 100644 boost/preprocessor/list/detail/fold_left.hpp create mode 100644 boost/preprocessor/list/detail/fold_right.hpp create mode 100644 boost/preprocessor/list/fold_left.hpp create mode 100644 boost/preprocessor/list/fold_right.hpp create mode 100644 boost/preprocessor/list/for_each_i.hpp create mode 100644 boost/preprocessor/list/reverse.hpp create mode 100644 boost/preprocessor/logical/and.hpp create mode 100644 boost/preprocessor/logical/bitand.hpp create mode 100644 boost/preprocessor/logical/bool.hpp create mode 100644 boost/preprocessor/logical/compl.hpp create mode 100644 boost/preprocessor/logical/not.hpp create mode 100644 boost/preprocessor/punctuation/comma.hpp create mode 100644 boost/preprocessor/punctuation/comma_if.hpp create mode 100644 boost/preprocessor/punctuation/detail/is_begin_parens.hpp create mode 100644 boost/preprocessor/punctuation/is_begin_parens.hpp create mode 100644 boost/preprocessor/repeat.hpp create mode 100644 boost/preprocessor/repetition/detail/dmc/for.hpp create mode 100644 boost/preprocessor/repetition/detail/edg/for.hpp create mode 100644 boost/preprocessor/repetition/detail/for.hpp create mode 100644 boost/preprocessor/repetition/detail/msvc/for.hpp create mode 100644 boost/preprocessor/repetition/enum.hpp create mode 100644 boost/preprocessor/repetition/enum_binary_params.hpp create mode 100644 boost/preprocessor/repetition/enum_params.hpp create mode 100644 boost/preprocessor/repetition/enum_params_with_a_default.hpp create mode 100644 boost/preprocessor/repetition/enum_shifted_params.hpp create mode 100644 boost/preprocessor/repetition/enum_trailing_params.hpp create mode 100644 boost/preprocessor/repetition/for.hpp create mode 100644 boost/preprocessor/repetition/repeat.hpp create mode 100644 boost/preprocessor/repetition/repeat_from_to.hpp create mode 100644 boost/preprocessor/seq/cat.hpp create mode 100644 boost/preprocessor/seq/detail/is_empty.hpp create mode 100644 boost/preprocessor/seq/detail/split.hpp create mode 100644 boost/preprocessor/seq/elem.hpp create mode 100644 boost/preprocessor/seq/enum.hpp create mode 100644 boost/preprocessor/seq/first_n.hpp create mode 100644 boost/preprocessor/seq/fold_left.hpp create mode 100644 boost/preprocessor/seq/for_each.hpp create mode 100644 boost/preprocessor/seq/for_each_i.hpp create mode 100644 boost/preprocessor/seq/rest_n.hpp create mode 100644 boost/preprocessor/seq/seq.hpp create mode 100644 boost/preprocessor/seq/size.hpp create mode 100644 boost/preprocessor/seq/subseq.hpp create mode 100644 boost/preprocessor/seq/to_tuple.hpp create mode 100644 boost/preprocessor/seq/transform.hpp create mode 100644 boost/preprocessor/slot/detail/counter.hpp create mode 100644 boost/preprocessor/slot/detail/def.hpp create mode 100644 boost/preprocessor/slot/detail/shared.hpp create mode 100644 boost/preprocessor/slot/detail/slot1.hpp create mode 100644 boost/preprocessor/slot/detail/slot2.hpp create mode 100644 boost/preprocessor/slot/detail/slot3.hpp create mode 100644 boost/preprocessor/slot/detail/slot4.hpp create mode 100644 boost/preprocessor/slot/detail/slot5.hpp create mode 100644 boost/preprocessor/slot/slot.hpp create mode 100644 boost/preprocessor/stringize.hpp create mode 100644 boost/preprocessor/tuple/detail/is_single_return.hpp create mode 100644 boost/preprocessor/tuple/eat.hpp create mode 100644 boost/preprocessor/tuple/elem.hpp create mode 100644 boost/preprocessor/tuple/rem.hpp create mode 100644 boost/preprocessor/tuple/size.hpp create mode 100644 boost/preprocessor/tuple/to_list.hpp create mode 100644 boost/preprocessor/variadic/elem.hpp create mode 100644 boost/preprocessor/variadic/size.hpp create mode 100644 boost/program_options.hpp create mode 100644 boost/program_options/cmdline.hpp create mode 100644 boost/program_options/config.hpp create mode 100644 boost/program_options/detail/cmdline.hpp create mode 100644 boost/program_options/detail/config_file.hpp create mode 100644 boost/program_options/detail/convert.hpp create mode 100644 boost/program_options/detail/parsers.hpp create mode 100644 boost/program_options/detail/utf8_codecvt_facet.hpp create mode 100644 boost/program_options/detail/value_semantic.hpp create mode 100644 boost/program_options/environment_iterator.hpp create mode 100644 boost/program_options/eof_iterator.hpp create mode 100644 boost/program_options/errors.hpp create mode 100644 boost/program_options/option.hpp create mode 100644 boost/program_options/options_description.hpp create mode 100644 boost/program_options/parsers.hpp create mode 100644 boost/program_options/positional_options.hpp create mode 100644 boost/program_options/value_semantic.hpp create mode 100644 boost/program_options/variables_map.hpp create mode 100644 boost/program_options/version.hpp create mode 100644 boost/progress.hpp create mode 100644 boost/range.hpp create mode 100644 boost/range/adaptor/adjacent_filtered.hpp create mode 100644 boost/range/adaptor/argument_fwd.hpp create mode 100644 boost/range/adaptor/copied.hpp create mode 100644 boost/range/adaptor/filtered.hpp create mode 100644 boost/range/adaptor/formatted.hpp create mode 100644 boost/range/adaptor/indexed.hpp create mode 100644 boost/range/adaptor/indirected.hpp create mode 100644 boost/range/adaptor/map.hpp create mode 100644 boost/range/adaptor/replaced.hpp create mode 100644 boost/range/adaptor/replaced_if.hpp create mode 100644 boost/range/adaptor/reversed.hpp create mode 100644 boost/range/adaptor/sliced.hpp create mode 100644 boost/range/adaptor/strided.hpp create mode 100644 boost/range/adaptor/tokenized.hpp create mode 100644 boost/range/adaptor/transformed.hpp create mode 100644 boost/range/adaptor/uniqued.hpp create mode 100644 boost/range/adaptors.hpp create mode 100644 boost/range/algorithm.hpp create mode 100644 boost/range/algorithm/adjacent_find.hpp create mode 100644 boost/range/algorithm/binary_search.hpp create mode 100644 boost/range/algorithm/copy.hpp create mode 100644 boost/range/algorithm/copy_backward.hpp create mode 100644 boost/range/algorithm/count.hpp create mode 100644 boost/range/algorithm/count_if.hpp create mode 100644 boost/range/algorithm/equal.hpp create mode 100644 boost/range/algorithm/equal_range.hpp create mode 100644 boost/range/algorithm/fill.hpp create mode 100644 boost/range/algorithm/fill_n.hpp create mode 100644 boost/range/algorithm/find.hpp create mode 100644 boost/range/algorithm/find_end.hpp create mode 100644 boost/range/algorithm/find_first_of.hpp create mode 100644 boost/range/algorithm/find_if.hpp create mode 100644 boost/range/algorithm/for_each.hpp create mode 100644 boost/range/algorithm/generate.hpp create mode 100644 boost/range/algorithm/heap_algorithm.hpp create mode 100644 boost/range/algorithm/inplace_merge.hpp create mode 100644 boost/range/algorithm/lexicographical_compare.hpp create mode 100644 boost/range/algorithm/lower_bound.hpp create mode 100644 boost/range/algorithm/max_element.hpp create mode 100644 boost/range/algorithm/merge.hpp create mode 100644 boost/range/algorithm/min_element.hpp create mode 100644 boost/range/algorithm/mismatch.hpp create mode 100644 boost/range/algorithm/nth_element.hpp create mode 100644 boost/range/algorithm/partial_sort.hpp create mode 100644 boost/range/algorithm/partial_sort_copy.hpp create mode 100644 boost/range/algorithm/partition.hpp create mode 100644 boost/range/algorithm/permutation.hpp create mode 100644 boost/range/algorithm/random_shuffle.hpp create mode 100644 boost/range/algorithm/remove.hpp create mode 100644 boost/range/algorithm/remove_copy.hpp create mode 100644 boost/range/algorithm/remove_copy_if.hpp create mode 100644 boost/range/algorithm/remove_if.hpp create mode 100644 boost/range/algorithm/replace.hpp create mode 100644 boost/range/algorithm/replace_copy.hpp create mode 100644 boost/range/algorithm/replace_copy_if.hpp create mode 100644 boost/range/algorithm/replace_if.hpp create mode 100644 boost/range/algorithm/reverse.hpp create mode 100644 boost/range/algorithm/reverse_copy.hpp create mode 100644 boost/range/algorithm/rotate.hpp create mode 100644 boost/range/algorithm/rotate_copy.hpp create mode 100644 boost/range/algorithm/search.hpp create mode 100644 boost/range/algorithm/search_n.hpp create mode 100644 boost/range/algorithm/set_algorithm.hpp create mode 100644 boost/range/algorithm/sort.hpp create mode 100644 boost/range/algorithm/stable_partition.hpp create mode 100644 boost/range/algorithm/stable_sort.hpp create mode 100644 boost/range/algorithm/transform.hpp create mode 100644 boost/range/algorithm/unique.hpp create mode 100644 boost/range/algorithm/unique_copy.hpp create mode 100644 boost/range/algorithm/upper_bound.hpp create mode 100644 boost/range/as_literal.hpp create mode 100644 boost/range/begin.hpp create mode 100644 boost/range/category.hpp create mode 100644 boost/range/concepts.hpp create mode 100644 boost/range/config.hpp create mode 100644 boost/range/const_iterator.hpp create mode 100644 boost/range/const_reverse_iterator.hpp create mode 100644 boost/range/detail/as_literal.hpp create mode 100644 boost/range/detail/begin.hpp create mode 100644 boost/range/detail/common.hpp create mode 100644 boost/range/detail/default_constructible_unary_fn.hpp create mode 100644 boost/range/detail/detail_str.hpp create mode 100644 boost/range/detail/end.hpp create mode 100644 boost/range/detail/extract_optional_type.hpp create mode 100644 boost/range/detail/has_member_size.hpp create mode 100644 boost/range/detail/implementation_help.hpp create mode 100644 boost/range/detail/misc_concept.hpp create mode 100644 boost/range/detail/msvc_has_iterator_workaround.hpp create mode 100644 boost/range/detail/range_return.hpp create mode 100644 boost/range/detail/remove_extent.hpp create mode 100644 boost/range/detail/safe_bool.hpp create mode 100644 boost/range/detail/sfinae.hpp create mode 100644 boost/range/detail/size_type.hpp create mode 100644 boost/range/detail/str_types.hpp create mode 100644 boost/range/detail/value_type.hpp create mode 100644 boost/range/difference_type.hpp create mode 100644 boost/range/distance.hpp create mode 100644 boost/range/empty.hpp create mode 100644 boost/range/end.hpp create mode 100644 boost/range/functions.hpp create mode 100644 boost/range/has_range_iterator.hpp create mode 100644 boost/range/iterator.hpp create mode 100644 boost/range/iterator_range.hpp create mode 100644 boost/range/iterator_range_core.hpp create mode 100644 boost/range/iterator_range_io.hpp create mode 100644 boost/range/metafunctions.hpp create mode 100644 boost/range/mutable_iterator.hpp create mode 100644 boost/range/pointer.hpp create mode 100644 boost/range/range_fwd.hpp create mode 100644 boost/range/rbegin.hpp create mode 100644 boost/range/reference.hpp create mode 100644 boost/range/rend.hpp create mode 100644 boost/range/result_iterator.hpp create mode 100644 boost/range/reverse_iterator.hpp create mode 100644 boost/range/reverse_result_iterator.hpp create mode 100644 boost/range/size.hpp create mode 100644 boost/range/size_type.hpp create mode 100644 boost/range/sub_range.hpp create mode 100644 boost/range/traversal.hpp create mode 100644 boost/range/value_type.hpp create mode 100644 boost/ratio/config.hpp create mode 100644 boost/ratio/detail/mpl/abs.hpp create mode 100644 boost/ratio/detail/mpl/gcd.hpp create mode 100644 boost/ratio/detail/mpl/lcm.hpp create mode 100644 boost/ratio/detail/mpl/sign.hpp create mode 100644 boost/ratio/detail/overflow_helpers.hpp create mode 100644 boost/ratio/detail/ratio_io.hpp create mode 100644 boost/ratio/mpl/rational_c_tag.hpp create mode 100644 boost/ratio/ratio.hpp create mode 100644 boost/ratio/ratio_fwd.hpp create mode 100644 boost/ratio/ratio_io.hpp create mode 100644 boost/rational.hpp create mode 100644 boost/ref.hpp create mode 100644 boost/regex.hpp create mode 100644 boost/regex/config.hpp create mode 100644 boost/regex/config/borland.hpp create mode 100644 boost/regex/config/cwchar.hpp create mode 100644 boost/regex/icu.hpp create mode 100644 boost/regex/pattern_except.hpp create mode 100644 boost/regex/pending/object_cache.hpp create mode 100644 boost/regex/pending/static_mutex.hpp create mode 100644 boost/regex/pending/unicode_iterator.hpp create mode 100644 boost/regex/regex_traits.hpp create mode 100644 boost/regex/user.hpp create mode 100644 boost/regex/v4/basic_regex.hpp create mode 100644 boost/regex/v4/basic_regex_creator.hpp create mode 100644 boost/regex/v4/basic_regex_parser.hpp create mode 100644 boost/regex/v4/c_regex_traits.hpp create mode 100644 boost/regex/v4/char_regex_traits.hpp create mode 100644 boost/regex/v4/cpp_regex_traits.hpp create mode 100644 boost/regex/v4/cregex.hpp create mode 100644 boost/regex/v4/error_type.hpp create mode 100644 boost/regex/v4/fileiter.hpp create mode 100644 boost/regex/v4/instances.hpp create mode 100644 boost/regex/v4/iterator_category.hpp create mode 100644 boost/regex/v4/iterator_traits.hpp create mode 100644 boost/regex/v4/match_flags.hpp create mode 100644 boost/regex/v4/match_results.hpp create mode 100644 boost/regex/v4/mem_block_cache.hpp create mode 100644 boost/regex/v4/perl_matcher.hpp create mode 100644 boost/regex/v4/perl_matcher_common.hpp create mode 100644 boost/regex/v4/perl_matcher_non_recursive.hpp create mode 100644 boost/regex/v4/perl_matcher_recursive.hpp create mode 100644 boost/regex/v4/primary_transform.hpp create mode 100644 boost/regex/v4/protected_call.hpp create mode 100644 boost/regex/v4/regbase.hpp create mode 100644 boost/regex/v4/regex.hpp create mode 100644 boost/regex/v4/regex_format.hpp create mode 100644 boost/regex/v4/regex_fwd.hpp create mode 100644 boost/regex/v4/regex_grep.hpp create mode 100644 boost/regex/v4/regex_iterator.hpp create mode 100644 boost/regex/v4/regex_match.hpp create mode 100644 boost/regex/v4/regex_merge.hpp create mode 100644 boost/regex/v4/regex_raw_buffer.hpp create mode 100644 boost/regex/v4/regex_replace.hpp create mode 100644 boost/regex/v4/regex_search.hpp create mode 100644 boost/regex/v4/regex_split.hpp create mode 100644 boost/regex/v4/regex_token_iterator.hpp create mode 100644 boost/regex/v4/regex_traits.hpp create mode 100644 boost/regex/v4/regex_traits_defaults.hpp create mode 100644 boost/regex/v4/regex_workaround.hpp create mode 100644 boost/regex/v4/states.hpp create mode 100644 boost/regex/v4/sub_match.hpp create mode 100644 boost/regex/v4/syntax_type.hpp create mode 100644 boost/regex/v4/u32regex_iterator.hpp create mode 100644 boost/regex/v4/u32regex_token_iterator.hpp create mode 100644 boost/regex/v4/w32_regex_traits.hpp create mode 100644 boost/regex_fwd.hpp create mode 100644 boost/scoped_array.hpp create mode 100644 boost/scoped_ptr.hpp create mode 100644 boost/shared_array.hpp create mode 100644 boost/shared_ptr.hpp create mode 100644 boost/smart_ptr.hpp create mode 100644 boost/smart_ptr/allocate_shared_array.hpp create mode 100644 boost/smart_ptr/bad_weak_ptr.hpp create mode 100644 boost/smart_ptr/detail/lightweight_mutex.hpp create mode 100644 boost/smart_ptr/detail/local_counted_base.hpp create mode 100644 boost/smart_ptr/detail/local_sp_deleter.hpp create mode 100644 boost/smart_ptr/detail/lwm_nop.hpp create mode 100644 boost/smart_ptr/detail/lwm_pthreads.hpp create mode 100644 boost/smart_ptr/detail/lwm_win32_cs.hpp create mode 100644 boost/smart_ptr/detail/operator_bool.hpp create mode 100644 boost/smart_ptr/detail/quick_allocator.hpp create mode 100644 boost/smart_ptr/detail/shared_count.hpp create mode 100644 boost/smart_ptr/detail/sp_convertible.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_aix.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_clang.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_nt.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_pt.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_spin.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_sync.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_base_w32.hpp create mode 100644 boost/smart_ptr/detail/sp_counted_impl.hpp create mode 100644 boost/smart_ptr/detail/sp_disable_deprecated.hpp create mode 100644 boost/smart_ptr/detail/sp_forward.hpp create mode 100644 boost/smart_ptr/detail/sp_has_sync.hpp create mode 100644 boost/smart_ptr/detail/sp_interlocked.hpp create mode 100644 boost/smart_ptr/detail/sp_noexcept.hpp create mode 100644 boost/smart_ptr/detail/sp_nullptr_t.hpp create mode 100644 boost/smart_ptr/detail/spinlock.hpp create mode 100644 boost/smart_ptr/detail/spinlock_gcc_arm.hpp create mode 100644 boost/smart_ptr/detail/spinlock_nt.hpp create mode 100644 boost/smart_ptr/detail/spinlock_pool.hpp create mode 100644 boost/smart_ptr/detail/spinlock_pt.hpp create mode 100644 boost/smart_ptr/detail/spinlock_std_atomic.hpp create mode 100644 boost/smart_ptr/detail/spinlock_sync.hpp create mode 100644 boost/smart_ptr/detail/spinlock_w32.hpp create mode 100644 boost/smart_ptr/detail/yield_k.hpp create mode 100644 boost/smart_ptr/enable_shared_from_this.hpp create mode 100644 boost/smart_ptr/intrusive_ptr.hpp create mode 100644 boost/smart_ptr/make_shared.hpp create mode 100644 boost/smart_ptr/make_shared_array.hpp create mode 100644 boost/smart_ptr/make_shared_object.hpp create mode 100644 boost/smart_ptr/scoped_array.hpp create mode 100644 boost/smart_ptr/scoped_ptr.hpp create mode 100644 boost/smart_ptr/shared_array.hpp create mode 100644 boost/smart_ptr/shared_ptr.hpp create mode 100644 boost/smart_ptr/weak_ptr.hpp create mode 100644 boost/static_assert.hpp create mode 100644 boost/swap.hpp create mode 100644 boost/system/api_config.hpp create mode 100644 boost/system/config.hpp create mode 100644 boost/system/cygwin_error.hpp create mode 100644 boost/system/detail/error_code.ipp create mode 100644 boost/system/detail/local_free_on_destruction.hpp create mode 100644 boost/system/error_code.hpp create mode 100644 boost/system/linux_error.hpp create mode 100644 boost/system/system_error.hpp create mode 100644 boost/system/windows_error.hpp create mode 100644 boost/test/debug.hpp create mode 100644 boost/test/debug_config.hpp create mode 100644 boost/test/detail/config.hpp create mode 100644 boost/test/detail/enable_warnings.hpp create mode 100644 boost/test/detail/fwd_decl.hpp create mode 100644 boost/test/detail/global_typedef.hpp create mode 100644 boost/test/detail/log_level.hpp create mode 100644 boost/test/detail/pp_variadic.hpp create mode 100644 boost/test/detail/suppress_warnings.hpp create mode 100644 boost/test/detail/throw_exception.hpp create mode 100644 boost/test/detail/workaround.hpp create mode 100644 boost/test/execution_monitor.hpp create mode 100644 boost/test/framework.hpp create mode 100644 boost/test/impl/compiler_log_formatter.ipp create mode 100644 boost/test/impl/cpp_main.ipp create mode 100644 boost/test/impl/debug.ipp create mode 100644 boost/test/impl/decorator.ipp create mode 100644 boost/test/impl/execution_monitor.ipp create mode 100644 boost/test/impl/framework.ipp create mode 100644 boost/test/impl/junit_log_formatter.ipp create mode 100644 boost/test/impl/plain_report_formatter.ipp create mode 100644 boost/test/impl/progress_monitor.ipp create mode 100644 boost/test/impl/results_collector.ipp create mode 100644 boost/test/impl/results_reporter.ipp create mode 100644 boost/test/impl/test_framework_init_observer.ipp create mode 100644 boost/test/impl/test_main.ipp create mode 100644 boost/test/impl/test_tools.ipp create mode 100644 boost/test/impl/test_tree.ipp create mode 100644 boost/test/impl/unit_test_log.ipp create mode 100644 boost/test/impl/unit_test_main.ipp create mode 100644 boost/test/impl/unit_test_monitor.ipp create mode 100644 boost/test/impl/unit_test_parameters.ipp create mode 100644 boost/test/impl/xml_log_formatter.ipp create mode 100644 boost/test/impl/xml_report_formatter.ipp create mode 100644 boost/test/included/prg_exec_monitor.hpp create mode 100644 boost/test/output/compiler_log_formatter.hpp create mode 100644 boost/test/output/junit_log_formatter.hpp create mode 100644 boost/test/output/plain_report_formatter.hpp create mode 100644 boost/test/output/xml_log_formatter.hpp create mode 100644 boost/test/output/xml_report_formatter.hpp create mode 100644 boost/test/prg_exec_monitor.hpp create mode 100644 boost/test/progress_monitor.hpp create mode 100644 boost/test/results_collector.hpp create mode 100644 boost/test/results_reporter.hpp create mode 100644 boost/test/test_framework_init_observer.hpp create mode 100644 boost/test/test_tools.hpp create mode 100644 boost/test/tools/assertion.hpp create mode 100644 boost/test/tools/assertion_result.hpp create mode 100644 boost/test/tools/collection_comparison_op.hpp create mode 100644 boost/test/tools/context.hpp create mode 100644 boost/test/tools/cstring_comparison_op.hpp create mode 100644 boost/test/tools/detail/bitwise_manip.hpp create mode 100644 boost/test/tools/detail/expression_holder.hpp create mode 100644 boost/test/tools/detail/fwd.hpp create mode 100644 boost/test/tools/detail/indirections.hpp create mode 100644 boost/test/tools/detail/it_pair.hpp create mode 100644 boost/test/tools/detail/lexicographic_manip.hpp create mode 100644 boost/test/tools/detail/per_element_manip.hpp create mode 100644 boost/test/tools/detail/print_helper.hpp create mode 100644 boost/test/tools/detail/tolerance_manip.hpp create mode 100644 boost/test/tools/floating_point_comparison.hpp create mode 100644 boost/test/tools/fpc_op.hpp create mode 100644 boost/test/tools/fpc_tolerance.hpp create mode 100644 boost/test/tools/interface.hpp create mode 100644 boost/test/tools/old/impl.hpp create mode 100644 boost/test/tools/old/interface.hpp create mode 100644 boost/test/tools/output_test_stream.hpp create mode 100644 boost/test/tree/auto_registration.hpp create mode 100644 boost/test/tree/decorator.hpp create mode 100644 boost/test/tree/fixture.hpp create mode 100644 boost/test/tree/global_fixture.hpp create mode 100644 boost/test/tree/observer.hpp create mode 100644 boost/test/tree/test_case_counter.hpp create mode 100644 boost/test/tree/test_case_template.hpp create mode 100644 boost/test/tree/test_unit.hpp create mode 100644 boost/test/tree/traverse.hpp create mode 100644 boost/test/tree/visitor.hpp create mode 100644 boost/test/unit_test_log.hpp create mode 100644 boost/test/unit_test_log_formatter.hpp create mode 100644 boost/test/unit_test_monitor.hpp create mode 100644 boost/test/unit_test_parameters.hpp create mode 100644 boost/test/unit_test_suite.hpp create mode 100644 boost/test/utils/algorithm.hpp create mode 100644 boost/test/utils/assign_op.hpp create mode 100644 boost/test/utils/basic_cstring/basic_cstring.hpp create mode 100644 boost/test/utils/basic_cstring/basic_cstring_fwd.hpp create mode 100644 boost/test/utils/basic_cstring/bcs_char_traits.hpp create mode 100644 boost/test/utils/basic_cstring/compare.hpp create mode 100644 boost/test/utils/basic_cstring/io.hpp create mode 100644 boost/test/utils/class_properties.hpp create mode 100644 boost/test/utils/custom_manip.hpp create mode 100644 boost/test/utils/foreach.hpp create mode 100644 boost/test/utils/is_cstring.hpp create mode 100644 boost/test/utils/is_forward_iterable.hpp create mode 100644 boost/test/utils/iterator/input_iterator_facade.hpp create mode 100644 boost/test/utils/iterator/token_iterator.hpp create mode 100644 boost/test/utils/lazy_ostream.hpp create mode 100644 boost/test/utils/named_params.hpp create mode 100644 boost/test/utils/rtti.hpp create mode 100644 boost/test/utils/runtime/argument.hpp create mode 100644 boost/test/utils/runtime/argument_factory.hpp create mode 100644 boost/test/utils/runtime/cla/argv_traverser.hpp create mode 100644 boost/test/utils/runtime/cla/parser.hpp create mode 100644 boost/test/utils/runtime/env/fetch.hpp create mode 100644 boost/test/utils/runtime/errors.hpp create mode 100644 boost/test/utils/runtime/finalize.hpp create mode 100644 boost/test/utils/runtime/fwd.hpp create mode 100644 boost/test/utils/runtime/modifier.hpp create mode 100644 boost/test/utils/runtime/parameter.hpp create mode 100644 boost/test/utils/setcolor.hpp create mode 100644 boost/test/utils/string_cast.hpp create mode 100644 boost/test/utils/trivial_singleton.hpp create mode 100644 boost/test/utils/wrap_stringstream.hpp create mode 100644 boost/test/utils/xml_printer.hpp create mode 100644 boost/thread.hpp create mode 100644 boost/thread/barrier.hpp create mode 100644 boost/thread/condition_variable.hpp create mode 100644 boost/thread/csbl/functional.hpp create mode 100644 boost/thread/csbl/memory/allocator_arg.hpp create mode 100644 boost/thread/csbl/memory/allocator_traits.hpp create mode 100644 boost/thread/csbl/memory/config.hpp create mode 100644 boost/thread/csbl/memory/pointer_traits.hpp create mode 100644 boost/thread/csbl/memory/scoped_allocator.hpp create mode 100644 boost/thread/csbl/memory/shared_ptr.hpp create mode 100644 boost/thread/csbl/memory/unique_ptr.hpp create mode 100644 boost/thread/csbl/tuple.hpp create mode 100644 boost/thread/csbl/vector.hpp create mode 100644 boost/thread/cv_status.hpp create mode 100644 boost/thread/detail/atomic_redef_macros.hpp create mode 100644 boost/thread/detail/atomic_undef_macros.hpp create mode 100644 boost/thread/detail/config.hpp create mode 100644 boost/thread/detail/delete.hpp create mode 100644 boost/thread/detail/invoke.hpp create mode 100644 boost/thread/detail/invoker.hpp create mode 100644 boost/thread/detail/is_convertible.hpp create mode 100644 boost/thread/detail/lockable_wrapper.hpp create mode 100644 boost/thread/detail/make_tuple_indices.hpp create mode 100644 boost/thread/detail/memory.hpp create mode 100644 boost/thread/detail/move.hpp create mode 100644 boost/thread/detail/nullary_function.hpp create mode 100644 boost/thread/detail/platform.hpp create mode 100644 boost/thread/detail/platform_time.hpp create mode 100644 boost/thread/detail/thread.hpp create mode 100644 boost/thread/detail/thread_group.hpp create mode 100644 boost/thread/detail/thread_heap_alloc.hpp create mode 100644 boost/thread/detail/thread_interruption.hpp create mode 100644 boost/thread/detail/tss_hooks.hpp create mode 100644 boost/thread/detail/variadic_footer.hpp create mode 100644 boost/thread/detail/variadic_header.hpp create mode 100644 boost/thread/exceptional_ptr.hpp create mode 100644 boost/thread/exceptions.hpp create mode 100644 boost/thread/executor.hpp create mode 100644 boost/thread/executors/executor.hpp create mode 100644 boost/thread/executors/executor_adaptor.hpp create mode 100644 boost/thread/executors/generic_executor_ref.hpp create mode 100644 boost/thread/executors/work.hpp create mode 100644 boost/thread/future.hpp create mode 100644 boost/thread/futures/future_error.hpp create mode 100644 boost/thread/futures/future_error_code.hpp create mode 100644 boost/thread/futures/future_status.hpp create mode 100644 boost/thread/futures/is_future_type.hpp create mode 100644 boost/thread/futures/launch.hpp create mode 100644 boost/thread/futures/wait_for_all.hpp create mode 100644 boost/thread/futures/wait_for_any.hpp create mode 100644 boost/thread/is_locked_by_this_thread.hpp create mode 100644 boost/thread/lock_algorithms.hpp create mode 100644 boost/thread/lock_guard.hpp create mode 100644 boost/thread/lock_options.hpp create mode 100644 boost/thread/lock_types.hpp create mode 100644 boost/thread/lockable_traits.hpp create mode 100644 boost/thread/locks.hpp create mode 100644 boost/thread/mutex.hpp create mode 100644 boost/thread/once.hpp create mode 100644 boost/thread/pthread/condition_variable.hpp create mode 100644 boost/thread/pthread/condition_variable_fwd.hpp create mode 100644 boost/thread/pthread/mutex.hpp create mode 100644 boost/thread/pthread/once.hpp create mode 100644 boost/thread/pthread/once_atomic.hpp create mode 100644 boost/thread/pthread/pthread_helpers.hpp create mode 100644 boost/thread/pthread/pthread_mutex_scoped_lock.hpp create mode 100644 boost/thread/pthread/recursive_mutex.hpp create mode 100644 boost/thread/pthread/shared_mutex.hpp create mode 100644 boost/thread/pthread/thread_data.hpp create mode 100644 boost/thread/pthread/thread_heap_alloc.hpp create mode 100644 boost/thread/recursive_mutex.hpp create mode 100644 boost/thread/shared_lock_guard.hpp create mode 100644 boost/thread/shared_mutex.hpp create mode 100644 boost/thread/thread.hpp create mode 100644 boost/thread/thread_only.hpp create mode 100644 boost/thread/thread_time.hpp create mode 100644 boost/thread/tss.hpp create mode 100644 boost/thread/v2/shared_mutex.hpp create mode 100644 boost/thread/win32/basic_recursive_mutex.hpp create mode 100644 boost/thread/win32/basic_timed_mutex.hpp create mode 100644 boost/thread/win32/condition_variable.hpp create mode 100644 boost/thread/win32/interlocked_read.hpp create mode 100644 boost/thread/win32/mutex.hpp create mode 100644 boost/thread/win32/once.hpp create mode 100644 boost/thread/win32/recursive_mutex.hpp create mode 100644 boost/thread/win32/shared_mutex.hpp create mode 100644 boost/thread/win32/thread_data.hpp create mode 100644 boost/thread/win32/thread_heap_alloc.hpp create mode 100644 boost/thread/win32/thread_primitives.hpp create mode 100644 boost/thread/xtime.hpp create mode 100644 boost/throw_exception.hpp create mode 100644 boost/timer.hpp create mode 100644 boost/timer/config.hpp create mode 100644 boost/timer/timer.hpp create mode 100644 boost/token_functions.hpp create mode 100644 boost/token_iterator.hpp create mode 100644 boost/tokenizer.hpp create mode 100644 boost/tuple/detail/tuple_basic.hpp create mode 100644 boost/tuple/tuple.hpp create mode 100644 boost/type.hpp create mode 100644 boost/type_index.hpp create mode 100644 boost/type_index/ctti_type_index.hpp create mode 100644 boost/type_index/detail/compile_time_type_info.hpp create mode 100644 boost/type_index/detail/ctti_register_class.hpp create mode 100644 boost/type_index/detail/stl_register_class.hpp create mode 100644 boost/type_index/stl_type_index.hpp create mode 100644 boost/type_index/type_index_facade.hpp create mode 100644 boost/type_traits/add_const.hpp create mode 100644 boost/type_traits/add_cv.hpp create mode 100644 boost/type_traits/add_lvalue_reference.hpp create mode 100644 boost/type_traits/add_pointer.hpp create mode 100644 boost/type_traits/add_reference.hpp create mode 100644 boost/type_traits/add_rvalue_reference.hpp create mode 100644 boost/type_traits/add_volatile.hpp create mode 100644 boost/type_traits/aligned_storage.hpp create mode 100644 boost/type_traits/alignment_of.hpp create mode 100644 boost/type_traits/common_type.hpp create mode 100644 boost/type_traits/composite_traits.hpp create mode 100644 boost/type_traits/conditional.hpp create mode 100644 boost/type_traits/conversion_traits.hpp create mode 100644 boost/type_traits/copy_cv.hpp create mode 100644 boost/type_traits/cv_traits.hpp create mode 100644 boost/type_traits/decay.hpp create mode 100644 boost/type_traits/declval.hpp create mode 100644 boost/type_traits/detail/bool_trait_undef.hpp create mode 100644 boost/type_traits/detail/common_arithmetic_type.hpp create mode 100644 boost/type_traits/detail/common_type_impl.hpp create mode 100644 boost/type_traits/detail/composite_member_pointer_type.hpp create mode 100644 boost/type_traits/detail/composite_pointer_type.hpp create mode 100644 boost/type_traits/detail/config.hpp create mode 100644 boost/type_traits/detail/has_binary_operator.hpp create mode 100644 boost/type_traits/detail/is_function_ptr_helper.hpp create mode 100644 boost/type_traits/detail/is_function_ptr_tester.hpp create mode 100644 boost/type_traits/detail/is_likely_lambda.hpp create mode 100644 boost/type_traits/detail/is_mem_fun_pointer_impl.hpp create mode 100644 boost/type_traits/detail/is_mem_fun_pointer_tester.hpp create mode 100644 boost/type_traits/detail/mp_defer.hpp create mode 100644 boost/type_traits/detail/yes_no_type.hpp create mode 100644 boost/type_traits/function_traits.hpp create mode 100644 boost/type_traits/has_left_shift.hpp create mode 100644 boost/type_traits/has_minus.hpp create mode 100644 boost/type_traits/has_minus_assign.hpp create mode 100644 boost/type_traits/has_nothrow_assign.hpp create mode 100644 boost/type_traits/has_nothrow_constructor.hpp create mode 100644 boost/type_traits/has_nothrow_copy.hpp create mode 100644 boost/type_traits/has_plus.hpp create mode 100644 boost/type_traits/has_plus_assign.hpp create mode 100644 boost/type_traits/has_right_shift.hpp create mode 100644 boost/type_traits/has_trivial_assign.hpp create mode 100644 boost/type_traits/has_trivial_constructor.hpp create mode 100644 boost/type_traits/has_trivial_copy.hpp create mode 100644 boost/type_traits/has_trivial_destructor.hpp create mode 100644 boost/type_traits/has_trivial_move_assign.hpp create mode 100644 boost/type_traits/has_trivial_move_constructor.hpp create mode 100644 boost/type_traits/integral_constant.hpp create mode 100644 boost/type_traits/intrinsics.hpp create mode 100644 boost/type_traits/is_abstract.hpp create mode 100644 boost/type_traits/is_arithmetic.hpp create mode 100644 boost/type_traits/is_array.hpp create mode 100644 boost/type_traits/is_assignable.hpp create mode 100644 boost/type_traits/is_base_and_derived.hpp create mode 100644 boost/type_traits/is_base_of.hpp create mode 100644 boost/type_traits/is_class.hpp create mode 100644 boost/type_traits/is_complete.hpp create mode 100644 boost/type_traits/is_const.hpp create mode 100644 boost/type_traits/is_constructible.hpp create mode 100644 boost/type_traits/is_convertible.hpp create mode 100644 boost/type_traits/is_copy_constructible.hpp create mode 100644 boost/type_traits/is_default_constructible.hpp create mode 100644 boost/type_traits/is_destructible.hpp create mode 100644 boost/type_traits/is_enum.hpp create mode 100644 boost/type_traits/is_float.hpp create mode 100644 boost/type_traits/is_floating_point.hpp create mode 100644 boost/type_traits/is_function.hpp create mode 100644 boost/type_traits/is_fundamental.hpp create mode 100644 boost/type_traits/is_integral.hpp create mode 100644 boost/type_traits/is_lvalue_reference.hpp create mode 100644 boost/type_traits/is_member_function_pointer.hpp create mode 100644 boost/type_traits/is_member_pointer.hpp create mode 100644 boost/type_traits/is_nothrow_move_assignable.hpp create mode 100644 boost/type_traits/is_nothrow_move_constructible.hpp create mode 100644 boost/type_traits/is_pod.hpp create mode 100644 boost/type_traits/is_pointer.hpp create mode 100644 boost/type_traits/is_polymorphic.hpp create mode 100644 boost/type_traits/is_reference.hpp create mode 100644 boost/type_traits/is_rvalue_reference.hpp create mode 100644 boost/type_traits/is_same.hpp create mode 100644 boost/type_traits/is_scalar.hpp create mode 100644 boost/type_traits/is_signed.hpp create mode 100644 boost/type_traits/is_union.hpp create mode 100644 boost/type_traits/is_unsigned.hpp create mode 100644 boost/type_traits/is_void.hpp create mode 100644 boost/type_traits/is_volatile.hpp create mode 100644 boost/type_traits/make_signed.hpp create mode 100644 boost/type_traits/make_unsigned.hpp create mode 100644 boost/type_traits/make_void.hpp create mode 100644 boost/type_traits/remove_all_extents.hpp create mode 100644 boost/type_traits/remove_bounds.hpp create mode 100644 boost/type_traits/remove_const.hpp create mode 100644 boost/type_traits/remove_cv.hpp create mode 100644 boost/type_traits/remove_extent.hpp create mode 100644 boost/type_traits/remove_pointer.hpp create mode 100644 boost/type_traits/remove_reference.hpp create mode 100644 boost/type_traits/remove_volatile.hpp create mode 100644 boost/type_traits/type_identity.hpp create mode 100644 boost/type_traits/type_with_alignment.hpp create mode 100644 boost/utility.hpp create mode 100644 boost/utility/addressof.hpp create mode 100644 boost/utility/base_from_member.hpp create mode 100644 boost/utility/binary.hpp create mode 100644 boost/utility/compare_pointees.hpp create mode 100644 boost/utility/declval.hpp create mode 100644 boost/utility/detail/result_of_iterate.hpp create mode 100644 boost/utility/enable_if.hpp create mode 100644 boost/utility/identity_type.hpp create mode 100644 boost/utility/result_of.hpp create mode 100644 boost/utility/swap.hpp create mode 100644 boost/utility/value_init.hpp create mode 100644 boost/version.hpp create mode 100644 boost/visit_each.hpp create mode 100644 boost/weak_ptr.hpp create mode 100644 boost/winapi/access_rights.hpp create mode 100644 boost/winapi/basic_types.hpp create mode 100644 boost/winapi/character_code_conversion.hpp create mode 100644 boost/winapi/config.hpp create mode 100644 boost/winapi/dll.hpp create mode 100644 boost/winapi/error_codes.hpp create mode 100644 boost/winapi/error_handling.hpp create mode 100644 boost/winapi/event.hpp create mode 100644 boost/winapi/get_current_process.hpp create mode 100644 boost/winapi/get_current_process_id.hpp create mode 100644 boost/winapi/get_current_thread.hpp create mode 100644 boost/winapi/get_current_thread_id.hpp create mode 100644 boost/winapi/get_last_error.hpp create mode 100644 boost/winapi/get_process_times.hpp create mode 100644 boost/winapi/get_thread_times.hpp create mode 100644 boost/winapi/handles.hpp create mode 100644 boost/winapi/heap_memory.hpp create mode 100644 boost/winapi/local_memory.hpp create mode 100644 boost/winapi/semaphore.hpp create mode 100644 boost/winapi/system.hpp create mode 100644 boost/winapi/thread.hpp create mode 100644 boost/winapi/thread_pool.hpp create mode 100644 boost/winapi/time.hpp create mode 100644 boost/winapi/timers.hpp create mode 100644 boost/winapi/wait.hpp create mode 100644 boostcpp.jam create mode 100644 bootstrap.bat create mode 100644 bootstrap.sh create mode 100644 build.cmd create mode 100644 doc/src/boostbook.css create mode 100644 doc/src/images/home.png create mode 100644 doc/src/images/important.png create mode 100644 doc/src/images/next.png create mode 100644 doc/src/images/prev.png create mode 100644 doc/src/images/up.png create mode 100644 doc/src/minimal.css create mode 100644 libs/atomic/build/Jamfile.v2 create mode 100644 libs/atomic/src/lockpool.cpp create mode 100644 libs/chrono/build/Jamfile.v2 create mode 100644 libs/chrono/src/chrono.cpp create mode 100644 libs/chrono/src/process_cpu_clocks.cpp create mode 100644 libs/chrono/src/thread_clock.cpp create mode 100644 libs/config/appveyor.bat create mode 100644 libs/config/checks/Jamfile.v2 create mode 100644 libs/config/checks/architecture/32.cpp create mode 100644 libs/config/checks/architecture/64.cpp create mode 100644 libs/config/checks/architecture/Jamroot.jam create mode 100644 libs/config/checks/architecture/arm.cpp create mode 100644 libs/config/checks/architecture/combined.cpp create mode 100644 libs/config/checks/architecture/mips1.cpp create mode 100644 libs/config/checks/architecture/power.cpp create mode 100644 libs/config/checks/architecture/sparc.cpp create mode 100644 libs/config/checks/architecture/x86.cpp create mode 100644 libs/config/checks/config.jam create mode 100644 libs/config/checks/test_case.cpp create mode 100644 libs/config/config.htm create mode 100644 libs/config/configure create mode 100644 libs/config/doc/Jamfile.v2 create mode 100644 libs/config/doc/acknowledgements.qbk create mode 100644 libs/config/doc/build_time.qbk create mode 100644 libs/config/doc/config.qbk create mode 100644 libs/config/doc/configuring_boost.qbk create mode 100644 libs/config/doc/cstdint.qbk create mode 100644 libs/config/doc/guidelines.qbk create mode 100644 libs/config/doc/html/HTML.manifest create mode 100644 libs/config/doc/html/boost_config/acknowledgements.html create mode 100644 libs/config/doc/html/boost_config/boost_macro_reference.html create mode 100644 libs/config/doc/html/boost_config/build_config.html create mode 100644 libs/config/doc/html/boost_config/cstdint.html create mode 100644 libs/config/doc/html/boost_config/guidelines_for_boost_authors.html create mode 100644 libs/config/doc/html/boost_config/rationale.html create mode 100644 libs/config/doc/html/index.html create mode 100644 libs/config/doc/html/standalone_HTML.manifest create mode 100644 libs/config/doc/macro_reference.qbk create mode 100644 libs/config/doc/rationale.qbk create mode 100644 libs/config/index.html create mode 100644 libs/config/meta/libraries.json create mode 100644 libs/config/test/Jamfile.v2 create mode 100644 libs/config/test/abi/abi_test.cpp create mode 100644 libs/config/test/abi/abi_test.hpp create mode 100644 libs/config/test/abi/main.cpp create mode 100644 libs/config/test/all/Jamfile.v2 create mode 100644 libs/config/test/all/options_v2.jam create mode 100644 libs/config/test/boost_fallthrough_test.cpp create mode 100644 libs/config/test/boost_has_2arg_use_facet.ipp create mode 100644 libs/config/test/boost_has_bethreads.ipp create mode 100644 libs/config/test/boost_has_clock_gettime.ipp create mode 100644 libs/config/test/boost_has_dirent_h.ipp create mode 100644 libs/config/test/boost_has_expm1.ipp create mode 100644 libs/config/test/boost_has_float128.ipp create mode 100644 libs/config/test/boost_has_ftime.ipp create mode 100644 libs/config/test/boost_has_getsystemtimeasfiletime.ipp create mode 100644 libs/config/test/boost_has_gettimeofday.ipp create mode 100644 libs/config/test/boost_has_hash.ipp create mode 100644 libs/config/test/boost_has_int128.ipp create mode 100644 libs/config/test/boost_has_log1p.ipp create mode 100644 libs/config/test/boost_has_long_long.ipp create mode 100644 libs/config/test/boost_has_macro_use_facet.ipp create mode 100644 libs/config/test/boost_has_ms_int64.ipp create mode 100644 libs/config/test/boost_has_nanosleep.ipp create mode 100644 libs/config/test/boost_has_nl_types_h.ipp create mode 100644 libs/config/test/boost_has_nrvo.ipp create mode 100644 libs/config/test/boost_has_part_alloc.ipp create mode 100644 libs/config/test/boost_has_pthread_delay_np.ipp create mode 100644 libs/config/test/boost_has_pthread_ma_st.ipp create mode 100644 libs/config/test/boost_has_pthread_yield.ipp create mode 100644 libs/config/test/boost_has_pthreads.ipp create mode 100644 libs/config/test/boost_has_rvalue_refs.ipp create mode 100644 libs/config/test/boost_has_sched_yield.ipp create mode 100644 libs/config/test/boost_has_sgi_type_traits.ipp create mode 100644 libs/config/test/boost_has_sigaction.ipp create mode 100644 libs/config/test/boost_has_slist.ipp create mode 100644 libs/config/test/boost_has_static_assert.ipp create mode 100644 libs/config/test/boost_has_stdint_h.ipp create mode 100644 libs/config/test/boost_has_stlp_use_facet.ipp create mode 100644 libs/config/test/boost_has_unistd_h.ipp create mode 100644 libs/config/test/boost_has_variadic_tmpl.ipp create mode 100644 libs/config/test/boost_has_vc6_mem_templ.ipp create mode 100644 libs/config/test/boost_has_vc_iterator.ipp create mode 100644 libs/config/test/boost_has_winthreads.ipp create mode 100644 libs/config/test/boost_no_adl_barrier.ipp create mode 100644 libs/config/test/boost_no_arg_dep_lookup.ipp create mode 100644 libs/config/test/boost_no_array_type_spec.ipp create mode 100644 libs/config/test/boost_no_auto_declarations.ipp create mode 100644 libs/config/test/boost_no_auto_multidecl.ipp create mode 100644 libs/config/test/boost_no_auto_ptr.ipp create mode 100644 libs/config/test/boost_no_bcb_partial_spec.ipp create mode 100644 libs/config/test/boost_no_char16_t.ipp create mode 100644 libs/config/test/boost_no_char32_t.ipp create mode 100644 libs/config/test/boost_no_com_value_init.ipp create mode 100644 libs/config/test/boost_no_constexpr.ipp create mode 100644 libs/config/test/boost_no_ctype_functions.ipp create mode 100644 libs/config/test/boost_no_cv_spec.ipp create mode 100644 libs/config/test/boost_no_cv_void_spec.ipp create mode 100644 libs/config/test/boost_no_cwchar.ipp create mode 100644 libs/config/test/boost_no_cwctype.ipp create mode 100644 libs/config/test/boost_no_cxx11_addressof.ipp create mode 100644 libs/config/test/boost_no_cxx11_alignas.ipp create mode 100644 libs/config/test/boost_no_cxx11_allocator.ipp create mode 100644 libs/config/test/boost_no_cxx11_atomic_sp.ipp create mode 100644 libs/config/test/boost_no_cxx11_defaulted_moves.ipp create mode 100644 libs/config/test/boost_no_cxx11_final.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_array.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_atomic.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_chrono.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_codecvt.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_condition_variable.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_forward_list.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_future.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_initializer_list.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_mutex.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_random.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_ratio.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_regex.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_system_error.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_thread.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_tuple.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_type_traits.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_typeindex.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_unordered_map.ipp create mode 100644 libs/config/test/boost_no_cxx11_hdr_unordered_set.ipp create mode 100644 libs/config/test/boost_no_cxx11_inline_namespaces.ipp create mode 100644 libs/config/test/boost_no_cxx11_non_pub_def_fun.ipp create mode 100644 libs/config/test/boost_no_cxx11_numeric_limits.ipp create mode 100644 libs/config/test/boost_no_cxx11_pointer_traits.ipp create mode 100644 libs/config/test/boost_no_cxx11_ref_qualifiers.ipp create mode 100644 libs/config/test/boost_no_cxx11_sfinae_expr.ipp create mode 100644 libs/config/test/boost_no_cxx11_smart_ptr.ipp create mode 100644 libs/config/test/boost_no_cxx11_std_align.ipp create mode 100644 libs/config/test/boost_no_cxx11_thread_local.ipp create mode 100644 libs/config/test/boost_no_cxx11_trailing_result_types.ipp create mode 100644 libs/config/test/boost_no_cxx11_user_lit.ipp create mode 100644 libs/config/test/boost_no_cxx14_binary_literals.ipp create mode 100644 libs/config/test/boost_no_cxx14_constexpr.ipp create mode 100644 libs/config/test/boost_no_cxx14_decltype_auto.ipp create mode 100644 libs/config/test/boost_no_cxx14_digit_separator.ipp create mode 100644 libs/config/test/boost_no_cxx14_generic_lambda.ipp create mode 100644 libs/config/test/boost_no_cxx14_hdr_shared_mutex.ipp create mode 100644 libs/config/test/boost_no_cxx14_lambda_capture.ipp create mode 100644 libs/config/test/boost_no_cxx14_member_init.ipp create mode 100644 libs/config/test/boost_no_cxx14_return_type_ded.ipp create mode 100644 libs/config/test/boost_no_cxx14_std_exchange.ipp create mode 100644 libs/config/test/boost_no_cxx14_var_templ.ipp create mode 100644 libs/config/test/boost_no_cxx17_fold_expressions.ipp create mode 100644 libs/config/test/boost_no_cxx17_inline_variables.ipp create mode 100644 libs/config/test/boost_no_cxx17_iterator_traits.ipp create mode 100644 libs/config/test/boost_no_cxx17_std_apply.ipp create mode 100644 libs/config/test/boost_no_cxx17_std_invoke.ipp create mode 100644 libs/config/test/boost_no_cxx17_structured_bindings.ipp create mode 100644 libs/config/test/boost_no_cxx98_binders.ipp create mode 100644 libs/config/test/boost_no_cxx98_function_base.ipp create mode 100644 libs/config/test/boost_no_cxx98_random_shuffle.ipp create mode 100644 libs/config/test/boost_no_cxx_hdr_functional.ipp create mode 100644 libs/config/test/boost_no_decltype.ipp create mode 100644 libs/config/test/boost_no_decltype_n3276.ipp create mode 100644 libs/config/test/boost_no_ded_typename.ipp create mode 100644 libs/config/test/boost_no_defaulted_functions.ipp create mode 100644 libs/config/test/boost_no_deleted_functions.ipp create mode 100644 libs/config/test/boost_no_dep_nested_class.ipp create mode 100644 libs/config/test/boost_no_dep_val_param.ipp create mode 100644 libs/config/test/boost_no_excep_std.ipp create mode 100644 libs/config/test/boost_no_exceptions.ipp create mode 100644 libs/config/test/boost_no_exp_func_tem_arg.ipp create mode 100644 libs/config/test/boost_no_explicit_cvt_ops.ipp create mode 100644 libs/config/test/boost_no_extern_template.ipp create mode 100644 libs/config/test/boost_no_fenv_h.ipp create mode 100644 libs/config/test/boost_no_fixed_len_variadic_templates.ipp create mode 100644 libs/config/test/boost_no_func_tmp_order.ipp create mode 100644 libs/config/test/boost_no_function_template_default_args.ipp create mode 100644 libs/config/test/boost_no_function_type_spec.ipp create mode 100644 libs/config/test/boost_no_i64_limits.ipp create mode 100644 libs/config/test/boost_no_inline_memb_init.ipp create mode 100644 libs/config/test/boost_no_integral_int64_t.ipp create mode 100644 libs/config/test/boost_no_iosfwd.ipp create mode 100644 libs/config/test/boost_no_iostream.ipp create mode 100644 libs/config/test/boost_no_is_abstract.ipp create mode 100644 libs/config/test/boost_no_iter_construct.ipp create mode 100644 libs/config/test/boost_no_lambdas.ipp create mode 100644 libs/config/test/boost_no_limits.ipp create mode 100644 libs/config/test/boost_no_limits_const_exp.ipp create mode 100644 libs/config/test/boost_no_ll_limits.ipp create mode 100644 libs/config/test/boost_no_long_long.ipp create mode 100644 libs/config/test/boost_no_mem_func_spec.ipp create mode 100644 libs/config/test/boost_no_mem_tem_keyword.ipp create mode 100644 libs/config/test/boost_no_mem_tem_pnts.ipp create mode 100644 libs/config/test/boost_no_mem_templ_frnds.ipp create mode 100644 libs/config/test/boost_no_mem_templates.ipp create mode 100644 libs/config/test/boost_no_nested_friendship.ipp create mode 100644 libs/config/test/boost_no_noexcept.ipp create mode 100644 libs/config/test/boost_no_nullptr.ipp create mode 100644 libs/config/test/boost_no_ops_in_namespace.ipp create mode 100644 libs/config/test/boost_no_part_spec_def_args.ipp create mode 100644 libs/config/test/boost_no_partial_spec.ipp create mode 100644 libs/config/test/boost_no_priv_aggregate.ipp create mode 100644 libs/config/test/boost_no_ptr_mem_const.ipp create mode 100644 libs/config/test/boost_no_range_based_for.ipp create mode 100644 libs/config/test/boost_no_raw_literals.ipp create mode 100644 libs/config/test/boost_no_restrict_references.ipp create mode 100644 libs/config/test/boost_no_ret_det.ipp create mode 100644 libs/config/test/boost_no_rtti.ipp create mode 100644 libs/config/test/boost_no_rvalue_references.ipp create mode 100644 libs/config/test/boost_no_scoped_enums.ipp create mode 100644 libs/config/test/boost_no_sfinae.ipp create mode 100644 libs/config/test/boost_no_sfinae_expr.ipp create mode 100644 libs/config/test/boost_no_sstream.ipp create mode 100644 libs/config/test/boost_no_static_assert.ipp create mode 100644 libs/config/test/boost_no_std_allocator.ipp create mode 100644 libs/config/test/boost_no_std_distance.ipp create mode 100644 libs/config/test/boost_no_std_iter_traits.ipp create mode 100644 libs/config/test/boost_no_std_iterator.ipp create mode 100644 libs/config/test/boost_no_std_locale.ipp create mode 100644 libs/config/test/boost_no_std_messages.ipp create mode 100644 libs/config/test/boost_no_std_min_max.ipp create mode 100644 libs/config/test/boost_no_std_oi_assign.ipp create mode 100644 libs/config/test/boost_no_std_typeinfo.ipp create mode 100644 libs/config/test/boost_no_std_use_facet.ipp create mode 100644 libs/config/test/boost_no_std_wstreambuf.ipp create mode 100644 libs/config/test/boost_no_std_wstring.ipp create mode 100644 libs/config/test/boost_no_stdc_namespace.ipp create mode 100644 libs/config/test/boost_no_swprintf.ipp create mode 100644 libs/config/test/boost_no_tem_local_classes.ipp create mode 100644 libs/config/test/boost_no_template_aliases.ipp create mode 100644 libs/config/test/boost_no_template_streams.ipp create mode 100644 libs/config/test/boost_no_template_template.ipp create mode 100644 libs/config/test/boost_no_two_phase_lookup.ipp create mode 100644 libs/config/test/boost_no_typeid.ipp create mode 100644 libs/config/test/boost_no_typename_with_ctor.ipp create mode 100644 libs/config/test/boost_no_unicode_literals.ipp create mode 100644 libs/config/test/boost_no_unified_init.ipp create mode 100644 libs/config/test/boost_no_using_breaks_adl.ipp create mode 100644 libs/config/test/boost_no_using_decl_overld.ipp create mode 100644 libs/config/test/boost_no_using_template.ipp create mode 100644 libs/config/test/boost_no_variadic_macros.ipp create mode 100644 libs/config/test/boost_no_variadic_templates.ipp create mode 100644 libs/config/test/boost_no_void_returns.ipp create mode 100644 libs/config/test/boost_no_wchar_t.ipp create mode 100644 libs/config/test/cmd_line_check.cpp create mode 100644 libs/config/test/config_build_check.cpp create mode 100644 libs/config/test/config_info.cpp create mode 100644 libs/config/test/config_test.cpp create mode 100644 libs/config/test/config_test_c.c create mode 100644 libs/config/test/cstdint_include_test.cpp create mode 100644 libs/config/test/cstdint_test.cpp create mode 100644 libs/config/test/cstdint_test2.cpp create mode 100644 libs/config/test/has_2arg_use_facet_fail.cpp create mode 100644 libs/config/test/has_2arg_use_facet_pass.cpp create mode 100644 libs/config/test/has_bethreads_fail.cpp create mode 100644 libs/config/test/has_bethreads_pass.cpp create mode 100644 libs/config/test/has_clock_gettime_fail.cpp create mode 100644 libs/config/test/has_clock_gettime_pass.cpp create mode 100644 libs/config/test/has_dirent_h_fail.cpp create mode 100644 libs/config/test/has_dirent_h_pass.cpp create mode 100644 libs/config/test/has_expm1_fail.cpp create mode 100644 libs/config/test/has_expm1_pass.cpp create mode 100644 libs/config/test/has_float128_fail.cpp create mode 100644 libs/config/test/has_float128_pass.cpp create mode 100644 libs/config/test/has_ftime_fail.cpp create mode 100644 libs/config/test/has_ftime_pass.cpp create mode 100644 libs/config/test/has_getsystemtimeasfiletime_fail.cpp create mode 100644 libs/config/test/has_getsystemtimeasfiletime_pass.cpp create mode 100644 libs/config/test/has_gettimeofday_fail.cpp create mode 100644 libs/config/test/has_gettimeofday_pass.cpp create mode 100644 libs/config/test/has_hash_fail.cpp create mode 100644 libs/config/test/has_hash_pass.cpp create mode 100644 libs/config/test/has_int128_fail.cpp create mode 100644 libs/config/test/has_int128_pass.cpp create mode 100644 libs/config/test/has_log1p_fail.cpp create mode 100644 libs/config/test/has_log1p_pass.cpp create mode 100644 libs/config/test/has_long_long_fail.cpp create mode 100644 libs/config/test/has_long_long_pass.cpp create mode 100644 libs/config/test/has_macro_use_facet_fail.cpp create mode 100644 libs/config/test/has_macro_use_facet_pass.cpp create mode 100644 libs/config/test/has_ms_int64_fail.cpp create mode 100644 libs/config/test/has_ms_int64_pass.cpp create mode 100644 libs/config/test/has_nanosleep_fail.cpp create mode 100644 libs/config/test/has_nanosleep_pass.cpp create mode 100644 libs/config/test/has_nl_types_h_fail.cpp create mode 100644 libs/config/test/has_nl_types_h_pass.cpp create mode 100644 libs/config/test/has_nrvo_fail.cpp create mode 100644 libs/config/test/has_nrvo_pass.cpp create mode 100644 libs/config/test/has_part_alloc_fail.cpp create mode 100644 libs/config/test/has_part_alloc_pass.cpp create mode 100644 libs/config/test/has_pthread_delay_np_fail.cpp create mode 100644 libs/config/test/has_pthread_delay_np_pass.cpp create mode 100644 libs/config/test/has_pthread_ma_st_fail.cpp create mode 100644 libs/config/test/has_pthread_ma_st_pass.cpp create mode 100644 libs/config/test/has_pthread_yield_fail.cpp create mode 100644 libs/config/test/has_pthread_yield_pass.cpp create mode 100644 libs/config/test/has_pthreads_fail.cpp create mode 100644 libs/config/test/has_pthreads_pass.cpp create mode 100644 libs/config/test/has_rvalue_refs_fail.cpp create mode 100644 libs/config/test/has_rvalue_refs_pass.cpp create mode 100644 libs/config/test/has_sched_yield_fail.cpp create mode 100644 libs/config/test/has_sched_yield_pass.cpp create mode 100644 libs/config/test/has_sgi_type_traits_fail.cpp create mode 100644 libs/config/test/has_sgi_type_traits_pass.cpp create mode 100644 libs/config/test/has_sigaction_fail.cpp create mode 100644 libs/config/test/has_sigaction_pass.cpp create mode 100644 libs/config/test/has_slist_fail.cpp create mode 100644 libs/config/test/has_slist_pass.cpp create mode 100644 libs/config/test/has_static_assert_fail.cpp create mode 100644 libs/config/test/has_static_assert_pass.cpp create mode 100644 libs/config/test/has_stdint_h_fail.cpp create mode 100644 libs/config/test/has_stdint_h_pass.cpp create mode 100644 libs/config/test/has_stlp_use_facet_fail.cpp create mode 100644 libs/config/test/has_stlp_use_facet_pass.cpp create mode 100644 libs/config/test/has_unistd_h_fail.cpp create mode 100644 libs/config/test/has_unistd_h_pass.cpp create mode 100644 libs/config/test/has_variadic_tmpl_fail.cpp create mode 100644 libs/config/test/has_variadic_tmpl_pass.cpp create mode 100644 libs/config/test/has_vc6_mem_templ_fail.cpp create mode 100644 libs/config/test/has_vc6_mem_templ_pass.cpp create mode 100644 libs/config/test/has_vc_iterator_fail.cpp create mode 100644 libs/config/test/has_vc_iterator_pass.cpp create mode 100644 libs/config/test/has_winthreads_fail.cpp create mode 100644 libs/config/test/has_winthreads_pass.cpp create mode 100644 libs/config/test/header_deprecated_test.cpp create mode 100644 libs/config/test/helper_macro_test.cpp create mode 100644 libs/config/test/helper_macros_test.cpp create mode 100644 libs/config/test/limits_test.cpp create mode 100644 libs/config/test/link/Jamfile.v2 create mode 100644 libs/config/test/link/bc_gen.sh create mode 100644 libs/config/test/link/borland.mak create mode 100644 libs/config/test/link/common.sh create mode 100644 libs/config/test/link/link_test.cpp create mode 100644 libs/config/test/link/link_test.hpp create mode 100644 libs/config/test/link/main.cpp create mode 100644 libs/config/test/link/test/Jamfile.v2 create mode 100644 libs/config/test/link/vc6-stlport.mak create mode 100644 libs/config/test/link/vc6.mak create mode 100644 libs/config/test/link/vc7-stlport.mak create mode 100644 libs/config/test/link/vc7.mak create mode 100644 libs/config/test/link/vc71-stlport.mak create mode 100644 libs/config/test/link/vc71.mak create mode 100644 libs/config/test/link/vc_gen.sh create mode 100644 libs/config/test/math_info.cpp create mode 100644 libs/config/test/no_adl_barrier_fail.cpp create mode 100644 libs/config/test/no_adl_barrier_pass.cpp create mode 100644 libs/config/test/no_arg_dep_lookup_fail.cpp create mode 100644 libs/config/test/no_arg_dep_lookup_pass.cpp create mode 100644 libs/config/test/no_array_type_spec_fail.cpp create mode 100644 libs/config/test/no_array_type_spec_pass.cpp create mode 100644 libs/config/test/no_auto_declarations_fail.cpp create mode 100644 libs/config/test/no_auto_declarations_pass.cpp create mode 100644 libs/config/test/no_auto_multidecl_fail.cpp create mode 100644 libs/config/test/no_auto_multidecl_pass.cpp create mode 100644 libs/config/test/no_auto_ptr_fail.cpp create mode 100644 libs/config/test/no_auto_ptr_pass.cpp create mode 100644 libs/config/test/no_bcb_partial_spec_fail.cpp create mode 100644 libs/config/test/no_bcb_partial_spec_pass.cpp create mode 100644 libs/config/test/no_char16_t_fail.cpp create mode 100644 libs/config/test/no_char16_t_pass.cpp create mode 100644 libs/config/test/no_char32_t_fail.cpp create mode 100644 libs/config/test/no_char32_t_pass.cpp create mode 100644 libs/config/test/no_com_value_init_fail.cpp create mode 100644 libs/config/test/no_com_value_init_pass.cpp create mode 100644 libs/config/test/no_constexpr_fail.cpp create mode 100644 libs/config/test/no_constexpr_pass.cpp create mode 100644 libs/config/test/no_ctype_functions_fail.cpp create mode 100644 libs/config/test/no_ctype_functions_pass.cpp create mode 100644 libs/config/test/no_cv_spec_fail.cpp create mode 100644 libs/config/test/no_cv_spec_pass.cpp create mode 100644 libs/config/test/no_cv_void_spec_fail.cpp create mode 100644 libs/config/test/no_cv_void_spec_pass.cpp create mode 100644 libs/config/test/no_cwchar_fail.cpp create mode 100644 libs/config/test/no_cwchar_pass.cpp create mode 100644 libs/config/test/no_cwctype_fail.cpp create mode 100644 libs/config/test/no_cwctype_pass.cpp create mode 100644 libs/config/test/no_cxx11_addressof_fail.cpp create mode 100644 libs/config/test/no_cxx11_addressof_pass.cpp create mode 100644 libs/config/test/no_cxx11_alignas_fail.cpp create mode 100644 libs/config/test/no_cxx11_alignas_pass.cpp create mode 100644 libs/config/test/no_cxx11_allocator_fail.cpp create mode 100644 libs/config/test/no_cxx11_allocator_pass.cpp create mode 100644 libs/config/test/no_cxx11_atomic_sp_fail.cpp create mode 100644 libs/config/test/no_cxx11_atomic_sp_pass.cpp create mode 100644 libs/config/test/no_cxx11_defaulted_moves_fail.cpp create mode 100644 libs/config/test/no_cxx11_defaulted_moves_pass.cpp create mode 100644 libs/config/test/no_cxx11_final_fail.cpp create mode 100644 libs/config/test/no_cxx11_final_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_array_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_array_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_atomic_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_atomic_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_chrono_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_chrono_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_codecvt_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_codecvt_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_condition_variable_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_condition_variable_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_forward_list_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_forward_list_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_future_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_future_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_initializer_list_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_initializer_list_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_mutex_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_mutex_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_random_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_random_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_ratio_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_ratio_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_regex_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_regex_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_system_error_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_system_error_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_thread_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_thread_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_tuple_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_tuple_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_type_traits_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_type_traits_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_typeindex_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_typeindex_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_unordered_map_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_unordered_map_pass.cpp create mode 100644 libs/config/test/no_cxx11_hdr_unordered_set_fail.cpp create mode 100644 libs/config/test/no_cxx11_hdr_unordered_set_pass.cpp create mode 100644 libs/config/test/no_cxx11_inline_namespaces_fail.cpp create mode 100644 libs/config/test/no_cxx11_inline_namespaces_pass.cpp create mode 100644 libs/config/test/no_cxx11_non_pub_def_fun_fail.cpp create mode 100644 libs/config/test/no_cxx11_non_pub_def_fun_pass.cpp create mode 100644 libs/config/test/no_cxx11_numeric_limits_fail.cpp create mode 100644 libs/config/test/no_cxx11_numeric_limits_pass.cpp create mode 100644 libs/config/test/no_cxx11_pointer_traits_fail.cpp create mode 100644 libs/config/test/no_cxx11_pointer_traits_pass.cpp create mode 100644 libs/config/test/no_cxx11_ref_qualifiers_fail.cpp create mode 100644 libs/config/test/no_cxx11_ref_qualifiers_pass.cpp create mode 100644 libs/config/test/no_cxx11_sfinae_expr_fail.cpp create mode 100644 libs/config/test/no_cxx11_sfinae_expr_pass.cpp create mode 100644 libs/config/test/no_cxx11_smart_ptr_fail.cpp create mode 100644 libs/config/test/no_cxx11_smart_ptr_pass.cpp create mode 100644 libs/config/test/no_cxx11_std_align_fail.cpp create mode 100644 libs/config/test/no_cxx11_std_align_pass.cpp create mode 100644 libs/config/test/no_cxx11_thread_local_fail.cpp create mode 100644 libs/config/test/no_cxx11_thread_local_pass.cpp create mode 100644 libs/config/test/no_cxx11_trailing_result_types_fail.cpp create mode 100644 libs/config/test/no_cxx11_trailing_result_types_pass.cpp create mode 100644 libs/config/test/no_cxx11_user_lit_fail.cpp create mode 100644 libs/config/test/no_cxx11_user_lit_pass.cpp create mode 100644 libs/config/test/no_cxx14_binary_literals_fail.cpp create mode 100644 libs/config/test/no_cxx14_binary_literals_pass.cpp create mode 100644 libs/config/test/no_cxx14_constexpr_fail.cpp create mode 100644 libs/config/test/no_cxx14_constexpr_pass.cpp create mode 100644 libs/config/test/no_cxx14_decltype_auto_fail.cpp create mode 100644 libs/config/test/no_cxx14_decltype_auto_pass.cpp create mode 100644 libs/config/test/no_cxx14_digit_separator_fail.cpp create mode 100644 libs/config/test/no_cxx14_digit_separator_pass.cpp create mode 100644 libs/config/test/no_cxx14_generic_lambda_fail.cpp create mode 100644 libs/config/test/no_cxx14_generic_lambda_pass.cpp create mode 100644 libs/config/test/no_cxx14_hdr_shared_mutex_fail.cpp create mode 100644 libs/config/test/no_cxx14_hdr_shared_mutex_pass.cpp create mode 100644 libs/config/test/no_cxx14_lambda_capture_fail.cpp create mode 100644 libs/config/test/no_cxx14_lambda_capture_pass.cpp create mode 100644 libs/config/test/no_cxx14_member_init_fail.cpp create mode 100644 libs/config/test/no_cxx14_member_init_pass.cpp create mode 100644 libs/config/test/no_cxx14_return_type_ded_fail.cpp create mode 100644 libs/config/test/no_cxx14_return_type_ded_pass.cpp create mode 100644 libs/config/test/no_cxx14_std_exchange_fail.cpp create mode 100644 libs/config/test/no_cxx14_std_exchange_pass.cpp create mode 100644 libs/config/test/no_cxx14_var_templ_fail.cpp create mode 100644 libs/config/test/no_cxx14_var_templ_pass.cpp create mode 100644 libs/config/test/no_cxx17_fold_expressions_fail.cpp create mode 100644 libs/config/test/no_cxx17_fold_expressions_pass.cpp create mode 100644 libs/config/test/no_cxx17_inline_variables_fail.cpp create mode 100644 libs/config/test/no_cxx17_inline_variables_pass.cpp create mode 100644 libs/config/test/no_cxx17_iterator_traits_fail.cpp create mode 100644 libs/config/test/no_cxx17_iterator_traits_pass.cpp create mode 100644 libs/config/test/no_cxx17_std_apply_fail.cpp create mode 100644 libs/config/test/no_cxx17_std_apply_pass.cpp create mode 100644 libs/config/test/no_cxx17_std_invoke_fail.cpp create mode 100644 libs/config/test/no_cxx17_std_invoke_pass.cpp create mode 100644 libs/config/test/no_cxx17_structured_bindings_fail.cpp create mode 100644 libs/config/test/no_cxx17_structured_bindings_pass.cpp create mode 100644 libs/config/test/no_cxx98_binders_fail.cpp create mode 100644 libs/config/test/no_cxx98_binders_pass.cpp create mode 100644 libs/config/test/no_cxx98_function_base_fail.cpp create mode 100644 libs/config/test/no_cxx98_function_base_pass.cpp create mode 100644 libs/config/test/no_cxx98_random_shuffle_fail.cpp create mode 100644 libs/config/test/no_cxx98_random_shuffle_pass.cpp create mode 100644 libs/config/test/no_cxx_hdr_functional_fail.cpp create mode 100644 libs/config/test/no_cxx_hdr_functional_pass.cpp create mode 100644 libs/config/test/no_decltype_fail.cpp create mode 100644 libs/config/test/no_decltype_n3276_fail.cpp create mode 100644 libs/config/test/no_decltype_n3276_pass.cpp create mode 100644 libs/config/test/no_decltype_pass.cpp create mode 100644 libs/config/test/no_ded_typename_fail.cpp create mode 100644 libs/config/test/no_ded_typename_pass.cpp create mode 100644 libs/config/test/no_defaulted_functions_fail.cpp create mode 100644 libs/config/test/no_defaulted_functions_pass.cpp create mode 100644 libs/config/test/no_deleted_functions_fail.cpp create mode 100644 libs/config/test/no_deleted_functions_pass.cpp create mode 100644 libs/config/test/no_dep_nested_class_fail.cpp create mode 100644 libs/config/test/no_dep_nested_class_pass.cpp create mode 100644 libs/config/test/no_dep_val_param_fail.cpp create mode 100644 libs/config/test/no_dep_val_param_pass.cpp create mode 100644 libs/config/test/no_excep_std_fail.cpp create mode 100644 libs/config/test/no_excep_std_pass.cpp create mode 100644 libs/config/test/no_exceptions_fail.cpp create mode 100644 libs/config/test/no_exceptions_pass.cpp create mode 100644 libs/config/test/no_exp_func_tem_arg_fail.cpp create mode 100644 libs/config/test/no_exp_func_tem_arg_pass.cpp create mode 100644 libs/config/test/no_explicit_cvt_ops_fail.cpp create mode 100644 libs/config/test/no_explicit_cvt_ops_pass.cpp create mode 100644 libs/config/test/no_extern_template_fail.cpp create mode 100644 libs/config/test/no_extern_template_pass.cpp create mode 100644 libs/config/test/no_fenv_h_fail.cpp create mode 100644 libs/config/test/no_fenv_h_pass.cpp create mode 100644 libs/config/test/no_fixed_len_variadic_templates_fail.cpp create mode 100644 libs/config/test/no_fixed_len_variadic_templates_pass.cpp create mode 100644 libs/config/test/no_func_tmp_order_fail.cpp create mode 100644 libs/config/test/no_func_tmp_order_pass.cpp create mode 100644 libs/config/test/no_function_template_default_args_fail.cpp create mode 100644 libs/config/test/no_function_template_default_args_pass.cpp create mode 100644 libs/config/test/no_function_type_spec_fail.cpp create mode 100644 libs/config/test/no_function_type_spec_pass.cpp create mode 100644 libs/config/test/no_i64_limits_fail.cpp create mode 100644 libs/config/test/no_i64_limits_pass.cpp create mode 100644 libs/config/test/no_inline_memb_init_fail.cpp create mode 100644 libs/config/test/no_inline_memb_init_pass.cpp create mode 100644 libs/config/test/no_integral_int64_t_fail.cpp create mode 100644 libs/config/test/no_integral_int64_t_pass.cpp create mode 100644 libs/config/test/no_iosfwd_fail.cpp create mode 100644 libs/config/test/no_iosfwd_pass.cpp create mode 100644 libs/config/test/no_iostream_fail.cpp create mode 100644 libs/config/test/no_iostream_pass.cpp create mode 100644 libs/config/test/no_is_abstract_fail.cpp create mode 100644 libs/config/test/no_is_abstract_pass.cpp create mode 100644 libs/config/test/no_iter_construct_fail.cpp create mode 100644 libs/config/test/no_iter_construct_pass.cpp create mode 100644 libs/config/test/no_lambdas_fail.cpp create mode 100644 libs/config/test/no_lambdas_pass.cpp create mode 100644 libs/config/test/no_limits_const_exp_fail.cpp create mode 100644 libs/config/test/no_limits_const_exp_pass.cpp create mode 100644 libs/config/test/no_limits_fail.cpp create mode 100644 libs/config/test/no_limits_pass.cpp create mode 100644 libs/config/test/no_ll_limits_fail.cpp create mode 100644 libs/config/test/no_ll_limits_pass.cpp create mode 100644 libs/config/test/no_long_long_fail.cpp create mode 100644 libs/config/test/no_long_long_pass.cpp create mode 100644 libs/config/test/no_mem_func_spec_fail.cpp create mode 100644 libs/config/test/no_mem_func_spec_pass.cpp create mode 100644 libs/config/test/no_mem_tem_keyword_fail.cpp create mode 100644 libs/config/test/no_mem_tem_keyword_pass.cpp create mode 100644 libs/config/test/no_mem_tem_pnts_fail.cpp create mode 100644 libs/config/test/no_mem_tem_pnts_pass.cpp create mode 100644 libs/config/test/no_mem_templ_frnds_fail.cpp create mode 100644 libs/config/test/no_mem_templ_frnds_pass.cpp create mode 100644 libs/config/test/no_mem_templates_fail.cpp create mode 100644 libs/config/test/no_mem_templates_pass.cpp create mode 100644 libs/config/test/no_nested_friendship_fail.cpp create mode 100644 libs/config/test/no_nested_friendship_pass.cpp create mode 100644 libs/config/test/no_noexcept_fail.cpp create mode 100644 libs/config/test/no_noexcept_pass.cpp create mode 100644 libs/config/test/no_nullptr_fail.cpp create mode 100644 libs/config/test/no_nullptr_pass.cpp create mode 100644 libs/config/test/no_ops_in_namespace_fail.cpp create mode 100644 libs/config/test/no_ops_in_namespace_pass.cpp create mode 100644 libs/config/test/no_part_spec_def_args_fail.cpp create mode 100644 libs/config/test/no_part_spec_def_args_pass.cpp create mode 100644 libs/config/test/no_partial_spec_fail.cpp create mode 100644 libs/config/test/no_partial_spec_pass.cpp create mode 100644 libs/config/test/no_priv_aggregate_fail.cpp create mode 100644 libs/config/test/no_priv_aggregate_pass.cpp create mode 100644 libs/config/test/no_ptr_mem_const_fail.cpp create mode 100644 libs/config/test/no_ptr_mem_const_pass.cpp create mode 100644 libs/config/test/no_range_based_for_fail.cpp create mode 100644 libs/config/test/no_range_based_for_pass.cpp create mode 100644 libs/config/test/no_raw_literals_fail.cpp create mode 100644 libs/config/test/no_raw_literals_pass.cpp create mode 100644 libs/config/test/no_restrict_references_fail.cpp create mode 100644 libs/config/test/no_restrict_references_pass.cpp create mode 100644 libs/config/test/no_ret_det_fail.cpp create mode 100644 libs/config/test/no_ret_det_pass.cpp create mode 100644 libs/config/test/no_rtti_fail.cpp create mode 100644 libs/config/test/no_rtti_pass.cpp create mode 100644 libs/config/test/no_rvalue_references_fail.cpp create mode 100644 libs/config/test/no_rvalue_references_pass.cpp create mode 100644 libs/config/test/no_scoped_enums_fail.cpp create mode 100644 libs/config/test/no_scoped_enums_pass.cpp create mode 100644 libs/config/test/no_sfinae_expr_fail.cpp create mode 100644 libs/config/test/no_sfinae_expr_pass.cpp create mode 100644 libs/config/test/no_sfinae_fail.cpp create mode 100644 libs/config/test/no_sfinae_pass.cpp create mode 100644 libs/config/test/no_sstream_fail.cpp create mode 100644 libs/config/test/no_sstream_pass.cpp create mode 100644 libs/config/test/no_static_assert_fail.cpp create mode 100644 libs/config/test/no_static_assert_pass.cpp create mode 100644 libs/config/test/no_std_allocator_fail.cpp create mode 100644 libs/config/test/no_std_allocator_pass.cpp create mode 100644 libs/config/test/no_std_distance_fail.cpp create mode 100644 libs/config/test/no_std_distance_pass.cpp create mode 100644 libs/config/test/no_std_iter_traits_fail.cpp create mode 100644 libs/config/test/no_std_iter_traits_pass.cpp create mode 100644 libs/config/test/no_std_iterator_fail.cpp create mode 100644 libs/config/test/no_std_iterator_pass.cpp create mode 100644 libs/config/test/no_std_locale_fail.cpp create mode 100644 libs/config/test/no_std_locale_pass.cpp create mode 100644 libs/config/test/no_std_messages_fail.cpp create mode 100644 libs/config/test/no_std_messages_pass.cpp create mode 100644 libs/config/test/no_std_min_max_fail.cpp create mode 100644 libs/config/test/no_std_min_max_pass.cpp create mode 100644 libs/config/test/no_std_oi_assign_fail.cpp create mode 100644 libs/config/test/no_std_oi_assign_pass.cpp create mode 100644 libs/config/test/no_std_typeinfo_fail.cpp create mode 100644 libs/config/test/no_std_typeinfo_pass.cpp create mode 100644 libs/config/test/no_std_use_facet_fail.cpp create mode 100644 libs/config/test/no_std_use_facet_pass.cpp create mode 100644 libs/config/test/no_std_wstreambuf_fail.cpp create mode 100644 libs/config/test/no_std_wstreambuf_pass.cpp create mode 100644 libs/config/test/no_std_wstring_fail.cpp create mode 100644 libs/config/test/no_std_wstring_pass.cpp create mode 100644 libs/config/test/no_stdc_namespace_fail.cpp create mode 100644 libs/config/test/no_stdc_namespace_pass.cpp create mode 100644 libs/config/test/no_swprintf_fail.cpp create mode 100644 libs/config/test/no_swprintf_pass.cpp create mode 100644 libs/config/test/no_tem_local_classes_fail.cpp create mode 100644 libs/config/test/no_tem_local_classes_pass.cpp create mode 100644 libs/config/test/no_template_aliases_fail.cpp create mode 100644 libs/config/test/no_template_aliases_pass.cpp create mode 100644 libs/config/test/no_template_streams_fail.cpp create mode 100644 libs/config/test/no_template_streams_pass.cpp create mode 100644 libs/config/test/no_template_template_fail.cpp create mode 100644 libs/config/test/no_template_template_pass.cpp create mode 100644 libs/config/test/no_two_phase_lookup_fail.cpp create mode 100644 libs/config/test/no_two_phase_lookup_pass.cpp create mode 100644 libs/config/test/no_typeid_fail.cpp create mode 100644 libs/config/test/no_typeid_pass.cpp create mode 100644 libs/config/test/no_typename_with_ctor_fail.cpp create mode 100644 libs/config/test/no_typename_with_ctor_pass.cpp create mode 100644 libs/config/test/no_unicode_literals_fail.cpp create mode 100644 libs/config/test/no_unicode_literals_pass.cpp create mode 100644 libs/config/test/no_unified_init_fail.cpp create mode 100644 libs/config/test/no_unified_init_pass.cpp create mode 100644 libs/config/test/no_using_breaks_adl_fail.cpp create mode 100644 libs/config/test/no_using_breaks_adl_pass.cpp create mode 100644 libs/config/test/no_using_decl_overld_fail.cpp create mode 100644 libs/config/test/no_using_decl_overld_pass.cpp create mode 100644 libs/config/test/no_using_template_fail.cpp create mode 100644 libs/config/test/no_using_template_pass.cpp create mode 100644 libs/config/test/no_variadic_macros_fail.cpp create mode 100644 libs/config/test/no_variadic_macros_pass.cpp create mode 100644 libs/config/test/no_variadic_templates_fail.cpp create mode 100644 libs/config/test/no_variadic_templates_pass.cpp create mode 100644 libs/config/test/no_void_returns_fail.cpp create mode 100644 libs/config/test/no_void_returns_pass.cpp create mode 100644 libs/config/test/no_wchar_t_fail.cpp create mode 100644 libs/config/test/no_wchar_t_pass.cpp create mode 100644 libs/config/test/pragma_message_test.cpp create mode 100644 libs/config/test/test.hpp create mode 100644 libs/config/test/threads/test_thread_fail1.cpp create mode 100644 libs/config/test/threads/test_thread_fail2.cpp create mode 100644 libs/config/tools/Jamfile.v2 create mode 100644 libs/config/tools/configure.in create mode 100644 libs/config/tools/generate.cpp create mode 100644 libs/date_time/build/Jamfile.v2 create mode 100644 libs/date_time/src/date_time.doc create mode 100644 libs/date_time/src/gregorian/date_generators.cpp create mode 100644 libs/date_time/src/gregorian/greg_month.cpp create mode 100644 libs/date_time/src/gregorian/greg_names.hpp create mode 100644 libs/date_time/src/gregorian/greg_weekday.cpp create mode 100644 libs/date_time/src/gregorian/gregorian_types.cpp create mode 100644 libs/date_time/src/posix_time/posix_time_types.cpp create mode 100644 libs/exception/build/Jamfile.v2 create mode 100644 libs/exception/src/clone_current_exception_non_intrusive.cpp create mode 100644 libs/filesystem/bug/Jamfile.v2 create mode 100644 libs/filesystem/bug/bug.cpp create mode 100644 libs/filesystem/bug/index.html create mode 100644 libs/filesystem/build/Jamfile.v2 create mode 100644 libs/filesystem/doc/Jamfile.v2 create mode 100644 libs/filesystem/doc/POSIX_filename_encoding.txt create mode 100644 libs/filesystem/doc/build_tutorial.bat create mode 100644 libs/filesystem/doc/deprecated.html create mode 100644 libs/filesystem/doc/design.htm create mode 100644 libs/filesystem/doc/do_list.html create mode 100644 libs/filesystem/doc/faq.htm create mode 100644 libs/filesystem/doc/index.htm create mode 100644 libs/filesystem/doc/issue_reporting.html create mode 100644 libs/filesystem/doc/path_table.cpp create mode 100644 libs/filesystem/doc/path_table.txt create mode 100644 libs/filesystem/doc/portability_guide.htm create mode 100644 libs/filesystem/doc/publish.bat create mode 100644 libs/filesystem/doc/reference.html create mode 100644 libs/filesystem/doc/relative_proposal.html create mode 100644 libs/filesystem/doc/release_history.html create mode 100644 libs/filesystem/doc/styles.css create mode 100644 libs/filesystem/doc/tickets.html create mode 100644 libs/filesystem/doc/tutorial.html create mode 100644 libs/filesystem/doc/v3.html create mode 100644 libs/filesystem/doc/v3_design.html create mode 100644 libs/filesystem/example/Jamfile.v2 create mode 100644 libs/filesystem/example/directory_symlink_parent_resolution.cpp create mode 100644 libs/filesystem/example/error_demo.cpp create mode 100644 libs/filesystem/example/file_size.cpp create mode 100644 libs/filesystem/example/file_status.cpp create mode 100644 libs/filesystem/example/mbcopy.cpp create mode 100644 libs/filesystem/example/mbpath.cpp create mode 100644 libs/filesystem/example/mbpath.hpp create mode 100644 libs/filesystem/example/msvc/common.props create mode 100644 libs/filesystem/example/msvc/directory_symlink_parent_resolution/directory_symlink_parent_resolution.vcxproj create mode 100644 libs/filesystem/example/msvc/filesystem-tutorials.sln create mode 100644 libs/filesystem/example/msvc/path_info/path_info.vcxproj create mode 100644 libs/filesystem/example/msvc/tut1/tut1.vcxproj create mode 100644 libs/filesystem/example/msvc/tut2/tut2.vcxproj create mode 100644 libs/filesystem/example/msvc/tut3/tut3.vcxproj create mode 100644 libs/filesystem/example/msvc/tut4/tut4.vcxproj create mode 100644 libs/filesystem/example/msvc/tut5/tut5.vcxproj create mode 100644 libs/filesystem/example/path_info.cpp create mode 100644 libs/filesystem/example/simple_ls.cpp create mode 100644 libs/filesystem/example/stems.cpp create mode 100644 libs/filesystem/example/tchar.cpp create mode 100644 libs/filesystem/example/test/Jamfile.v2 create mode 100644 libs/filesystem/example/test/build.bat create mode 100644 libs/filesystem/example/test/build.sh create mode 100644 libs/filesystem/example/test/setup.bat create mode 100644 libs/filesystem/example/test/setup.sh create mode 100644 libs/filesystem/example/tut0.cpp create mode 100644 libs/filesystem/example/tut1.cpp create mode 100644 libs/filesystem/example/tut2.cpp create mode 100644 libs/filesystem/example/tut3.cpp create mode 100644 libs/filesystem/example/tut4.cpp create mode 100644 libs/filesystem/example/tut5.cpp create mode 100644 libs/filesystem/example/tut6a.cpp create mode 100644 libs/filesystem/example/tut6b.cpp create mode 100644 libs/filesystem/example/tut6c.cpp create mode 100644 libs/filesystem/index.html create mode 100644 libs/filesystem/meta/libraries.json create mode 100644 libs/filesystem/src/codecvt_error_category.cpp create mode 100644 libs/filesystem/src/operations.cpp create mode 100644 libs/filesystem/src/path.cpp create mode 100644 libs/filesystem/src/path_traits.cpp create mode 100644 libs/filesystem/src/portability.cpp create mode 100644 libs/filesystem/src/unique_path.cpp create mode 100644 libs/filesystem/src/utf8_codecvt_facet.cpp create mode 100644 libs/filesystem/src/windows_file_codecvt.cpp create mode 100644 libs/filesystem/src/windows_file_codecvt.hpp create mode 100644 libs/filesystem/test/Jamfile.v2 create mode 100644 libs/filesystem/test/b2.log create mode 100644 libs/filesystem/test/config_info.cpp create mode 100644 libs/filesystem/test/convenience_test.cpp create mode 100644 libs/filesystem/test/deprecated_test.cpp create mode 100644 libs/filesystem/test/design_use_cases.cpp create mode 100644 libs/filesystem/test/equivalent.cpp create mode 100644 libs/filesystem/test/fstream_test.cpp create mode 100644 libs/filesystem/test/issues/10038.cpp create mode 100644 libs/filesystem/test/issues/10205.cpp create mode 100644 libs/filesystem/test/issues/10485.cpp create mode 100644 libs/filesystem/test/issues/10641.cpp create mode 100644 libs/filesystem/test/issues/11166-remove-race.cpp create mode 100644 libs/filesystem/test/issues/11228--filtered-recursive_directory_iterator-range.cpp create mode 100644 libs/filesystem/test/issues/3332/test.cpp create mode 100644 libs/filesystem/test/issues/4329.-basename.cpp create mode 100644 libs/filesystem/test/issues/5300-temp-dir-path-130.cpp create mode 100644 libs/filesystem/test/issues/6638-global-init-fails-3.cpp create mode 100644 libs/filesystem/test/issues/8930.cpp create mode 100644 libs/filesystem/test/issues/9054_static_const_codecvt_segfault_pre_main.cpp create mode 100644 libs/filesystem/test/issues/9219.cpp create mode 100644 libs/filesystem/test/issues/Jamfile.v2 create mode 100644 libs/filesystem/test/issues/boost-no-inspect create mode 100644 libs/filesystem/test/issues/copy_file-compilation-error-2015-05-04.cpp create mode 100644 libs/filesystem/test/issues/fchmodat_AT_SYMLINK_NOFOLLOW_6659.cpp create mode 100644 libs/filesystem/test/issues/hello_filesystem.cpp create mode 100644 libs/filesystem/test/issues/readme.txt create mode 100644 libs/filesystem/test/issues/recurse_dir_iter_5403.cpp create mode 100644 libs/filesystem/test/large_file_support_test.cpp create mode 100644 libs/filesystem/test/locale_info.cpp create mode 100644 libs/filesystem/test/long_path_test.cpp create mode 100644 libs/filesystem/test/macro_default_test.cpp create mode 100644 libs/filesystem/test/msvc/boost-no-inspect create mode 100644 libs/filesystem/test/msvc/common.props create mode 100644 libs/filesystem/test/msvc/config_info/config_info.vcxproj create mode 100644 libs/filesystem/test/msvc/convenience_test/convenience_test.vcxproj create mode 100644 libs/filesystem/test/msvc/deprecated_test/deprecated_test.vcxproj create mode 100644 libs/filesystem/test/msvc/exec_monitor_dll/exec_monitor_dll.vcxproj create mode 100644 libs/filesystem/test/msvc/exec_monitor_lib/exec_monitor_lib.vcxproj create mode 100644 libs/filesystem/test/msvc/file_status/file_status.vcxproj create mode 100644 libs/filesystem/test/msvc/filesystem.sln create mode 100644 libs/filesystem/test/msvc/filesystem_dll/filesystem_dll.vcxproj create mode 100644 libs/filesystem/test/msvc/filesystem_lib/filesystem_lib.vcxproj create mode 100644 libs/filesystem/test/msvc/fstream_test/fstream_test.vcxproj create mode 100644 libs/filesystem/test/msvc/headers/headers.vcxproj create mode 100644 libs/filesystem/test/msvc/hello_filesystem/hello_filesystem.vcxproj create mode 100644 libs/filesystem/test/msvc/issue_test/issue_test.vcxproj create mode 100644 libs/filesystem/test/msvc/issues_test_static/issues_test_static.vcxproj create mode 100644 libs/filesystem/test/msvc/locale_info/locale_info.vcxproj create mode 100644 libs/filesystem/test/msvc/long_path_test/long_path_test.vcxproj create mode 100644 libs/filesystem/test/msvc/macro_default_test/macro_default_test.vcxproj create mode 100644 libs/filesystem/test/msvc/odr_test/odr_test.vcxproj create mode 100644 libs/filesystem/test/msvc/operations_test/operations_test.vcxproj create mode 100644 libs/filesystem/test/msvc/operations_unit_test/operations_unit_test.vcxproj create mode 100644 libs/filesystem/test/msvc/path_test/path_test.vcxproj create mode 100644 libs/filesystem/test/msvc/path_test_static/path_test_static.vcxproj create mode 100644 libs/filesystem/test/msvc/path_timings/path_timings.vcxproj create mode 100644 libs/filesystem/test/msvc/path_unit_test/path_unit_test.vcxproj create mode 100644 libs/filesystem/test/msvc/recurse_dir_iter_test/recurse_dir_iter_test.vcxproj create mode 100644 libs/filesystem/test/msvc/relative_test/relative_test.vcxproj create mode 100644 libs/filesystem/test/msvc/stems/stems.vcxproj create mode 100644 libs/filesystem/test/msvc/system_dll/system_dll.vcxproj create mode 100644 libs/filesystem/test/msvc/system_lib/system_lib.vcxproj create mode 100644 libs/filesystem/test/msvc/tut1/tut1.vcxproj create mode 100644 libs/filesystem/test/msvc/tut2/tut2.vcxproj create mode 100644 libs/filesystem/test/msvc/tut3/tut3.vcxproj create mode 100644 libs/filesystem/test/msvc/tut4/tut4.vcxproj create mode 100644 libs/filesystem/test/msvc/tut5/tut5.vcxproj create mode 100644 libs/filesystem/test/msvc/tut6a/tut6a.vcxproj create mode 100644 libs/filesystem/test/msvc/tut6b/tut6b.vcxproj create mode 100644 libs/filesystem/test/msvc/tut6c/tut6c.vcxproj create mode 100644 libs/filesystem/test/msvc/windows_attributes/windows_attributes.vcxproj create mode 100644 libs/filesystem/test/odr1_test.cpp create mode 100644 libs/filesystem/test/odr2_test.cpp create mode 100644 libs/filesystem/test/operations_test.cpp create mode 100644 libs/filesystem/test/operations_unit_test.cpp create mode 100644 libs/filesystem/test/path_test.cpp create mode 100644 libs/filesystem/test/path_times.cpp create mode 100644 libs/filesystem/test/path_unit_test.cpp create mode 100644 libs/filesystem/test/quick.cpp create mode 100644 libs/filesystem/test/relative_test.cpp create mode 100644 libs/filesystem/test/sample_test.cpp create mode 100644 libs/filesystem/test/test_codecvt.hpp create mode 100644 libs/filesystem/test/test_links.html create mode 100644 libs/filesystem/test/test_status.html create mode 100644 libs/filesystem/test/windows_attributes.cpp create mode 100644 libs/filesystem/tools/backup.bat create mode 100644 libs/filesystem/tools/exclude.txt create mode 100644 libs/filesystem/tools/publish.bat create mode 100644 libs/predef/build.jam create mode 100644 libs/predef/check/predef.jam create mode 100644 libs/predef/doc/build.jam create mode 100644 libs/predef/doc/hardware_simd.qbk create mode 100644 libs/predef/doc/history.qbk create mode 100644 libs/predef/doc/predef.qbk create mode 100644 libs/predef/doc/todo.qbk create mode 100644 libs/predef/index.html create mode 100644 libs/predef/meta/libraries.json create mode 100644 libs/predef/test/build.jam create mode 100644 libs/predef/test/check_value.cpp create mode 100644 libs/predef/test/info_as_c.c create mode 100644 libs/predef/test/info_as_cpp.cpp create mode 100644 libs/predef/test/info_as_objc.m create mode 100644 libs/predef/test/info_as_objcpp.mm create mode 100644 libs/predef/test/macos_endian.c create mode 100644 libs/predef/test/macos_vs_bsd.c create mode 100644 libs/predef/test/make.cpp create mode 100644 libs/predef/test/platform_windows.cpp create mode 100644 libs/predef/test/predef_info.h create mode 100644 libs/predef/test/tested_at.cpp create mode 100644 libs/predef/test/tested_at_outdated.cpp create mode 100644 libs/predef/test/version.cpp create mode 100644 libs/predef/test/workaround.cpp create mode 100644 libs/predef/test/workaround_strict_config.cpp create mode 100644 libs/predef/tools/check/build.jam create mode 100644 libs/predef/tools/check/predef.jam create mode 100644 libs/predef/tools/check/predef_check.h create mode 100644 libs/predef/tools/check/predef_check_as_c.c create mode 100644 libs/predef/tools/check/predef_check_as_cpp.cpp create mode 100644 libs/predef/tools/check/predef_check_as_objc.m create mode 100644 libs/predef/tools/check/predef_check_as_objcpp.mm create mode 100644 libs/predef/tools/check/predef_check_cc.h create mode 100644 libs/predef/tools/check/predef_check_cc_as_c.c create mode 100644 libs/predef/tools/check/predef_check_cc_as_cpp.cpp create mode 100644 libs/predef/tools/check/predef_check_cc_as_objc.m create mode 100644 libs/predef/tools/check/predef_check_cc_as_objcpp.mm create mode 100644 libs/program_options/Jamfile create mode 100644 libs/program_options/README.md create mode 100644 libs/program_options/build/Jamfile.v2 create mode 100644 libs/program_options/ci/build.sh create mode 100644 libs/program_options/ci/codecov.sh create mode 100644 libs/program_options/ci/coverity.sh create mode 100644 libs/program_options/ci/cppcheck.sh create mode 100644 libs/program_options/ci/mingw.bat create mode 100644 libs/program_options/doc/Jamfile.v2 create mode 100644 libs/program_options/doc/acknowledgements.xml create mode 100644 libs/program_options/doc/alternatives create mode 100644 libs/program_options/doc/autodoc.xml create mode 100644 libs/program_options/doc/changes.xml create mode 100644 libs/program_options/doc/design.xml create mode 100644 libs/program_options/doc/glossary.dox create mode 100644 libs/program_options/doc/glossary.xml create mode 100644 libs/program_options/doc/howto.xml create mode 100644 libs/program_options/doc/index.html create mode 100644 libs/program_options/doc/overview.xml create mode 100644 libs/program_options/doc/post_review_plan.txt create mode 100644 libs/program_options/doc/program_options.dox create mode 100644 libs/program_options/doc/program_options.ent create mode 100644 libs/program_options/doc/program_options.xml create mode 100644 libs/program_options/doc/questions create mode 100644 libs/program_options/doc/questions.dox create mode 100644 libs/program_options/doc/rationale create mode 100644 libs/program_options/doc/rationale.dox create mode 100644 libs/program_options/doc/recipes.dox create mode 100644 libs/program_options/doc/requirements-Rozental create mode 100644 libs/program_options/doc/todo.txt create mode 100644 libs/program_options/doc/tutorial.xml create mode 100644 libs/program_options/example/Jamfile.v2 create mode 100644 libs/program_options/example/custom_syntax.cpp create mode 100644 libs/program_options/example/first.cpp create mode 100644 libs/program_options/example/multiple_sources.cfg create mode 100644 libs/program_options/example/multiple_sources.cpp create mode 100644 libs/program_options/example/option_groups.cpp create mode 100644 libs/program_options/example/options_description.cpp create mode 100644 libs/program_options/example/real.cpp create mode 100644 libs/program_options/example/regex.cpp create mode 100644 libs/program_options/example/response_file.cpp create mode 100644 libs/program_options/example/response_file.rsp create mode 100644 libs/program_options/index.html create mode 100644 libs/program_options/meta/libraries.json create mode 100644 libs/program_options/src/cmdline.cpp create mode 100644 libs/program_options/src/config_file.cpp create mode 100644 libs/program_options/src/convert.cpp create mode 100644 libs/program_options/src/options_description.cpp create mode 100644 libs/program_options/src/parsers.cpp create mode 100644 libs/program_options/src/positional_options.cpp create mode 100644 libs/program_options/src/split.cpp create mode 100644 libs/program_options/src/utf8_codecvt_facet.cpp create mode 100644 libs/program_options/src/value_semantic.cpp create mode 100644 libs/program_options/src/variables_map.cpp create mode 100644 libs/program_options/src/winmain.cpp create mode 100644 libs/program_options/test/Jamfile.v2 create mode 100644 libs/program_options/test/cmdline_test.cpp create mode 100644 libs/program_options/test/config_test.cfg create mode 100644 libs/program_options/test/exception_test.cpp create mode 100644 libs/program_options/test/exception_txt_test.cpp create mode 100644 libs/program_options/test/minitest.hpp create mode 100644 libs/program_options/test/optional_test.cpp create mode 100644 libs/program_options/test/options_description_test.cpp create mode 100644 libs/program_options/test/parsers_test.cpp create mode 100644 libs/program_options/test/positional_options_test.cpp create mode 100644 libs/program_options/test/program_options_size_test.py create mode 100644 libs/program_options/test/quick.cpp create mode 100644 libs/program_options/test/required_test.cfg create mode 100644 libs/program_options/test/required_test.cpp create mode 100644 libs/program_options/test/split_test.cpp create mode 100644 libs/program_options/test/test_convert.cpp create mode 100644 libs/program_options/test/ucs2.txt create mode 100644 libs/program_options/test/unicode_test.cpp create mode 100644 libs/program_options/test/unrecognized_test.cpp create mode 100644 libs/program_options/test/utf8.txt create mode 100644 libs/program_options/test/variable_map_test.cpp create mode 100644 libs/program_options/test/winmain.cpp create mode 100644 libs/program_options/test/winmain.py create mode 100644 libs/regex/build/Jamfile.v2 create mode 100644 libs/regex/build/has_icu_test.cpp create mode 100644 libs/regex/src/c_regex_traits.cpp create mode 100644 libs/regex/src/cpp_regex_traits.cpp create mode 100644 libs/regex/src/cregex.cpp create mode 100644 libs/regex/src/fileiter.cpp create mode 100644 libs/regex/src/icu.cpp create mode 100644 libs/regex/src/instances.cpp create mode 100644 libs/regex/src/internals.hpp create mode 100644 libs/regex/src/posix_api.cpp create mode 100644 libs/regex/src/regex.cpp create mode 100644 libs/regex/src/regex_debug.cpp create mode 100644 libs/regex/src/regex_raw_buffer.cpp create mode 100644 libs/regex/src/regex_traits_defaults.cpp create mode 100644 libs/regex/src/static_mutex.cpp create mode 100644 libs/regex/src/usinstances.cpp create mode 100644 libs/regex/src/w32_regex_traits.cpp create mode 100644 libs/regex/src/wc_regex_traits.cpp create mode 100644 libs/regex/src/wide_posix_api.cpp create mode 100644 libs/regex/src/winstances.cpp create mode 100644 libs/regex/test/config_info/regex_config_info.cpp create mode 100644 libs/system/build/Jamfile.v2 create mode 100644 libs/system/doc/index.html create mode 100644 libs/system/doc/reference.html create mode 100644 libs/system/index.html create mode 100644 libs/system/meta/libraries.json create mode 100644 libs/system/src/error_code.cpp create mode 100644 libs/system/test/Jamfile.v2 create mode 100644 libs/system/test/before_main_test.cpp create mode 100644 libs/system/test/config_test.cpp create mode 100644 libs/system/test/dynamic_link_test.cpp create mode 100644 libs/system/test/error_code_test.cpp create mode 100644 libs/system/test/error_code_user_test.cpp create mode 100644 libs/system/test/header_only_test.cpp create mode 100644 libs/system/test/initialization_test.cpp create mode 100644 libs/system/test/msvc/common.props create mode 100644 libs/system/test/msvc/config_test/config_test.vcxproj create mode 100644 libs/system/test/msvc/error_code_test/error_code_test.vcxproj create mode 100644 libs/system/test/msvc/header_only_error_code_test/header_only_error_code_test.vcxproj create mode 100644 libs/system/test/msvc/header_only_test/header_only_test.vcxproj create mode 100644 libs/system/test/msvc/std_interop_test/std_interop_test.vcxproj create mode 100644 libs/system/test/msvc/system-dll/system-dll.vcxproj create mode 100644 libs/system/test/msvc/system.sln create mode 100644 libs/system/test/quick.cpp create mode 100644 libs/system/test/single_instance_1.cpp create mode 100644 libs/system/test/single_instance_2.cpp create mode 100644 libs/system/test/single_instance_test.cpp create mode 100644 libs/system/test/std_interop_test.cpp create mode 100644 libs/system/test/std_mismatch_test.cpp create mode 100644 libs/system/test/system_error_test.cpp create mode 100644 libs/system/test/throw_test.cpp create mode 100644 libs/system/test/throws_assign_fail.cpp create mode 100644 libs/test/build/CMakeLists.txt create mode 100644 libs/test/build/Jamfile.v2 create mode 100644 libs/test/src/compiler_log_formatter.cpp create mode 100644 libs/test/src/cpp_main.cpp create mode 100644 libs/test/src/debug.cpp create mode 100644 libs/test/src/decorator.cpp create mode 100644 libs/test/src/execution_monitor.cpp create mode 100644 libs/test/src/framework.cpp create mode 100644 libs/test/src/junit_log_formatter.cpp create mode 100644 libs/test/src/plain_report_formatter.cpp create mode 100644 libs/test/src/progress_monitor.cpp create mode 100644 libs/test/src/results_collector.cpp create mode 100644 libs/test/src/results_reporter.cpp create mode 100644 libs/test/src/test_framework_init_observer.cpp create mode 100644 libs/test/src/test_main.cpp create mode 100644 libs/test/src/test_tools.cpp create mode 100644 libs/test/src/test_tree.cpp create mode 100644 libs/test/src/unit_test_log.cpp create mode 100644 libs/test/src/unit_test_main.cpp create mode 100644 libs/test/src/unit_test_monitor.cpp create mode 100644 libs/test/src/unit_test_parameters.cpp create mode 100644 libs/test/src/xml_log_formatter.cpp create mode 100644 libs/test/src/xml_report_formatter.cpp create mode 100644 libs/thread/build/Jamfile.v2 create mode 100644 libs/thread/build/has_atomic_flag_lockfree_test.cpp create mode 100644 libs/thread/src/future.cpp create mode 100644 libs/thread/src/pthread/once.cpp create mode 100644 libs/thread/src/pthread/once_atomic.cpp create mode 100644 libs/thread/src/pthread/thread.cpp create mode 100644 libs/thread/src/tss_null.cpp create mode 100644 libs/thread/src/win32/thread.cpp create mode 100644 libs/thread/src/win32/thread_primitives.cpp create mode 100644 libs/thread/src/win32/tss_dll.cpp create mode 100644 libs/thread/src/win32/tss_pe.cpp create mode 100644 libs/timer/build/Jamfile.v2 create mode 100644 libs/timer/src/auto_timers_construction.cpp create mode 100644 libs/timer/src/cpu_timer.cpp create mode 100644 tools/build/CONTRIBUTING.rst create mode 100644 tools/build/Jamroot.jam create mode 100644 tools/build/README.rst create mode 100644 tools/build/boost-build.jam create mode 100644 tools/build/bootstrap.bat create mode 100644 tools/build/bootstrap.sh create mode 100644 tools/build/bootstrap_vms.com create mode 100644 tools/build/doc/bjam.qbk create mode 100644 tools/build/doc/boost.png create mode 100644 tools/build/doc/boostbook.css create mode 100644 tools/build/doc/examples.qbk create mode 100644 tools/build/doc/history.qbk create mode 100644 tools/build/doc/images/alert.png create mode 100644 tools/build/doc/images/blank.png create mode 100644 tools/build/doc/images/callouts/1.png create mode 100644 tools/build/doc/images/callouts/1.svg create mode 100644 tools/build/doc/images/callouts/10.png create mode 100644 tools/build/doc/images/callouts/10.svg create mode 100644 tools/build/doc/images/callouts/11.png create mode 100644 tools/build/doc/images/callouts/11.svg create mode 100644 tools/build/doc/images/callouts/12.png create mode 100644 tools/build/doc/images/callouts/12.svg create mode 100644 tools/build/doc/images/callouts/13.png create mode 100644 tools/build/doc/images/callouts/13.svg create mode 100644 tools/build/doc/images/callouts/14.png create mode 100644 tools/build/doc/images/callouts/14.svg create mode 100644 tools/build/doc/images/callouts/15.png create mode 100644 tools/build/doc/images/callouts/15.svg create mode 100644 tools/build/doc/images/callouts/16.svg create mode 100644 tools/build/doc/images/callouts/17.svg create mode 100644 tools/build/doc/images/callouts/18.svg create mode 100644 tools/build/doc/images/callouts/19.svg create mode 100644 tools/build/doc/images/callouts/2.png create mode 100644 tools/build/doc/images/callouts/2.svg create mode 100644 tools/build/doc/images/callouts/20.svg create mode 100644 tools/build/doc/images/callouts/21.svg create mode 100644 tools/build/doc/images/callouts/22.svg create mode 100644 tools/build/doc/images/callouts/23.svg create mode 100644 tools/build/doc/images/callouts/24.svg create mode 100644 tools/build/doc/images/callouts/25.svg create mode 100644 tools/build/doc/images/callouts/26.svg create mode 100644 tools/build/doc/images/callouts/27.svg create mode 100644 tools/build/doc/images/callouts/28.svg create mode 100644 tools/build/doc/images/callouts/29.svg create mode 100644 tools/build/doc/images/callouts/3.png create mode 100644 tools/build/doc/images/callouts/3.svg create mode 100644 tools/build/doc/images/callouts/30.svg create mode 100644 tools/build/doc/images/callouts/4.png create mode 100644 tools/build/doc/images/callouts/4.svg create mode 100644 tools/build/doc/images/callouts/5.png create mode 100644 tools/build/doc/images/callouts/5.svg create mode 100644 tools/build/doc/images/callouts/6.png create mode 100644 tools/build/doc/images/callouts/6.svg create mode 100644 tools/build/doc/images/callouts/7.png create mode 100644 tools/build/doc/images/callouts/7.svg create mode 100644 tools/build/doc/images/callouts/8.png create mode 100644 tools/build/doc/images/callouts/8.svg create mode 100644 tools/build/doc/images/callouts/9.png create mode 100644 tools/build/doc/images/callouts/9.svg create mode 100644 tools/build/doc/images/caution.png create mode 100644 tools/build/doc/images/caution.svg create mode 100644 tools/build/doc/images/draft.png create mode 100644 tools/build/doc/images/home.png create mode 100644 tools/build/doc/images/home.svg create mode 100644 tools/build/doc/images/important.png create mode 100644 tools/build/doc/images/important.svg create mode 100644 tools/build/doc/images/next.png create mode 100644 tools/build/doc/images/next.svg create mode 100644 tools/build/doc/images/next_disabled.png create mode 100644 tools/build/doc/images/note.png create mode 100644 tools/build/doc/images/note.svg create mode 100644 tools/build/doc/images/prev.png create mode 100644 tools/build/doc/images/prev.svg create mode 100644 tools/build/doc/images/prev_disabled.png create mode 100644 tools/build/doc/images/smiley.png create mode 100644 tools/build/doc/images/tip.png create mode 100644 tools/build/doc/images/tip.svg create mode 100644 tools/build/doc/images/toc-blank.png create mode 100644 tools/build/doc/images/toc-minus.png create mode 100644 tools/build/doc/images/toc-plus.png create mode 100644 tools/build/doc/images/up.png create mode 100644 tools/build/doc/images/up.svg create mode 100644 tools/build/doc/images/up_disabled.png create mode 100644 tools/build/doc/images/warning.png create mode 100644 tools/build/doc/images/warning.svg create mode 100644 tools/build/doc/jamfile.jam create mode 100644 tools/build/doc/src/abstract-target.xml create mode 100644 tools/build/doc/src/architecture.xml create mode 100644 tools/build/doc/src/basic-target.xml create mode 100644 tools/build/doc/src/debug.xml create mode 100644 tools/build/doc/src/extending.xml create mode 100644 tools/build/doc/src/faq.xml create mode 100644 tools/build/doc/src/fragments.xml create mode 100644 tools/build/doc/src/howto.xml create mode 100644 tools/build/doc/src/install.xml create mode 100644 tools/build/doc/src/main-target.xml create mode 100644 tools/build/doc/src/overview.xml create mode 100644 tools/build/doc/src/path.xml create mode 100644 tools/build/doc/src/project-target.xml create mode 100644 tools/build/doc/src/property-set.xml create mode 100644 tools/build/doc/src/recipes.xml create mode 100644 tools/build/doc/src/reference.xml create mode 100644 tools/build/doc/src/regex.xml create mode 100644 tools/build/doc/src/sequence.xml create mode 100644 tools/build/doc/src/standalone.xml create mode 100644 tools/build/doc/src/tasks.xml create mode 100644 tools/build/doc/src/tools.adoc create mode 100644 tools/build/doc/src/tutorial.xml create mode 100644 tools/build/doc/src/type.xml create mode 100644 tools/build/doc/src/typed-target.xml create mode 100644 tools/build/doc/src/userman.xml create mode 100644 tools/build/example/asciidoctor/example.adoc create mode 100644 tools/build/example/asciidoctor/example_manpage.adoc create mode 100644 tools/build/example/asciidoctor/jamroot.jam create mode 100644 tools/build/example/boost-build.jam create mode 100644 tools/build/example/built_tool/Jamroot.jam create mode 100644 tools/build/example/built_tool/core/Jamfile.jam create mode 100644 tools/build/example/built_tool/core/a.td create mode 100644 tools/build/example/built_tool/core/core.cpp create mode 100644 tools/build/example/built_tool/readme.txt create mode 100644 tools/build/example/built_tool/tblgen/Jamfile.jam create mode 100644 tools/build/example/built_tool/tblgen/tblgen.cpp create mode 100644 tools/build/example/complex-testing/compile-fail.cpp create mode 100644 tools/build/example/complex-testing/fail.cpp create mode 100644 tools/build/example/complex-testing/jamroot.jam create mode 100644 tools/build/example/complex-testing/post.cpp create mode 100644 tools/build/example/complex-testing/success.cpp create mode 100644 tools/build/example/customization/class.verbatim create mode 100644 tools/build/example/customization/codegen.cpp create mode 100644 tools/build/example/customization/inline_file.py create mode 100644 tools/build/example/customization/jamroot.jam create mode 100644 tools/build/example/customization/readme.txt create mode 100644 tools/build/example/customization/t1.verbatim create mode 100644 tools/build/example/customization/t2.verbatim create mode 100644 tools/build/example/customization/usage.verbatim create mode 100644 tools/build/example/customization/verbatim.jam create mode 100644 tools/build/example/customization/verbatim.py create mode 100644 tools/build/example/generate/README.txt create mode 100644 tools/build/example/generate/a.cpp create mode 100644 tools/build/example/generate/gen.jam create mode 100644 tools/build/example/generate/gen.py create mode 100644 tools/build/example/generate/jamroot.jam create mode 100644 tools/build/example/generator/README.txt create mode 100644 tools/build/example/generator/foo.gci create mode 100644 tools/build/example/generator/jamroot.jam create mode 100644 tools/build/example/generator/soap.jam create mode 100644 tools/build/example/gettext/jamfile.jam create mode 100644 tools/build/example/gettext/jamroot.jam create mode 100644 tools/build/example/gettext/main.cpp create mode 100644 tools/build/example/gettext/readme.txt create mode 100644 tools/build/example/gettext/russian.po create mode 100644 tools/build/example/hello/hello.cpp create mode 100644 tools/build/example/hello/jamroot.jam create mode 100644 tools/build/example/hello/readme.qbk create mode 100644 tools/build/example/libraries/app/app.cpp create mode 100644 tools/build/example/libraries/app/jamfile.jam create mode 100644 tools/build/example/libraries/jamroot.jam create mode 100644 tools/build/example/libraries/util/foo/bar.cpp create mode 100644 tools/build/example/libraries/util/foo/include/lib1.h create mode 100644 tools/build/example/libraries/util/foo/jamfile.jam create mode 100644 tools/build/example/make/foo.py create mode 100644 tools/build/example/make/jamroot.jam create mode 100644 tools/build/example/make/main_cpp.pro create mode 100644 tools/build/example/make/readme.txt create mode 100644 tools/build/example/pch/include/pch.hpp create mode 100644 tools/build/example/pch/jamroot.jam create mode 100644 tools/build/example/pch/source/hello_world.cpp create mode 100644 tools/build/example/python_modules/jamroot.jam create mode 100644 tools/build/example/python_modules/python_helpers.jam create mode 100644 tools/build/example/python_modules/python_helpers.py create mode 100644 tools/build/example/python_modules/readme.txt create mode 100644 tools/build/example/qt/README.txt create mode 100644 tools/build/example/qt/qt3/hello/canvas.cpp create mode 100644 tools/build/example/qt/qt3/hello/canvas.h create mode 100644 tools/build/example/qt/qt3/hello/jamroot.jam create mode 100644 tools/build/example/qt/qt3/hello/main.cpp create mode 100644 tools/build/example/qt/qt3/moccable-cpp/jamroot.jam create mode 100644 tools/build/example/qt/qt3/moccable-cpp/main.cpp create mode 100644 tools/build/example/qt/qt3/uic/hello_world_widget.ui create mode 100644 tools/build/example/qt/qt3/uic/jamroot.jam create mode 100644 tools/build/example/qt/qt3/uic/main.cpp create mode 100644 tools/build/example/qt/qt4/hello/arrow.cpp create mode 100644 tools/build/example/qt/qt4/hello/arrow.h create mode 100644 tools/build/example/qt/qt4/hello/jamroot.jam create mode 100644 tools/build/example/qt/qt4/hello/main.cpp create mode 100644 tools/build/example/qt/qt4/moccable-cpp/jamroot.jam create mode 100644 tools/build/example/qt/qt4/moccable-cpp/main.cpp create mode 100644 tools/build/example/qt/qt4/uic/hello_world_widget.ui create mode 100644 tools/build/example/qt/qt4/uic/jamroot.jam create mode 100644 tools/build/example/qt/qt4/uic/main.cpp create mode 100644 tools/build/example/sass/importing.scss create mode 100644 tools/build/example/sass/include/foobar.scss create mode 100644 tools/build/example/sass/jamroot.jam create mode 100644 tools/build/example/sass/singleton.sass create mode 100644 tools/build/example/sass/singleton.scss create mode 100644 tools/build/example/site-config.jam create mode 100644 tools/build/example/testing/compile-fail.cpp create mode 100644 tools/build/example/testing/fail.cpp create mode 100644 tools/build/example/testing/jamroot.jam create mode 100644 tools/build/example/testing/success.cpp create mode 100644 tools/build/example/time/hello.cpp create mode 100644 tools/build/example/time/jamroot.jam create mode 100644 tools/build/example/time/readme.qbk create mode 100644 tools/build/example/try_compile/Jamroot.jam create mode 100644 tools/build/example/try_compile/foo.cpp create mode 100644 tools/build/example/try_compile/main.cpp create mode 100644 tools/build/example/user-config.jam create mode 100644 tools/build/example/variant/a.cpp create mode 100644 tools/build/example/variant/jamfile.jam create mode 100644 tools/build/example/variant/jamroot.jam create mode 100644 tools/build/example/variant/libs/jamfile.jam create mode 100644 tools/build/example/variant/libs/l.cpp create mode 100644 tools/build/example/variant/readme.qbk create mode 100644 tools/build/index.html create mode 100644 tools/build/notes/README.txt create mode 100644 tools/build/notes/build_dir_option.txt create mode 100644 tools/build/notes/changes.txt create mode 100644 tools/build/notes/relative_source_paths.txt create mode 100644 tools/build/notes/release_procedure.txt create mode 100644 tools/build/scripts/build-docs.sh create mode 100644 tools/build/scripts/nightly.sh create mode 100644 tools/build/scripts/roll.sh create mode 100644 tools/build/scripts/to_merge.sh create mode 100644 tools/build/src/__init__.py create mode 100644 tools/build/src/bootstrap.jam create mode 100644 tools/build/src/build-system.jam create mode 100644 tools/build/src/build/__init__.py create mode 100644 tools/build/src/build/ac.jam create mode 100644 tools/build/src/build/alias.jam create mode 100644 tools/build/src/build/alias.py create mode 100644 tools/build/src/build/build-request.jam create mode 100644 tools/build/src/build/build_request.py create mode 100644 tools/build/src/build/config-cache.jam create mode 100644 tools/build/src/build/configure.jam create mode 100644 tools/build/src/build/configure.py create mode 100644 tools/build/src/build/engine.py create mode 100644 tools/build/src/build/errors.py create mode 100644 tools/build/src/build/feature.jam create mode 100644 tools/build/src/build/feature.py create mode 100644 tools/build/src/build/generators.jam create mode 100644 tools/build/src/build/generators.py create mode 100644 tools/build/src/build/project.jam create mode 100644 tools/build/src/build/project.py create mode 100644 tools/build/src/build/property-set.jam create mode 100644 tools/build/src/build/property.jam create mode 100644 tools/build/src/build/property.py create mode 100644 tools/build/src/build/property_set.py create mode 100644 tools/build/src/build/readme.txt create mode 100644 tools/build/src/build/scanner.jam create mode 100644 tools/build/src/build/scanner.py create mode 100644 tools/build/src/build/targets.jam create mode 100644 tools/build/src/build/targets.py create mode 100644 tools/build/src/build/toolset.jam create mode 100644 tools/build/src/build/toolset.py create mode 100644 tools/build/src/build/type.jam create mode 100644 tools/build/src/build/type.py create mode 100644 tools/build/src/build/version.jam create mode 100644 tools/build/src/build/version.py create mode 100644 tools/build/src/build/virtual-target.jam create mode 100644 tools/build/src/build/virtual_target.py create mode 100644 tools/build/src/build_system.py create mode 100644 tools/build/src/contrib/__init__.py create mode 100644 tools/build/src/contrib/boost.jam create mode 100644 tools/build/src/contrib/boost.py create mode 100644 tools/build/src/contrib/modular.jam create mode 100644 tools/build/src/contrib/tntnet.jam create mode 100644 tools/build/src/contrib/wxFormBuilder.jam create mode 100644 tools/build/src/engine/Jambase create mode 100644 tools/build/src/engine/boehm_gc/AmigaOS.c create mode 100644 tools/build/src/engine/boehm_gc/BCC_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/ChangeLog create mode 100644 tools/build/src/engine/boehm_gc/EMX_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/MacOS.c create mode 100644 tools/build/src/engine/boehm_gc/MacProjects.sit.hqx create mode 100644 tools/build/src/engine/boehm_gc/Mac_files/MacOS_Test_config.h create mode 100644 tools/build/src/engine/boehm_gc/Mac_files/MacOS_config.h create mode 100644 tools/build/src/engine/boehm_gc/Mac_files/dataend.c create mode 100644 tools/build/src/engine/boehm_gc/Mac_files/datastart.c create mode 100644 tools/build/src/engine/boehm_gc/Makefile.DLLs create mode 100644 tools/build/src/engine/boehm_gc/Makefile.am create mode 100644 tools/build/src/engine/boehm_gc/Makefile.direct create mode 100644 tools/build/src/engine/boehm_gc/Makefile.dj create mode 100644 tools/build/src/engine/boehm_gc/Makefile.in create mode 100644 tools/build/src/engine/boehm_gc/NT_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/NT_STATIC_THREADS_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/NT_THREADS_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/NT_X64_STATIC_THREADS_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/OS2_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/PCR-Makefile create mode 100644 tools/build/src/engine/boehm_gc/README.QUICK create mode 100644 tools/build/src/engine/boehm_gc/SMakefile.amiga create mode 100644 tools/build/src/engine/boehm_gc/WCC_MAKEFILE create mode 100644 tools/build/src/engine/boehm_gc/acinclude.m4 create mode 100644 tools/build/src/engine/boehm_gc/aclocal.m4 create mode 100644 tools/build/src/engine/boehm_gc/add_gc_prefix.c create mode 100644 tools/build/src/engine/boehm_gc/allchblk.c create mode 100644 tools/build/src/engine/boehm_gc/alloc.c create mode 100644 tools/build/src/engine/boehm_gc/alpha_mach_dep.S create mode 100644 tools/build/src/engine/boehm_gc/backgraph.c create mode 100644 tools/build/src/engine/boehm_gc/bdw-gc.pc create mode 100644 tools/build/src/engine/boehm_gc/bdw-gc.pc.in create mode 100644 tools/build/src/engine/boehm_gc/blacklst.c create mode 100644 tools/build/src/engine/boehm_gc/callprocs create mode 100644 tools/build/src/engine/boehm_gc/checksums.c create mode 100644 tools/build/src/engine/boehm_gc/compile create mode 100644 tools/build/src/engine/boehm_gc/config.guess create mode 100644 tools/build/src/engine/boehm_gc/config.sub create mode 100644 tools/build/src/engine/boehm_gc/configure create mode 100644 tools/build/src/engine/boehm_gc/configure.ac create mode 100644 tools/build/src/engine/boehm_gc/configure.host create mode 100644 tools/build/src/engine/boehm_gc/configure_atomic_ops.sh create mode 100644 tools/build/src/engine/boehm_gc/cord/cord.am create mode 100644 tools/build/src/engine/boehm_gc/cord/cordbscs.c create mode 100644 tools/build/src/engine/boehm_gc/cord/cordprnt.c create mode 100644 tools/build/src/engine/boehm_gc/cord/cordtest.c create mode 100644 tools/build/src/engine/boehm_gc/cord/cordxtra.c create mode 100644 tools/build/src/engine/boehm_gc/cord/de.c create mode 100644 tools/build/src/engine/boehm_gc/cord/de_cmds.h create mode 100644 tools/build/src/engine/boehm_gc/cord/de_win.ICO create mode 100644 tools/build/src/engine/boehm_gc/cord/de_win.RC create mode 100644 tools/build/src/engine/boehm_gc/cord/de_win.c create mode 100644 tools/build/src/engine/boehm_gc/cord/de_win.h create mode 100644 tools/build/src/engine/boehm_gc/darwin_stop_world.c create mode 100644 tools/build/src/engine/boehm_gc/dbg_mlc.c create mode 100644 tools/build/src/engine/boehm_gc/depcomp create mode 100644 tools/build/src/engine/boehm_gc/digimars.mak create mode 100644 tools/build/src/engine/boehm_gc/doc/README create mode 100644 tools/build/src/engine/boehm_gc/doc/README.DGUX386 create mode 100644 tools/build/src/engine/boehm_gc/doc/README.Mac create mode 100644 tools/build/src/engine/boehm_gc/doc/README.MacOSX create mode 100644 tools/build/src/engine/boehm_gc/doc/README.OS2 create mode 100644 tools/build/src/engine/boehm_gc/doc/README.amiga create mode 100644 tools/build/src/engine/boehm_gc/doc/README.arm.cross create mode 100644 tools/build/src/engine/boehm_gc/doc/README.autoconf create mode 100644 tools/build/src/engine/boehm_gc/doc/README.changes create mode 100644 tools/build/src/engine/boehm_gc/doc/README.contributors create mode 100644 tools/build/src/engine/boehm_gc/doc/README.cords create mode 100644 tools/build/src/engine/boehm_gc/doc/README.darwin create mode 100644 tools/build/src/engine/boehm_gc/doc/README.dj create mode 100644 tools/build/src/engine/boehm_gc/doc/README.environment create mode 100644 tools/build/src/engine/boehm_gc/doc/README.ews4800 create mode 100644 tools/build/src/engine/boehm_gc/doc/README.hp create mode 100644 tools/build/src/engine/boehm_gc/doc/README.linux create mode 100644 tools/build/src/engine/boehm_gc/doc/README.macros create mode 100644 tools/build/src/engine/boehm_gc/doc/README.rs6000 create mode 100644 tools/build/src/engine/boehm_gc/doc/README.sgi create mode 100644 tools/build/src/engine/boehm_gc/doc/README.solaris2 create mode 100644 tools/build/src/engine/boehm_gc/doc/README.uts create mode 100644 tools/build/src/engine/boehm_gc/doc/README.win32 create mode 100644 tools/build/src/engine/boehm_gc/doc/README.win64 create mode 100644 tools/build/src/engine/boehm_gc/doc/barrett_diagram create mode 100644 tools/build/src/engine/boehm_gc/doc/debugging.html create mode 100644 tools/build/src/engine/boehm_gc/doc/doc.am create mode 100644 tools/build/src/engine/boehm_gc/doc/gc.man create mode 100644 tools/build/src/engine/boehm_gc/doc/gcdescr.html create mode 100644 tools/build/src/engine/boehm_gc/doc/gcinterface.html create mode 100644 tools/build/src/engine/boehm_gc/doc/leak.html create mode 100644 tools/build/src/engine/boehm_gc/doc/overview.html create mode 100644 tools/build/src/engine/boehm_gc/doc/porting.html create mode 100644 tools/build/src/engine/boehm_gc/doc/scale.html create mode 100644 tools/build/src/engine/boehm_gc/doc/simple_example.html create mode 100644 tools/build/src/engine/boehm_gc/doc/tree.html create mode 100644 tools/build/src/engine/boehm_gc/dyn_load.c create mode 100644 tools/build/src/engine/boehm_gc/finalize.c create mode 100644 tools/build/src/engine/boehm_gc/gc.mak create mode 100644 tools/build/src/engine/boehm_gc/gc_cpp.cc create mode 100644 tools/build/src/engine/boehm_gc/gc_cpp.cpp create mode 100644 tools/build/src/engine/boehm_gc/gc_dlopen.c create mode 100644 tools/build/src/engine/boehm_gc/gcj_mlc.c create mode 100644 tools/build/src/engine/boehm_gc/gcname.c create mode 100644 tools/build/src/engine/boehm_gc/headers.c create mode 100644 tools/build/src/engine/boehm_gc/hpux_test_and_clear.s create mode 100644 tools/build/src/engine/boehm_gc/ia64_save_regs_in_stack.s create mode 100644 tools/build/src/engine/boehm_gc/if_mach.c create mode 100644 tools/build/src/engine/boehm_gc/if_not_there.c create mode 100644 tools/build/src/engine/boehm_gc/include/cord.h create mode 100644 tools/build/src/engine/boehm_gc/include/ec.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_allocator.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_amiga_redirects.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_backptr.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_config_macros.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_cpp.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_gcj.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_inline.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_mark.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_pthread_redirects.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_tiny_fl.h create mode 100644 tools/build/src/engine/boehm_gc/include/gc_typed.h create mode 100644 tools/build/src/engine/boehm_gc/include/include.am create mode 100644 tools/build/src/engine/boehm_gc/include/javaxfc.h create mode 100644 tools/build/src/engine/boehm_gc/include/leak_detector.h create mode 100644 tools/build/src/engine/boehm_gc/include/new_gc_alloc.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/cord_pos.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/darwin_semaphore.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/darwin_stop_world.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/dbg_mlc.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/gc_hdrs.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/gc_locks.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/gc_pmark.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/gc_priv.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/gcconfig.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/msvc_dbg.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/pthread_stop_world.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/pthread_support.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/specific.h create mode 100644 tools/build/src/engine/boehm_gc/include/private/thread_local_alloc.h create mode 100644 tools/build/src/engine/boehm_gc/include/weakpointer.h create mode 100644 tools/build/src/engine/boehm_gc/install-sh create mode 100644 tools/build/src/engine/boehm_gc/libtool.m4 create mode 100644 tools/build/src/engine/boehm_gc/ltmain.sh create mode 100644 tools/build/src/engine/boehm_gc/mach_dep.c create mode 100644 tools/build/src/engine/boehm_gc/malloc.c create mode 100644 tools/build/src/engine/boehm_gc/mallocx.c create mode 100644 tools/build/src/engine/boehm_gc/mark.c create mode 100644 tools/build/src/engine/boehm_gc/mark_rts.c create mode 100644 tools/build/src/engine/boehm_gc/mips_sgi_mach_dep.s create mode 100644 tools/build/src/engine/boehm_gc/mips_ultrix_mach_dep.s create mode 100644 tools/build/src/engine/boehm_gc/misc.c create mode 100644 tools/build/src/engine/boehm_gc/missing create mode 100644 tools/build/src/engine/boehm_gc/mkinstalldirs create mode 100644 tools/build/src/engine/boehm_gc/msvc_dbg.c create mode 100644 tools/build/src/engine/boehm_gc/new_hblk.c create mode 100644 tools/build/src/engine/boehm_gc/obj_map.c create mode 100644 tools/build/src/engine/boehm_gc/os_dep.c create mode 100644 tools/build/src/engine/boehm_gc/pcr_interface.c create mode 100644 tools/build/src/engine/boehm_gc/pthread_stop_world.c create mode 100644 tools/build/src/engine/boehm_gc/pthread_support.c create mode 100644 tools/build/src/engine/boehm_gc/ptr_chck.c create mode 100644 tools/build/src/engine/boehm_gc/real_malloc.c create mode 100644 tools/build/src/engine/boehm_gc/reclaim.c create mode 100644 tools/build/src/engine/boehm_gc/rs6000_mach_dep.s create mode 100644 tools/build/src/engine/boehm_gc/setjmp_t.c create mode 100644 tools/build/src/engine/boehm_gc/sparc_mach_dep.S create mode 100644 tools/build/src/engine/boehm_gc/sparc_netbsd_mach_dep.s create mode 100644 tools/build/src/engine/boehm_gc/sparc_sunos4_mach_dep.s create mode 100644 tools/build/src/engine/boehm_gc/specific.c create mode 100644 tools/build/src/engine/boehm_gc/stubborn.c create mode 100644 tools/build/src/engine/boehm_gc/tests/leak_test.c create mode 100644 tools/build/src/engine/boehm_gc/tests/middle.c create mode 100644 tools/build/src/engine/boehm_gc/tests/test.c create mode 100644 tools/build/src/engine/boehm_gc/tests/test_cpp.cc create mode 100644 tools/build/src/engine/boehm_gc/tests/tests.am create mode 100644 tools/build/src/engine/boehm_gc/tests/thread_leak_test.c create mode 100644 tools/build/src/engine/boehm_gc/thread_local_alloc.c create mode 100644 tools/build/src/engine/boehm_gc/threadlibs.c create mode 100644 tools/build/src/engine/boehm_gc/typd_mlc.c create mode 100644 tools/build/src/engine/boehm_gc/version.h create mode 100644 tools/build/src/engine/boehm_gc/win32_threads.c create mode 100644 tools/build/src/engine/boost-jam.spec create mode 100644 tools/build/src/engine/boost-no-inspect create mode 100644 tools/build/src/engine/build.bat create mode 100644 tools/build/src/engine/build.jam create mode 100644 tools/build/src/engine/build.sh create mode 100644 tools/build/src/engine/build_vms.com create mode 100644 tools/build/src/engine/builtins.c create mode 100644 tools/build/src/engine/builtins.h create mode 100644 tools/build/src/engine/bump_version.py create mode 100644 tools/build/src/engine/class.c create mode 100644 tools/build/src/engine/class.h create mode 100644 tools/build/src/engine/command.c create mode 100644 tools/build/src/engine/command.h create mode 100644 tools/build/src/engine/compile.c create mode 100644 tools/build/src/engine/compile.h create mode 100644 tools/build/src/engine/config_toolset.bat create mode 100644 tools/build/src/engine/constants.c create mode 100644 tools/build/src/engine/constants.h create mode 100644 tools/build/src/engine/cwd.c create mode 100644 tools/build/src/engine/cwd.h create mode 100644 tools/build/src/engine/debian/changelog create mode 100644 tools/build/src/engine/debian/control create mode 100644 tools/build/src/engine/debian/copyright create mode 100644 tools/build/src/engine/debian/jam.man.sgml create mode 100644 tools/build/src/engine/debian/rules create mode 100644 tools/build/src/engine/debug.c create mode 100644 tools/build/src/engine/debug.h create mode 100644 tools/build/src/engine/debugger.c create mode 100644 tools/build/src/engine/debugger.h create mode 100644 tools/build/src/engine/execcmd.c create mode 100644 tools/build/src/engine/execcmd.h create mode 100644 tools/build/src/engine/execnt.c create mode 100644 tools/build/src/engine/execunix.c create mode 100644 tools/build/src/engine/execvms.c create mode 100644 tools/build/src/engine/filent.c create mode 100644 tools/build/src/engine/filesys.c create mode 100644 tools/build/src/engine/filesys.h create mode 100644 tools/build/src/engine/fileunix.c create mode 100644 tools/build/src/engine/filevms.c create mode 100644 tools/build/src/engine/frames.c create mode 100644 tools/build/src/engine/frames.h create mode 100644 tools/build/src/engine/function.c create mode 100644 tools/build/src/engine/function.h create mode 100644 tools/build/src/engine/glob.c create mode 100644 tools/build/src/engine/guess_toolset.bat create mode 100644 tools/build/src/engine/hash.c create mode 100644 tools/build/src/engine/hash.h create mode 100644 tools/build/src/engine/hcache.c create mode 100644 tools/build/src/engine/hcache.h create mode 100644 tools/build/src/engine/hdrmacro.c create mode 100644 tools/build/src/engine/hdrmacro.h create mode 100644 tools/build/src/engine/headers.c create mode 100644 tools/build/src/engine/headers.h create mode 100644 tools/build/src/engine/jam.c create mode 100644 tools/build/src/engine/jam.h create mode 100644 tools/build/src/engine/jambase.c create mode 100644 tools/build/src/engine/jambase.h create mode 100644 tools/build/src/engine/jamgram.c create mode 100644 tools/build/src/engine/jamgram.h create mode 100644 tools/build/src/engine/jamgram.y create mode 100644 tools/build/src/engine/jamgram.yy create mode 100644 tools/build/src/engine/jamgramtab.h create mode 100644 tools/build/src/engine/lists.c create mode 100644 tools/build/src/engine/lists.h create mode 100644 tools/build/src/engine/make.c create mode 100644 tools/build/src/engine/make.h create mode 100644 tools/build/src/engine/make1.c create mode 100644 tools/build/src/engine/md5.c create mode 100644 tools/build/src/engine/md5.h create mode 100644 tools/build/src/engine/mem.c create mode 100644 tools/build/src/engine/mem.h create mode 100644 tools/build/src/engine/mkjambase.c create mode 100644 tools/build/src/engine/modules.c create mode 100644 tools/build/src/engine/modules.h create mode 100644 tools/build/src/engine/modules/order.c create mode 100644 tools/build/src/engine/modules/path.c create mode 100644 tools/build/src/engine/modules/property-set.c create mode 100644 tools/build/src/engine/modules/readme.txt create mode 100644 tools/build/src/engine/modules/regex.c create mode 100644 tools/build/src/engine/modules/sequence.c create mode 100644 tools/build/src/engine/modules/set.c create mode 100644 tools/build/src/engine/native.c create mode 100644 tools/build/src/engine/native.h create mode 100644 tools/build/src/engine/object.c create mode 100644 tools/build/src/engine/object.h create mode 100644 tools/build/src/engine/option.c create mode 100644 tools/build/src/engine/option.h create mode 100644 tools/build/src/engine/output.c create mode 100644 tools/build/src/engine/output.h create mode 100644 tools/build/src/engine/parse.c create mode 100644 tools/build/src/engine/parse.h create mode 100644 tools/build/src/engine/patchlevel.h create mode 100644 tools/build/src/engine/pathnt.c create mode 100644 tools/build/src/engine/pathsys.c create mode 100644 tools/build/src/engine/pathsys.h create mode 100644 tools/build/src/engine/pathunix.c create mode 100644 tools/build/src/engine/pathvms.c create mode 100644 tools/build/src/engine/regexp.c create mode 100644 tools/build/src/engine/regexp.h create mode 100644 tools/build/src/engine/rules.c create mode 100644 tools/build/src/engine/rules.h create mode 100644 tools/build/src/engine/scan.c create mode 100644 tools/build/src/engine/scan.h create mode 100644 tools/build/src/engine/search.c create mode 100644 tools/build/src/engine/search.h create mode 100644 tools/build/src/engine/strings.c create mode 100644 tools/build/src/engine/strings.h create mode 100644 tools/build/src/engine/subst.c create mode 100644 tools/build/src/engine/subst.h create mode 100644 tools/build/src/engine/timestamp.c create mode 100644 tools/build/src/engine/timestamp.h create mode 100644 tools/build/src/engine/variable.c create mode 100644 tools/build/src/engine/variable.h create mode 100644 tools/build/src/engine/vswhere_usability_wrapper.cmd create mode 100644 tools/build/src/engine/w32_getreg.c create mode 100644 tools/build/src/engine/yyacc.c create mode 100644 tools/build/src/exceptions.py create mode 100644 tools/build/src/kernel/boost-build.jam create mode 100644 tools/build/src/kernel/bootstrap.jam create mode 100644 tools/build/src/kernel/bootstrap.py create mode 100644 tools/build/src/kernel/class.jam create mode 100644 tools/build/src/kernel/errors.jam create mode 100644 tools/build/src/kernel/modules.jam create mode 100644 tools/build/src/manager.py create mode 100644 tools/build/src/options/help.jam create mode 100644 tools/build/src/tools/__init__.py create mode 100644 tools/build/src/tools/acc.jam create mode 100644 tools/build/src/tools/asciidoctor.jam create mode 100644 tools/build/src/tools/auto-index.jam create mode 100644 tools/build/src/tools/bison.jam create mode 100644 tools/build/src/tools/boostbook-config.jam create mode 100644 tools/build/src/tools/boostbook.jam create mode 100644 tools/build/src/tools/borland.jam create mode 100644 tools/build/src/tools/builtin.jam create mode 100644 tools/build/src/tools/builtin.py create mode 100644 tools/build/src/tools/bzip2.jam create mode 100644 tools/build/src/tools/cast.jam create mode 100644 tools/build/src/tools/cast.py create mode 100644 tools/build/src/tools/clang-darwin.jam create mode 100644 tools/build/src/tools/clang-linux.jam create mode 100644 tools/build/src/tools/clang-vxworks.jam create mode 100644 tools/build/src/tools/clang-win.jam create mode 100644 tools/build/src/tools/clang.jam create mode 100644 tools/build/src/tools/common.jam create mode 100644 tools/build/src/tools/common.py create mode 100644 tools/build/src/tools/como-linux.jam create mode 100644 tools/build/src/tools/como-win.jam create mode 100644 tools/build/src/tools/como.jam create mode 100644 tools/build/src/tools/convert.jam create mode 100644 tools/build/src/tools/cray.jam create mode 100644 tools/build/src/tools/cw-config.jam create mode 100644 tools/build/src/tools/cw.jam create mode 100644 tools/build/src/tools/cygwin.jam create mode 100644 tools/build/src/tools/darwin.jam create mode 100644 tools/build/src/tools/darwin.py create mode 100644 tools/build/src/tools/diab.jam create mode 100644 tools/build/src/tools/dmc.jam create mode 100644 tools/build/src/tools/docutils.jam create mode 100644 tools/build/src/tools/doxproc.py create mode 100644 tools/build/src/tools/doxygen-config.jam create mode 100644 tools/build/src/tools/doxygen.jam create mode 100644 tools/build/src/tools/doxygen/windows-paths-check.doxyfile create mode 100644 tools/build/src/tools/doxygen/windows-paths-check.hpp create mode 100644 tools/build/src/tools/emscripten.jam create mode 100644 tools/build/src/tools/features/__init_features__.jam create mode 100644 tools/build/src/tools/features/address-model-feature.jam create mode 100644 tools/build/src/tools/features/allow-feature.jam create mode 100644 tools/build/src/tools/features/architecture-feature.jam create mode 100644 tools/build/src/tools/features/archiveflags-feature.jam create mode 100644 tools/build/src/tools/features/asmflags-feature.jam create mode 100644 tools/build/src/tools/features/build-feature.jam create mode 100644 tools/build/src/tools/features/cflags-feature.jam create mode 100644 tools/build/src/tools/features/conditional-feature.jam create mode 100644 tools/build/src/tools/features/cxx-template-depth-feature.jam create mode 100644 tools/build/src/tools/features/cxxabi-feature.jam create mode 100644 tools/build/src/tools/features/cxxflags-feature.jam create mode 100644 tools/build/src/tools/features/cxxstd-feature.jam create mode 100644 tools/build/src/tools/features/debug-feature.jam create mode 100644 tools/build/src/tools/features/define-feature.jam create mode 100644 tools/build/src/tools/features/dependency-feature.jam create mode 100644 tools/build/src/tools/features/dll-feature.jam create mode 100644 tools/build/src/tools/features/exception-feature.jam create mode 100644 tools/build/src/tools/features/fflags-feature.jam create mode 100644 tools/build/src/tools/features/file-feature.jam create mode 100644 tools/build/src/tools/features/find-lib-feature.jam create mode 100644 tools/build/src/tools/features/flags-feature.jam create mode 100644 tools/build/src/tools/features/include-feature.jam create mode 100644 tools/build/src/tools/features/instruction-set-feature.jam create mode 100644 tools/build/src/tools/features/internal-feature.jam create mode 100644 tools/build/src/tools/features/library-feature.jam create mode 100644 tools/build/src/tools/features/link-feature.jam create mode 100644 tools/build/src/tools/features/linkflags-feature.jam create mode 100644 tools/build/src/tools/features/location-feature.jam create mode 100644 tools/build/src/tools/features/location-prefix-feature.jam create mode 100644 tools/build/src/tools/features/name-feature.jam create mode 100644 tools/build/src/tools/features/objcflags-feature.jam create mode 100644 tools/build/src/tools/features/optimization-feature.jam create mode 100644 tools/build/src/tools/features/os-feature.jam create mode 100644 tools/build/src/tools/features/relevant-feature.jam create mode 100644 tools/build/src/tools/features/rtti-feature.jam create mode 100644 tools/build/src/tools/features/runtime-feature.jam create mode 100644 tools/build/src/tools/features/search-feature.jam create mode 100644 tools/build/src/tools/features/source-feature.jam create mode 100644 tools/build/src/tools/features/stdlib-feature.jam create mode 100644 tools/build/src/tools/features/strip-feature.jam create mode 100644 tools/build/src/tools/features/tag-feature.jam create mode 100644 tools/build/src/tools/features/threadapi-feature.jam create mode 100644 tools/build/src/tools/features/threading-feature.jam create mode 100644 tools/build/src/tools/features/toolset-feature.jam create mode 100644 tools/build/src/tools/features/user-interface-feature.jam create mode 100644 tools/build/src/tools/features/variant-feature.jam create mode 100644 tools/build/src/tools/features/version-feature.jam create mode 100644 tools/build/src/tools/features/warnings-feature.jam create mode 100644 tools/build/src/tools/flags.jam create mode 100644 tools/build/src/tools/fop.jam create mode 100644 tools/build/src/tools/fortran.jam create mode 100644 tools/build/src/tools/gcc.jam create mode 100644 tools/build/src/tools/gcc.py create mode 100644 tools/build/src/tools/generate.jam create mode 100644 tools/build/src/tools/generators/__init_generators__.jam create mode 100644 tools/build/src/tools/generators/archive-generator.jam create mode 100644 tools/build/src/tools/generators/c-compiling-generator.jam create mode 100644 tools/build/src/tools/generators/dummy-generator.jam create mode 100644 tools/build/src/tools/generators/lib-generator.jam create mode 100644 tools/build/src/tools/generators/linking-generator.jam create mode 100644 tools/build/src/tools/generators/prebuilt-lib-generator.jam create mode 100644 tools/build/src/tools/generators/searched-lib-generator.jam create mode 100644 tools/build/src/tools/gettext.jam create mode 100644 tools/build/src/tools/gfortran.jam create mode 100644 tools/build/src/tools/hp_cxx.jam create mode 100644 tools/build/src/tools/hpfortran.jam create mode 100644 tools/build/src/tools/ifort.jam create mode 100644 tools/build/src/tools/intel-darwin.jam create mode 100644 tools/build/src/tools/intel-linux.jam create mode 100644 tools/build/src/tools/intel-vxworks.jam create mode 100644 tools/build/src/tools/intel-win.jam create mode 100644 tools/build/src/tools/intel.jam create mode 100644 tools/build/src/tools/lex.jam create mode 100644 tools/build/src/tools/libjpeg.jam create mode 100644 tools/build/src/tools/libpng.jam create mode 100644 tools/build/src/tools/libtiff.jam create mode 100644 tools/build/src/tools/link.jam create mode 100644 tools/build/src/tools/lzma.jam create mode 100644 tools/build/src/tools/make.jam create mode 100644 tools/build/src/tools/make.py create mode 100644 tools/build/src/tools/mc.jam create mode 100644 tools/build/src/tools/mc.py create mode 100644 tools/build/src/tools/message.jam create mode 100644 tools/build/src/tools/message.py create mode 100644 tools/build/src/tools/midl.jam create mode 100644 tools/build/src/tools/midl.py create mode 100644 tools/build/src/tools/mipspro.jam create mode 100644 tools/build/src/tools/mpi.jam create mode 100644 tools/build/src/tools/msvc-config.jam create mode 100644 tools/build/src/tools/msvc.jam create mode 100644 tools/build/src/tools/msvc.py create mode 100644 tools/build/src/tools/notfile.jam create mode 100644 tools/build/src/tools/notfile.py create mode 100644 tools/build/src/tools/package.jam create mode 100644 tools/build/src/tools/package.py create mode 100644 tools/build/src/tools/pathscale.jam create mode 100644 tools/build/src/tools/pch.jam create mode 100644 tools/build/src/tools/pch.py create mode 100644 tools/build/src/tools/pgi.jam create mode 100644 tools/build/src/tools/python-config.jam create mode 100644 tools/build/src/tools/python.jam create mode 100644 tools/build/src/tools/qcc.jam create mode 100644 tools/build/src/tools/qt.jam create mode 100644 tools/build/src/tools/qt3.jam create mode 100644 tools/build/src/tools/qt4.jam create mode 100644 tools/build/src/tools/qt5.jam create mode 100644 tools/build/src/tools/quickbook-config.jam create mode 100644 tools/build/src/tools/quickbook.jam create mode 100644 tools/build/src/tools/rc.jam create mode 100644 tools/build/src/tools/rc.py create mode 100644 tools/build/src/tools/sass.jam create mode 100644 tools/build/src/tools/stage.jam create mode 100644 tools/build/src/tools/stage.py create mode 100644 tools/build/src/tools/stlport.jam create mode 100644 tools/build/src/tools/sun.jam create mode 100644 tools/build/src/tools/symlink.jam create mode 100644 tools/build/src/tools/symlink.py create mode 100644 tools/build/src/tools/testing-aux.jam create mode 100644 tools/build/src/tools/testing.jam create mode 100644 tools/build/src/tools/testing.py create mode 100644 tools/build/src/tools/types/__init__.py create mode 100644 tools/build/src/tools/types/adoc.jam create mode 100644 tools/build/src/tools/types/asm.jam create mode 100644 tools/build/src/tools/types/asm.py create mode 100644 tools/build/src/tools/types/cpp.jam create mode 100644 tools/build/src/tools/types/cpp.py create mode 100644 tools/build/src/tools/types/css.jam create mode 100644 tools/build/src/tools/types/docbook.jam create mode 100644 tools/build/src/tools/types/exe.jam create mode 100644 tools/build/src/tools/types/exe.py create mode 100644 tools/build/src/tools/types/html.jam create mode 100644 tools/build/src/tools/types/html.py create mode 100644 tools/build/src/tools/types/lib.jam create mode 100644 tools/build/src/tools/types/lib.py create mode 100644 tools/build/src/tools/types/man.jam create mode 100644 tools/build/src/tools/types/markdown.jam create mode 100644 tools/build/src/tools/types/markdown.py create mode 100644 tools/build/src/tools/types/obj.jam create mode 100644 tools/build/src/tools/types/obj.py create mode 100644 tools/build/src/tools/types/objc.jam create mode 100644 tools/build/src/tools/types/pdf.jam create mode 100644 tools/build/src/tools/types/preprocessed.jam create mode 100644 tools/build/src/tools/types/preprocessed.py create mode 100644 tools/build/src/tools/types/qt.jam create mode 100644 tools/build/src/tools/types/register.jam create mode 100644 tools/build/src/tools/types/rsp.jam create mode 100644 tools/build/src/tools/types/rsp.py create mode 100644 tools/build/src/tools/types/sass-type.jam create mode 100644 tools/build/src/tools/types/xml.jam create mode 100644 tools/build/src/tools/unix.jam create mode 100644 tools/build/src/tools/unix.py create mode 100644 tools/build/src/tools/vacpp.jam create mode 100644 tools/build/src/tools/vmsdecc.jam create mode 100644 tools/build/src/tools/whale.jam create mode 100644 tools/build/src/tools/xlcpp.jam create mode 100644 tools/build/src/tools/xlf.jam create mode 100644 tools/build/src/tools/xsltproc-config.jam create mode 100644 tools/build/src/tools/xsltproc.jam create mode 100644 tools/build/src/tools/xsltproc/included.xsl create mode 100644 tools/build/src/tools/xsltproc/test.xml create mode 100644 tools/build/src/tools/xsltproc/test.xsl create mode 100644 tools/build/src/tools/zlib.jam create mode 100644 tools/build/src/tools/zstd.jam create mode 100644 tools/build/src/util/__init__.py create mode 100644 tools/build/src/util/assert.jam create mode 100644 tools/build/src/util/container.jam create mode 100644 tools/build/src/util/doc.jam create mode 100644 tools/build/src/util/indirect.jam create mode 100644 tools/build/src/util/indirect.py create mode 100644 tools/build/src/util/logger.py create mode 100644 tools/build/src/util/numbers.jam create mode 100644 tools/build/src/util/option.jam create mode 100644 tools/build/src/util/option.py create mode 100644 tools/build/src/util/order.jam create mode 100644 tools/build/src/util/order.py create mode 100644 tools/build/src/util/os.jam create mode 100644 tools/build/src/util/os_j.py create mode 100644 tools/build/src/util/param.jam create mode 100644 tools/build/src/util/path.jam create mode 100644 tools/build/src/util/path.py create mode 100644 tools/build/src/util/print.jam create mode 100644 tools/build/src/util/regex.jam create mode 100644 tools/build/src/util/regex.py create mode 100644 tools/build/src/util/sequence.jam create mode 100644 tools/build/src/util/sequence.py create mode 100644 tools/build/src/util/set.jam create mode 100644 tools/build/src/util/set.py create mode 100644 tools/build/src/util/string.jam create mode 100644 tools/build/src/util/utility.jam create mode 100644 tools/build/src/util/utility.py create mode 100644 tools/build/test/BoostBuild.py create mode 100644 tools/build/test/Jamfile.jam create mode 100644 tools/build/test/MockToolset.py create mode 100644 tools/build/test/TestCmd.py create mode 100644 tools/build/test/TestToolset.py create mode 100644 tools/build/test/abs_workdir.py create mode 100644 tools/build/test/absolute_sources.py create mode 100644 tools/build/test/alias.py create mode 100644 tools/build/test/alternatives.py create mode 100644 tools/build/test/bad_dirname.py create mode 100644 tools/build/test/boost-build.jam create mode 100644 tools/build/test/boostbook.py create mode 100644 tools/build/test/boostbook/a.hpp create mode 100644 tools/build/test/boostbook/docs.xml create mode 100644 tools/build/test/boostbook/jamroot.jam create mode 100644 tools/build/test/build_dir.py create mode 100644 tools/build/test/build_file.py create mode 100644 tools/build/test/build_hooks.py create mode 100644 tools/build/test/build_no.py create mode 100644 tools/build/test/builtin_echo.py create mode 100644 tools/build/test/builtin_exit.py create mode 100644 tools/build/test/builtin_glob.py create mode 100644 tools/build/test/builtin_glob_archive.py create mode 100644 tools/build/test/builtin_readlink.py create mode 100644 tools/build/test/builtin_split_by_characters.py create mode 100644 tools/build/test/bzip2.py create mode 100644 tools/build/test/c_file.py create mode 100644 tools/build/test/chain.py create mode 100644 tools/build/test/clean.py create mode 100644 tools/build/test/cli_property_expansion.py create mode 100644 tools/build/test/collect_debug_info.py create mode 100644 tools/build/test/command_line_properties.py create mode 100644 tools/build/test/composite.py create mode 100644 tools/build/test/conditionals.py create mode 100644 tools/build/test/conditionals2.py create mode 100644 tools/build/test/conditionals3.py create mode 100644 tools/build/test/conditionals_multiple.py create mode 100644 tools/build/test/configuration.py create mode 100644 tools/build/test/configure.py create mode 100644 tools/build/test/copy_time.py create mode 100644 tools/build/test/core-language/test.jam create mode 100644 tools/build/test/core_action_output.py create mode 100644 tools/build/test/core_action_status.py create mode 100644 tools/build/test/core_actions_quietly.py create mode 100644 tools/build/test/core_arguments.py create mode 100644 tools/build/test/core_at_file.py create mode 100644 tools/build/test/core_bindrule.py create mode 100644 tools/build/test/core_d12.py create mode 100644 tools/build/test/core_delete_module.py create mode 100644 tools/build/test/core_dependencies.py create mode 100644 tools/build/test/core_fail_expected.py create mode 100644 tools/build/test/core_import_module.py create mode 100644 tools/build/test/core_jamshell.py create mode 100644 tools/build/test/core_language.py create mode 100644 tools/build/test/core_modifiers.py create mode 100644 tools/build/test/core_multifile_actions.py create mode 100644 tools/build/test/core_nt_cmd_line.py create mode 100644 tools/build/test/core_option_d2.py create mode 100644 tools/build/test/core_option_l.py create mode 100644 tools/build/test/core_option_n.py create mode 100644 tools/build/test/core_parallel_actions.py create mode 100644 tools/build/test/core_parallel_multifile_actions_1.py create mode 100644 tools/build/test/core_parallel_multifile_actions_2.py create mode 100644 tools/build/test/core_scanner.py create mode 100644 tools/build/test/core_source_line_tracking.py create mode 100644 tools/build/test/core_typecheck.py create mode 100644 tools/build/test/core_update_now.py create mode 100644 tools/build/test/core_variables_in_actions.py create mode 100644 tools/build/test/core_varnames.py create mode 100644 tools/build/test/custom_generator.py create mode 100644 tools/build/test/debugger-mi.py create mode 100644 tools/build/test/debugger.py create mode 100644 tools/build/test/default_build.py create mode 100644 tools/build/test/default_features.py create mode 100644 tools/build/test/default_toolset.py create mode 100644 tools/build/test/dependency_property.py create mode 100644 tools/build/test/dependency_test.py create mode 100644 tools/build/test/disambiguation.py create mode 100644 tools/build/test/dll_path.py create mode 100644 tools/build/test/double_loading.py create mode 100644 tools/build/test/duplicate.py create mode 100644 tools/build/test/example_customization.py create mode 100644 tools/build/test/example_gettext.py create mode 100644 tools/build/test/example_libraries.py create mode 100644 tools/build/test/example_make.py create mode 100644 tools/build/test/example_qt4.py create mode 100644 tools/build/test/exit_status.py create mode 100644 tools/build/test/expansion.py create mode 100644 tools/build/test/explicit.py create mode 100644 tools/build/test/feature_cxxflags.py create mode 100644 tools/build/test/feature_implicit_dependency.py create mode 100644 tools/build/test/feature_relevant.py create mode 100644 tools/build/test/feature_suppress_import_lib.py create mode 100644 tools/build/test/file_types.py create mode 100644 tools/build/test/flags.py create mode 100644 tools/build/test/gcc_runtime.py create mode 100644 tools/build/test/generator_selection.py create mode 100644 tools/build/test/generators_test.py create mode 100644 tools/build/test/implicit_dependency.py create mode 100644 tools/build/test/indirect_conditional.py create mode 100644 tools/build/test/inherit_toolset.py create mode 100644 tools/build/test/inherited_dependency.py create mode 100644 tools/build/test/inline.py create mode 100644 tools/build/test/lib_source_property.py create mode 100644 tools/build/test/lib_zlib.py create mode 100644 tools/build/test/libjpeg.py create mode 100644 tools/build/test/liblzma.py create mode 100644 tools/build/test/libpng.py create mode 100644 tools/build/test/library_chain.py create mode 100644 tools/build/test/library_order.py create mode 100644 tools/build/test/library_property.py create mode 100644 tools/build/test/libtiff.py create mode 100644 tools/build/test/libzstd.py create mode 100644 tools/build/test/link.py create mode 100644 tools/build/test/load_dir.py create mode 100644 tools/build/test/load_order.py create mode 100644 tools/build/test/loop.py create mode 100644 tools/build/test/make_rule.py create mode 100644 tools/build/test/message.py create mode 100644 tools/build/test/module_actions.py create mode 100644 tools/build/test/ndebug.py create mode 100644 tools/build/test/no_type.py create mode 100644 tools/build/test/notfile.py create mode 100644 tools/build/test/ordered_include.py create mode 100644 tools/build/test/ordered_properties.py create mode 100644 tools/build/test/out_of_tree.py create mode 100644 tools/build/test/param.py create mode 100644 tools/build/test/path_features.py create mode 100644 tools/build/test/pch.py create mode 100644 tools/build/test/prebuilt.py create mode 100644 tools/build/test/prebuilt/ext/a.cpp create mode 100644 tools/build/test/prebuilt/ext/debug/a.h create mode 100644 tools/build/test/prebuilt/ext/jamfile.jam create mode 100644 tools/build/test/prebuilt/ext/jamfile2.jam create mode 100644 tools/build/test/prebuilt/ext/jamfile3.jam create mode 100644 tools/build/test/prebuilt/ext/jamroot.jam create mode 100644 tools/build/test/prebuilt/ext/release/a.h create mode 100644 tools/build/test/prebuilt/hello.cpp create mode 100644 tools/build/test/prebuilt/jamfile.jam create mode 100644 tools/build/test/prebuilt/jamroot.jam create mode 100644 tools/build/test/preprocessor.py create mode 100644 tools/build/test/print.py create mode 100644 tools/build/test/project-test3/a.cpp create mode 100644 tools/build/test/project-test3/jamfile.jam create mode 100644 tools/build/test/project-test3/jamroot.jam create mode 100644 tools/build/test/project-test3/lib/b.cpp create mode 100644 tools/build/test/project-test3/lib/jamfile.jam create mode 100644 tools/build/test/project-test3/lib2/c.cpp create mode 100644 tools/build/test/project-test3/lib2/d.cpp create mode 100644 tools/build/test/project-test3/lib2/helper/e.cpp create mode 100644 tools/build/test/project-test3/lib2/helper/jamfile.jam create mode 100644 tools/build/test/project-test3/lib2/jamfile.jam create mode 100644 tools/build/test/project-test3/lib3/f.cpp create mode 100644 tools/build/test/project-test3/lib3/jamfile.jam create mode 100644 tools/build/test/project-test3/lib3/jamroot.jam create mode 100644 tools/build/test/project-test3/readme.txt create mode 100644 tools/build/test/project-test4/a.cpp create mode 100644 tools/build/test/project-test4/a_gcc.cpp create mode 100644 tools/build/test/project-test4/jamfile.jam create mode 100644 tools/build/test/project-test4/jamfile3.jam create mode 100644 tools/build/test/project-test4/jamfile4.jam create mode 100644 tools/build/test/project-test4/jamfile5.jam create mode 100644 tools/build/test/project-test4/jamroot.jam create mode 100644 tools/build/test/project-test4/lib/b.cpp create mode 100644 tools/build/test/project-test4/lib/jamfile.jam create mode 100644 tools/build/test/project-test4/lib/jamfile1.jam create mode 100644 tools/build/test/project-test4/lib/jamfile2.jam create mode 100644 tools/build/test/project-test4/lib/jamfile3.jam create mode 100644 tools/build/test/project-test4/lib2/jamfile.jam create mode 100644 tools/build/test/project-test4/lib2/jamfile2.jam create mode 100644 tools/build/test/project-test4/readme.txt create mode 100644 tools/build/test/project_dependencies.py create mode 100644 tools/build/test/project_glob.py create mode 100644 tools/build/test/project_id.py create mode 100644 tools/build/test/project_root_constants.py create mode 100644 tools/build/test/project_root_rule.py create mode 100644 tools/build/test/project_test3.py create mode 100644 tools/build/test/project_test4.py create mode 100644 tools/build/test/property_expansion.py create mode 100644 tools/build/test/qt4.py create mode 100644 tools/build/test/qt4/jamroot.jam create mode 100644 tools/build/test/qt4/mock.cpp create mode 100644 tools/build/test/qt4/mock.h create mode 100644 tools/build/test/qt4/phonon.cpp create mode 100644 tools/build/test/qt4/qt3support.cpp create mode 100644 tools/build/test/qt4/qtassistant.cpp create mode 100644 tools/build/test/qt4/qtcore.cpp create mode 100644 tools/build/test/qt4/qtcorefail.cpp create mode 100644 tools/build/test/qt4/qtdeclarative.cpp create mode 100644 tools/build/test/qt4/qtgui.cpp create mode 100644 tools/build/test/qt4/qthelp.cpp create mode 100644 tools/build/test/qt4/qtmultimedia.cpp create mode 100644 tools/build/test/qt4/qtnetwork.cpp create mode 100644 tools/build/test/qt4/qtscript.cpp create mode 100644 tools/build/test/qt4/qtscripttools.cpp create mode 100644 tools/build/test/qt4/qtsql.cpp create mode 100644 tools/build/test/qt4/qtsvg.cpp create mode 100644 tools/build/test/qt4/qttest.cpp create mode 100644 tools/build/test/qt4/qtwebkit.cpp create mode 100644 tools/build/test/qt4/qtxml.cpp create mode 100644 tools/build/test/qt4/qtxmlpatterns.cpp create mode 100644 tools/build/test/qt4/rcc.cpp create mode 100644 tools/build/test/qt4/rcc.qrc create mode 100644 tools/build/test/qt5.py create mode 100644 tools/build/test/qt5/jamroot.jam create mode 100644 tools/build/test/qt5/mock.cpp create mode 100644 tools/build/test/qt5/mock.h create mode 100644 tools/build/test/qt5/qt3dcore.cpp create mode 100644 tools/build/test/qt5/qt3dinput.cpp create mode 100644 tools/build/test/qt5/qt3dlogic.cpp create mode 100644 tools/build/test/qt5/qt3drender.cpp create mode 100644 tools/build/test/qt5/qtassistant.cpp create mode 100644 tools/build/test/qt5/qtbluetooth.cpp create mode 100644 tools/build/test/qt5/qtcharts.cpp create mode 100644 tools/build/test/qt5/qtcore.cpp create mode 100644 tools/build/test/qt5/qtcorefail.cpp create mode 100644 tools/build/test/qt5/qtdatavisualization.cpp create mode 100644 tools/build/test/qt5/qtdeclarative.cpp create mode 100644 tools/build/test/qt5/qtgamepad.cpp create mode 100644 tools/build/test/qt5/qthelp.cpp create mode 100644 tools/build/test/qt5/qtlocation.cpp create mode 100644 tools/build/test/qt5/qtmultimedia.cpp create mode 100644 tools/build/test/qt5/qtnetwork.cpp create mode 100644 tools/build/test/qt5/qtnfc.cpp create mode 100644 tools/build/test/qt5/qtpositioning.cpp create mode 100644 tools/build/test/qt5/qtpurchasing.cpp create mode 100644 tools/build/test/qt5/qtquick.cpp create mode 100644 tools/build/test/qt5/qtquick.qml create mode 100644 tools/build/test/qt5/qtscript.cpp create mode 100644 tools/build/test/qt5/qtscripttools.cpp create mode 100644 tools/build/test/qt5/qtscxml.cpp create mode 100644 tools/build/test/qt5/qtserialbus.cpp create mode 100644 tools/build/test/qt5/qtserialport.cpp create mode 100644 tools/build/test/qt5/qtsql.cpp create mode 100644 tools/build/test/qt5/qtsvg.cpp create mode 100644 tools/build/test/qt5/qttest.cpp create mode 100644 tools/build/test/qt5/qtwebchannel.cpp create mode 100644 tools/build/test/qt5/qtwebengine.cpp create mode 100644 tools/build/test/qt5/qtwebenginewidgets.cpp create mode 100644 tools/build/test/qt5/qtwebkit.cpp create mode 100644 tools/build/test/qt5/qtwebkitwidgets.cpp create mode 100644 tools/build/test/qt5/qtwebsocket.cpp create mode 100644 tools/build/test/qt5/qtwebsockets.cpp create mode 100644 tools/build/test/qt5/qtwebview.cpp create mode 100644 tools/build/test/qt5/qtwidgets.cpp create mode 100644 tools/build/test/qt5/qtxml.cpp create mode 100644 tools/build/test/qt5/qtxmlpatterns.cpp create mode 100644 tools/build/test/qt5/rcc.cpp create mode 100644 tools/build/test/qt5/rcc.qrc create mode 100644 tools/build/test/railsys.py create mode 100644 tools/build/test/railsys/libx/include/test_libx.h create mode 100644 tools/build/test/railsys/libx/jamroot.jam create mode 100644 tools/build/test/railsys/libx/src/jamfile.jam create mode 100644 tools/build/test/railsys/libx/src/test_libx.cpp create mode 100644 tools/build/test/railsys/program/include/test_a.h create mode 100644 tools/build/test/railsys/program/jamfile.jam create mode 100644 tools/build/test/railsys/program/jamroot.jam create mode 100644 tools/build/test/railsys/program/liba/jamfile.jam create mode 100644 tools/build/test/railsys/program/liba/test_a.cpp create mode 100644 tools/build/test/railsys/program/main/jamfile.jam create mode 100644 tools/build/test/railsys/program/main/main.cpp create mode 100644 tools/build/test/readme.txt create mode 100644 tools/build/test/rebuilds.py create mode 100644 tools/build/test/relative_sources.py create mode 100644 tools/build/test/remove_requirement.py create mode 100644 tools/build/test/rescan_header.py create mode 100644 tools/build/test/resolution.py create mode 100644 tools/build/test/results-python.txt create mode 100644 tools/build/test/scanner_causing_rebuilds.py create mode 100644 tools/build/test/searched_lib.py create mode 100644 tools/build/test/skipping.py create mode 100644 tools/build/test/sort_rule.py create mode 100644 tools/build/test/source_locations.py create mode 100644 tools/build/test/source_order.py create mode 100644 tools/build/test/space_in_path.py create mode 100644 tools/build/test/stage.py create mode 100644 tools/build/test/standalone.py create mode 100644 tools/build/test/startup/boost-root/boost-build.jam create mode 100644 tools/build/test/startup/boost-root/build/boost-build.jam create mode 100644 tools/build/test/startup/boost-root/build/bootstrap.jam create mode 100644 tools/build/test/startup/bootstrap-env/boost-build.jam create mode 100644 tools/build/test/startup/bootstrap-explicit/boost-build.jam create mode 100644 tools/build/test/startup/bootstrap-implicit/readme.txt create mode 100644 tools/build/test/startup/no-bootstrap1/boost-build.jam create mode 100644 tools/build/test/startup/no-bootstrap1/subdir/readme.txt create mode 100644 tools/build/test/startup/no-bootstrap2/boost-build.jam create mode 100644 tools/build/test/startup/no-bootstrap3/boost-build.jam create mode 100644 tools/build/test/startup_v2.py create mode 100644 tools/build/test/static_and_shared_library.py create mode 100644 tools/build/test/suffix.py create mode 100644 tools/build/test/symlink.py create mode 100644 tools/build/test/tag.py create mode 100644 tools/build/test/template.py create mode 100644 tools/build/test/test-config-example.jam create mode 100644 tools/build/test/test.jam create mode 100644 tools/build/test/test1.py create mode 100644 tools/build/test/test2.py create mode 100644 tools/build/test/test2/foo.cpp create mode 100644 tools/build/test/test2/jamroot.jam create mode 100644 tools/build/test/test_all.py create mode 100644 tools/build/test/test_rc.py create mode 100644 tools/build/test/test_system.html create mode 100644 tools/build/test/testing.py create mode 100644 tools/build/test/timedata.py create mode 100644 tools/build/test/toolset-mock/Jamroot.jam create mode 100644 tools/build/test/toolset-mock/lib.cpp create mode 100644 tools/build/test/toolset-mock/main.cpp create mode 100644 tools/build/test/toolset-mock/project-config.jam create mode 100644 tools/build/test/toolset-mock/src/Jamroot.jam create mode 100644 tools/build/test/toolset-mock/src/MockProgram.py create mode 100644 tools/build/test/toolset-mock/src/ar.py create mode 100644 tools/build/test/toolset-mock/src/clang-3.9.0-darwin.py create mode 100644 tools/build/test/toolset-mock/src/clang-linux-3.9.0.py create mode 100644 tools/build/test/toolset-mock/src/clang-vxworks-4.0.1.py create mode 100644 tools/build/test/toolset-mock/src/darwin-4.2.1.py create mode 100644 tools/build/test/toolset-mock/src/gcc-4.2.1-darwin.py create mode 100644 tools/build/test/toolset-mock/src/gcc-4.8.3-linux.py create mode 100644 tools/build/test/toolset-mock/src/intel-darwin-10.2.py create mode 100644 tools/build/test/toolset-mock/src/ld.py create mode 100644 tools/build/test/toolset-mock/src/libtool.py create mode 100644 tools/build/test/toolset-mock/src/mock-program.cpp create mode 100644 tools/build/test/toolset-mock/src/project-config.jam create mode 100644 tools/build/test/toolset-mock/src/ranlib.py create mode 100644 tools/build/test/toolset-mock/src/strip.py create mode 100644 tools/build/test/toolset-mock/src/verify.py create mode 100644 tools/build/test/toolset_clang_darwin.py create mode 100644 tools/build/test/toolset_clang_linux.py create mode 100644 tools/build/test/toolset_clang_vxworks.py create mode 100644 tools/build/test/toolset_darwin.py create mode 100644 tools/build/test/toolset_defaults.py create mode 100644 tools/build/test/toolset_gcc.py create mode 100644 tools/build/test/toolset_intel_darwin.py create mode 100644 tools/build/test/toolset_requirements.py create mode 100644 tools/build/test/tree.py create mode 100644 tools/build/test/unit_test.py create mode 100644 tools/build/test/unit_tests.py create mode 100644 tools/build/test/unused.py create mode 100644 tools/build/test/use_requirements.py create mode 100644 tools/build/test/using.py create mode 100644 tools/build/test/wrapper.py create mode 100644 tools/build/test/wrong_project.py create mode 100644 tools/build/tutorial.html create mode 100644 tools/build/website/boost.css create mode 100644 tools/build/website/boost_build.png create mode 100644 tools/build/website/boost_build.svg create mode 100644 tools/build/website/bootstrap/css/bootstrap-theme.css create mode 100644 tools/build/website/bootstrap/css/bootstrap-theme.min.css create mode 100644 tools/build/website/bootstrap/css/bootstrap.css create mode 100644 tools/build/website/bootstrap/css/bootstrap.min.css create mode 100644 tools/build/website/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 tools/build/website/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 tools/build/website/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 tools/build/website/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 tools/build/website/bootstrap/js/bootstrap.js create mode 100644 tools/build/website/bootstrap/js/bootstrap.min.js create mode 100644 tools/build/website/index.css diff --git a/Jamroot b/Jamroot new file mode 100644 index 00000000..c285815f --- /dev/null +++ b/Jamroot @@ -0,0 +1,340 @@ +# Copyright Vladimir Prus 2002-2006. +# Copyright Dave Abrahams 2005-2006. +# Copyright Rene Rivera 2005-2007. +# Copyright Douglas Gregor 2005. +# +# 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) + +# Usage: +# +# b2 [options] [properties] [install|stage] +# +# Builds and installs Boost. +# +# Targets and Related Options: +# +# install Install headers and compiled library files to the +# ======= configured locations (below). +# +# --prefix= Install architecture independent files here. +# Default; C:\Boost on Win32 +# Default; /usr/local on Unix. Linux, etc. +# +# --exec-prefix= Install architecture dependent files here. +# Default; +# +# --libdir= Install library files here. +# Default; /lib +# +# --includedir= Install header files here. +# Default; /include +# +# stage Build and install only compiled library files to the +# ===== stage directory. +# +# --stagedir= Install library files here +# Default; ./stage +# +# Other Options: +# +# --build-type= Build the specified pre-defined set of variations of +# the libraries. Note, that which variants get built +# depends on what each library supports. +# +# -- minimal -- (default) Builds a minimal set of +# variants. On Windows, these are static +# multithreaded libraries in debug and release +# modes, using shared runtime. On Linux, these are +# static and shared multithreaded libraries in +# release mode. +# +# -- complete -- Build all possible variations. +# +# --build-dir=DIR Build in this location instead of building within +# the distribution tree. Recommended! +# +# --show-libraries Display the list of Boost libraries that require +# build and installation steps, and then exit. +# +# --layout= Determine whether to choose library names and header +# locations such that multiple versions of Boost or +# multiple compilers can be used on the same system. +# +# -- versioned -- Names of boost binaries include +# the Boost version number, name and version of +# the compiler and encoded build properties. Boost +# headers are installed in a subdirectory of +# whose name contains the Boost version +# number. +# +# -- tagged -- Names of boost binaries include the +# encoded build properties such as variant and +# threading, but do not including compiler name +# and version, or Boost version. This option is +# useful if you build several variants of Boost, +# using the same compiler. +# +# -- system -- Binaries names do not include the +# Boost version number or the name and version +# number of the compiler. Boost headers are +# installed directly into . This option is +# intended for system integrators building +# distribution packages. +# +# The default value is 'versioned' on Windows, and +# 'system' on Unix. +# +# --buildid=ID Add the specified ID to the name of built libraries. +# The default is to not add anything. +# +# --python-buildid=ID Add the specified ID to the name of built libraries +# that depend on Python. The default is to not add +# anything. This ID is added in addition to --buildid. +# +# --help This message. +# +# --with- Build and install the specified . If this +# option is used, only libraries specified using this +# option will be built. +# +# --without- Do not build, stage, or install the specified +# . By default, all libraries are built. +# +# Properties: +# +# toolset=toolset Indicate the toolset to build with. +# +# variant=debug|release Select the build variant +# +# link=static|shared Whether to build static or shared libraries +# +# threading=single|multi Whether to build single or multithreaded binaries +# +# runtime-link=static|shared +# Whether to link to static or shared C and C++ +# runtime. +# + +# TODO: +# - handle boost version +# - handle python options such as pydebug + +import boostcpp ; +import package ; + +import sequence ; +import xsltproc ; +import set ; +import path ; +import link ; +import notfile ; +import virtual-target ; +import "class" : new ; +import property-set ; +import threadapi-feature ; +import option ; + +path-constant BOOST_ROOT : . ; +constant BOOST_VERSION : 1.67.0 ; +constant BOOST_JAMROOT_MODULE : $(__name__) ; + +boostcpp.set-version $(BOOST_VERSION) ; + +use-project /boost/architecture : libs/config/checks/architecture ; + +local all-headers = + [ MATCH .*libs/(.*)/include/boost : [ glob libs/*/include/boost libs/*/*/include/boost ] ] ; + +for dir in $(all-headers) +{ + link-directory $(dir)-headers : libs/$(dir)/include/boost : . ; + explicit $(dir)-headers ; +} + +if $(all-headers) +{ + constant BOOST_MODULARLAYOUT : $(all-headers) ; +} + +project boost + : requirements . + + [ boostcpp.architecture ] + [ boostcpp.address-model ] + + # Disable auto-linking for all targets here, primarily because it caused + # troubles with V2. + BOOST_ALL_NO_LIB=1 + # Used to encode variant in target name. See the 'tag' rule below. + @$(__name__).tag + @handle-static-runtime + # Comeau does not support shared lib + como:static + como-linux:_GNU_SOURCE=1 + # When building docs within Boost, we want the standard Boost style + boost.defaults=Boost + @threadapi-feature.detect + : usage-requirements . + : build-dir bin.v2 + ; + +# This rule is called by Boost.Build to determine the name of target. We use it +# to encode the build variant, compiler name and boost version in the target +# name. +# +rule tag ( name : type ? : property-set ) +{ + return [ boostcpp.tag $(name) : $(type) : $(property-set) ] ; +} + +rule python-tag ( name : type ? : property-set ) +{ + return [ boostcpp.python-tag $(name) : $(type) : $(property-set) ] ; +} + +rule handle-static-runtime ( properties * ) +{ + # Using static runtime with shared libraries is impossible on Linux, and + # dangerous on Windows. Therefore, we disallow it. This might be drastic, + # but it was disabled for a while without anybody complaining. + + # For CW, static runtime is needed so that std::locale works. + if shared in $(properties) && static in $(properties) && + ! ( cw in $(properties) ) + { + if ! $(.shared-static-warning-emitted) + { + ECHO "warning: skipping configuration link=shared, runtime-link=static" ; + ECHO "warning: this combination is either impossible or too dangerous" ; + ECHO "warning: to be of any use" ; + .shared-static-warning-emitted = 1 ; + } + + return no ; + } +} + +all-libraries = [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ] + [ glob libs/*/build/Jamfile ] ] ; + +all-libraries = [ sequence.unique $(all-libraries) ] ; +# The function_types library has a Jamfile, but it's used for maintenance +# purposes, there's no library to build and install. +all-libraries = [ set.difference $(all-libraries) : function_types ] ; + +# Setup convenient aliases for all libraries. + +local rule explicit-alias ( id : targets + ) +{ + alias $(id) : $(targets) ; + explicit $(id) ; +} + +# First, the complicated libraries: where the target name in Jamfile is +# different from its directory name. +explicit-alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ; +explicit-alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ; +explicit-alias unit_test_framework : libs/test/build//boost_unit_test_framework ; +explicit-alias bgl-vis : libs/graps/build//bgl-vis ; +explicit-alias serialization : libs/serialization/build//boost_serialization ; +explicit-alias wserialization : libs/serialization/build//boost_wserialization ; +for local l in $(all-libraries) +{ + if ! $(l) in test graph serialization + { + explicit-alias $(l) : libs/$(l)/build//boost_$(l) ; + } +} + +# Log has an additional target +explicit-alias log_setup : libs/log/build//boost_log_setup ; + +rule do-nothing { } + +rule generate-alias ( project name : property-set : sources * ) +{ + local action-name = [ $(property-set).get ] ; + local m = [ MATCH ^@(.*) : $(action-name) ] ; + property-set = [ property-set.empty ] ; + local action = [ new action $(sources) : $(m[1]) : $(property-set) ] ; + local t = [ new notfile-target $(name) : $(project) : $(action) ] ; + return [ virtual-target.register $(t) ] ; +} + +generate headers : $(all-headers)-headers : @generate-alias @do-nothing : : . ; + +#alias headers : $(all-headers)-headers : : : . ; +explicit headers ; + +# Make project ids of all libraries known. +for local l in $(all-libraries) +{ + use-project /boost/$(l) : libs/$(l)/build ; +} + +if [ path.exists $(BOOST_ROOT)/tools/inspect/build ] +{ + use-project /boost/tools/inspect : tools/inspect/build ; +} + +if [ path.exists $(BOOST_ROOT)/libs/wave/tool/build ] +{ + use-project /boost/libs/wave/tool : libs/wave/tool/build ; +} + +# This rule should be called from libraries' Jamfiles and will create two +# targets, "install" and "stage", that will install or stage that library. The +# --prefix option is respected, but --with and --without options, naturally, are +# ignored. +# +# - libraries -- list of library targets to install. +# +rule boost-install ( libraries * ) +{ + package.install install + : /boost//install-proper-headers $(install-requirements) + : # No binaries + : $(libraries) + : # No headers, it is handled by the dependency. + ; + + local stage-locate = [ option.get stagedir : $(BOOST_ROOT)/stage ] ; + + install stage : $(libraries) : $(stage-locate)/lib ; + + module [ CALLER_MODULE ] + { + explicit stage ; + explicit install ; + } +} + +# Creates a library target, adding autolink support and also creates +# stage and install targets via boost-install, above. +rule boost-lib ( name : sources * : requirements * : default-build * : usage-requirements * ) +{ + name = boost_$(name) ; + autolink = shared:$(name:U)_DYN_LINK=1 ; + lib $(name) + : $(sources) + : $(requirements) $(autolink) + : $(default-build) + : $(usage-requirements) $(autolink) + ; + boost-install $(name) ; +} + + +headers = + # The .SUNWCCh files are present in tr1 include directory and have to be + # installed (see http://lists.boost.org/Archives/boost/2007/05/121430.php). + [ path.glob-tree $(BOOST_ROOT)/boost : *.hpp *.ipp *.h *.inc *.SUNWCCh : CVS .svn ] + [ path.glob-tree $(BOOST_ROOT)/boost/compatibility/cpp_c_headers : c* : CVS .svn ] + [ path.glob $(BOOST_ROOT)/boost/tr1/tr1 : * : bcc32 sun CVS .svn ] + ; + +# Declare special top-level targets that build and install the desired variants +# of the libraries. +boostcpp.declare-targets $(all-libraries) : $(headers) : $(all-headers) ; diff --git a/LICENSE_1_0.txt b/LICENSE_1_0.txt new file mode 100644 index 00000000..36b7cd93 --- /dev/null +++ b/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..7a2f1499 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +Boost libraries - trimmed down for Vita3K +======================================== + +This is a subset of Boost v1.67.0 generated using the bcp tool. To get a list of boost modules guaranteed to exist, check the build script. +Adapted from [citra-emu/ext-boost](https://github.com/citra-emu/ext-boost). + +Updating this repo (on Windows) +=============================== + +To update the Boost version (or to add a new library) follow these steps: + + - Download Boost and extract the package, then launch Powershell and `cd` to the `boost_1_xx_0` directory. + - Build the `bcp` tool: + ``` + .\boostrap.bat + .\b2 tools\bcp + ``` + + - Store the boost directory in a variable for later use: `$boost_dir = $pwd`. + - `cd` to this repo's directory (`...\externals\boost\`) + - Remove the existing boost from the repo: `rm -r boost` (This is only necessary if doing a Boost version upgrade, in case they removed any files in the new version.) + - Run `.\build.cmd $boost_dir` to build a new trimmed down distro. + - Copy the `tools/build/` directory from the untouched `boost_1_xx_0` zip to `./tools/build`. Alternatively we could include it with `bcp`'s files, but it would also include a bunch of build files (since we've built Boost build tools) that unecessarily increase the size. + - Add/remove all files in git and commit. \ No newline at end of file diff --git a/b2.exe b/b2.exe new file mode 100644 index 0000000000000000000000000000000000000000..37a246aa387dec3fd2553b0472682111eaa2c83c GIT binary patch literal 387072 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

SqwV}$F3U1n`2!5 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%0Df8Lf??*y=Q$pCz8QXsAEWDhqvag4 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 +#include + +namespace boost { namespace algorithm { + +/// \fn all_of ( InputIterator first, InputIterator last, Predicate p ) +/// \return true if all elements in [first, last) satisfy the predicate 'p' +/// \note returns true on an empty range +/// +/// \param first The start of the input sequence +/// \param last One past the end of the input sequence +/// \param p A predicate for testing the elements of the sequence +/// +/// \note This function is part of the C++2011 standard library. +template +bool all_of ( InputIterator first, InputIterator last, Predicate p ) +{ + for ( ; first != last; ++first ) + if ( !p(*first)) + return false; + return true; +} + +/// \fn all_of ( const Range &r, Predicate p ) +/// \return true if all elements in the range satisfy the predicate 'p' +/// \note returns true on an empty range +/// +/// \param r The input range +/// \param p A predicate for testing the elements of the range +/// +template +bool all_of ( const Range &r, Predicate p ) +{ + return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p ); +} + +/// \fn all_of_equal ( InputIterator first, InputIterator last, const T &val ) +/// \return true if all elements in [first, last) are equal to 'val' +/// \note returns true on an empty range +/// +/// \param first The start of the input sequence +/// \param last One past the end of the input sequence +/// \param val A value to compare against +/// +template +bool all_of_equal ( InputIterator first, InputIterator last, const T &val ) +{ + for ( ; first != last; ++first ) + if ( val != *first ) + return false; + return true; +} + +/// \fn all_of_equal ( const Range &r, const T &val ) +/// \return true if all elements in the range are equal to 'val' +/// \note returns true on an empty range +/// +/// \param r The input range +/// \param val A value to compare against +/// +template +bool all_of_equal ( const Range &r, const T &val ) +{ + return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val ); +} + +}} // namespace boost and algorithm + +#endif // BOOST_ALGORITHM_ALL_OF_HPP diff --git a/boost/algorithm/string/classification.hpp b/boost/algorithm/string/classification.hpp new file mode 100644 index 00000000..ca43602d --- /dev/null +++ b/boost/algorithm/string/classification.hpp @@ -0,0 +1,312 @@ +// Boost string_algo library classification.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_CLASSIFICATION_HPP +#define BOOST_STRING_CLASSIFICATION_HPP + +#include +#include +#include +#include +#include +#include + + +/*! \file + Classification predicates are included in the library to give + some more convenience when using algorithms like \c trim() and \c all(). + They wrap functionality of STL classification functions ( e.g. \c std::isspace() ) + into generic functors. +*/ + +namespace boost { + namespace algorithm { + +// classification functor generator -------------------------------------// + + //! is_classified predicate + /*! + Construct the \c is_classified predicate. This predicate holds if the input is + of specified \c std::ctype category. + + \param Type A \c std::ctype category + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(Type, Loc); + } + + //! is_space predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::space category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_space(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::space, Loc); + } + + //! is_alnum predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alnum category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alnum(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alnum, Loc); + } + + //! is_alpha predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alpha category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alpha(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alpha, Loc); + } + + //! is_cntrl predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::cntrl category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_cntrl(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::cntrl, Loc); + } + + //! is_digit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::digit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_digit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::digit, Loc); + } + + //! is_graph predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::graph category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_graph(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::graph, Loc); + } + + //! is_lower predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::lower category. + + \param Loc A locale used for classification + \return An instance of \c is_classified predicate + */ + inline detail::is_classifiedF + is_lower(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::lower, Loc); + } + + //! is_print predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::print category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_print(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::print, Loc); + } + + //! is_punct predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::punct category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_punct(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::punct, Loc); + } + + //! is_upper predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::upper category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_upper(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::upper, Loc); + } + + //! is_xdigit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::xdigit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_xdigit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::xdigit, Loc); + } + + //! is_any_of predicate + /*! + Construct the \c is_any_of predicate. The predicate holds if the input + is included in the specified set of characters. + + \param Set A set of characters to be recognized + \return An instance of the \c is_any_of predicate + */ + template + inline detail::is_any_ofF< + BOOST_STRING_TYPENAME range_value::type> + is_any_of( const RangeT& Set ) + { + iterator_range::type> lit_set(boost::as_literal(Set)); + return detail::is_any_ofF::type>(lit_set); + } + + //! is_from_range predicate + /*! + Construct the \c is_from_range predicate. The predicate holds if the input + is included in the specified range. (i.e. From <= Ch <= To ) + + \param From The start of the range + \param To The end of the range + \return An instance of the \c is_from_range predicate + */ + template + inline detail::is_from_rangeF is_from_range(CharT From, CharT To) + { + return detail::is_from_rangeF(From,To); + } + + // predicate combinators ---------------------------------------------------// + + //! predicate 'and' composition predicate + /*! + Construct the \c class_and predicate. This predicate can be used + to logically combine two classification predicates. \c class_and holds, + if both predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_and predicate + */ + template + inline detail::pred_andF + operator&&( + const predicate_facade& Pred1, + const predicate_facade& Pred2 ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_andF( + *static_cast(&Pred1), + *static_cast(&Pred2) ); + } + + //! predicate 'or' composition predicate + /*! + Construct the \c class_or predicate. This predicate can be used + to logically combine two classification predicates. \c class_or holds, + if one of the predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_or predicate + */ + template + inline detail::pred_orF + operator||( + const predicate_facade& Pred1, + const predicate_facade& Pred2 ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_orF( + *static_cast(&Pred1), + *static_cast(&Pred2)); + } + + //! predicate negation operator + /*! + Construct the \c class_not predicate. This predicate represents a negation. + \c class_or holds if of the predicates return false. + + \param Pred The predicate to be negated + \return An instance of the \c class_not predicate + */ + template + inline detail::pred_notF + operator!( const predicate_facade& Pred ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_notF(*static_cast(&Pred)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_classified; + using algorithm::is_space; + using algorithm::is_alnum; + using algorithm::is_alpha; + using algorithm::is_cntrl; + using algorithm::is_digit; + using algorithm::is_graph; + using algorithm::is_lower; + using algorithm::is_upper; + using algorithm::is_print; + using algorithm::is_punct; + using algorithm::is_xdigit; + using algorithm::is_any_of; + using algorithm::is_from_range; + +} // namespace boost + +#endif // BOOST_STRING_PREDICATE_HPP diff --git a/boost/algorithm/string/compare.hpp b/boost/algorithm/string/compare.hpp new file mode 100644 index 00000000..734303a9 --- /dev/null +++ b/boost/algorithm/string/compare.hpp @@ -0,0 +1,199 @@ +// Boost string_algo library compare.hpp header file -------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// 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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_COMPARE_HPP +#define BOOST_STRING_COMPARE_HPP + +#include +#include + +/*! \file + Defines element comparison predicates. Many algorithms in this library can + take an additional argument with a predicate used to compare elements. + This makes it possible, for instance, to have case insensitive versions + of the algorithms. +*/ + +namespace boost { + namespace algorithm { + + // is_equal functor -----------------------------------------------// + + //! is_equal functor + /*! + Standard STL equal_to only handle comparison between arguments + of the same type. This is a less restrictive version which wraps operator ==. + */ + struct is_equal + { + //! Function operator + /*! + Compare two operands for equality + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1==Arg2; + } + }; + + //! case insensitive version of is_equal + /*! + Case insensitive comparison predicate. Comparison is done using + specified locales. + */ + struct is_iequal + { + //! Constructor + /*! + \param Loc locales used for comparison + */ + is_iequal( const std::locale& Loc=std::locale() ) : + m_Loc( Loc ) {} + + //! Function operator + /*! + Compare two operands. Case is ignored. + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)==std::toupper(Arg2); + #else + return std::toupper(Arg1,m_Loc)==std::toupper(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + // is_less functor -----------------------------------------------// + + //! is_less functor + /*! + Convenient version of standard std::less. Operation is templated, therefore it is + not required to specify the exact types upon the construction + */ + struct is_less + { + //! Functor operation + /*! + Compare two operands using > operator + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1 + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)(Arg1,m_Loc)(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + // is_not_greater functor -----------------------------------------------// + + //! is_not_greater functor + /*! + Convenient version of standard std::not_greater_to. Operation is templated, therefore it is + not required to specify the exact types upon the construction + */ + struct is_not_greater + { + //! Functor operation + /*! + Compare two operands using > operator + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1<=Arg2; + } + }; + + + //! case insensitive version of is_not_greater + /*! + Case insensitive comparison predicate. Comparison is done using + specified locales. + */ + struct is_not_igreater + { + //! Constructor + /*! + \param Loc locales used for comparison + */ + is_not_igreater( const std::locale& Loc=std::locale() ) : + m_Loc( Loc ) {} + + //! Function operator + /*! + Compare two operands. Case is ignored. + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)<=std::toupper(Arg2); + #else + return std::toupper(Arg1,m_Loc)<=std::toupper(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_equal; + using algorithm::is_iequal; + using algorithm::is_less; + using algorithm::is_iless; + using algorithm::is_not_greater; + using algorithm::is_not_igreater; + +} // namespace boost + + +#endif // BOOST_STRING_COMPARE_HPP diff --git a/boost/algorithm/string/concept.hpp b/boost/algorithm/string/concept.hpp new file mode 100644 index 00000000..17e83495 --- /dev/null +++ b/boost/algorithm/string/concept.hpp @@ -0,0 +1,83 @@ +// Boost string_algo library concept.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONCEPT_HPP +#define BOOST_STRING_CONCEPT_HPP + +#include +#include +#include +#include + +/*! \file + Defines concepts used in string_algo library +*/ + +namespace boost { + namespace algorithm { + + //! Finder concept + /*! + Defines the Finder concept. Finder is a functor which selects + an arbitrary part of a string. Search is performed on + the range specified by starting and ending iterators. + + Result of the find operation must be convertible to iterator_range. + */ + template + struct FinderConcept + { + private: + typedef iterator_range range; + public: + void constraints() + { + // Operation + r=(*pF)(i,i); + } + private: + range r; + IteratorT i; + FinderT* pF; + }; // Finder_concept + + + //! Formatter concept + /*! + Defines the Formatter concept. Formatter is a functor, which + takes a result from a finder operation and transforms it + in a specific way. + + Result must be a container supported by container_traits, + or a reference to it. + */ + template + struct FormatterConcept + { + public: + void constraints() + { + // Operation + ::boost::begin((*pFo)( (*pF)(i,i) )); + ::boost::end((*pFo)( (*pF)(i,i) )); + } + private: + IteratorT i; + FinderT* pF; + FormatterT *pFo; + }; // FormatterConcept; + + } // namespace algorithm +} // namespace boost + + + + +#endif // BOOST_STRING_CONCEPT_HPP diff --git a/boost/algorithm/string/config.hpp b/boost/algorithm/string/config.hpp new file mode 100644 index 00000000..559750ac --- /dev/null +++ b/boost/algorithm/string/config.hpp @@ -0,0 +1,28 @@ +// Boost string_algo library config.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONFIG_HPP +#define BOOST_STRING_CONFIG_HPP + +#include +#include + +#ifdef BOOST_STRING_DEDUCED_TYPENAME +# error "macro already defined!" +#endif + +#define BOOST_STRING_TYPENAME BOOST_DEDUCED_TYPENAME + +// Metrowerks workaround +#if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x +#pragma parse_func_templ off +#endif + +#endif // BOOST_STRING_CONFIG_HPP diff --git a/boost/algorithm/string/constants.hpp b/boost/algorithm/string/constants.hpp new file mode 100644 index 00000000..6ed70eff --- /dev/null +++ b/boost/algorithm/string/constants.hpp @@ -0,0 +1,36 @@ +// Boost string_algo library constants.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONSTANTS_HPP +#define BOOST_STRING_CONSTANTS_HPP + +namespace boost { + namespace algorithm { + + //! Token compression mode + /*! + Specifies token compression mode for the token_finder. + */ + enum token_compress_mode_type + { + token_compress_on, //!< Compress adjacent tokens + token_compress_off //!< Do not compress adjacent tokens + }; + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::token_compress_on; + using algorithm::token_compress_off; + +} // namespace boost + +#endif // BOOST_STRING_CONSTANTS_HPP + diff --git a/boost/algorithm/string/detail/classification.hpp b/boost/algorithm/string/detail/classification.hpp new file mode 100644 index 00000000..704d9d20 --- /dev/null +++ b/boost/algorithm/string/detail/classification.hpp @@ -0,0 +1,353 @@ +// Boost string_algo library classification.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP +#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP + +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// classification functors -----------------------------------------------// + + // is_classified functor + struct is_classifiedF : + public predicate_facade + { + // Boost.ResultOf support + typedef bool result_type; + + // Constructor from a locale + is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : + m_Type(Type), m_Locale(Loc) {} + // Operation + template + bool operator()( CharT Ch ) const + { + return std::use_facet< std::ctype >(m_Locale).is( m_Type, Ch ); + } + + #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL) + template<> + bool operator()( char const Ch ) const + { + return std::use_facet< std::ctype >(m_Locale).is( m_Type, Ch ); + } + #endif + + private: + std::ctype_base::mask m_Type; + std::locale m_Locale; + }; + + + // is_any_of functor + /* + returns true if the value is from the specified set + */ + template + struct is_any_ofF : + public predicate_facade > + { + private: + // set cannot operate on const value-type + typedef typename ::boost::remove_const::type set_value_type; + + public: + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + template + is_any_ofF( const RangeT& Range ) : m_Size(0) + { + // Prepare storage + m_Storage.m_dynSet=0; + + std::size_t Size=::boost::distance(Range); + m_Size=Size; + set_value_type* Storage=0; + + if(use_fixed_storage(m_Size)) + { + // Use fixed storage + Storage=&m_Storage.m_fixSet[0]; + } + else + { + // Use dynamic storage + m_Storage.m_dynSet=new set_value_type[m_Size]; + Storage=m_Storage.m_dynSet; + } + + // Use fixed storage + ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage); + ::std::sort(Storage, Storage+m_Size); + } + + // Copy constructor + is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size) + { + // Prepare storage + m_Storage.m_dynSet=0; + const set_value_type* SrcStorage=0; + set_value_type* DestStorage=0; + + if(use_fixed_storage(m_Size)) + { + // Use fixed storage + DestStorage=&m_Storage.m_fixSet[0]; + SrcStorage=&Other.m_Storage.m_fixSet[0]; + } + else + { + // Use dynamic storage + m_Storage.m_dynSet=new set_value_type[m_Size]; + DestStorage=m_Storage.m_dynSet; + SrcStorage=Other.m_Storage.m_dynSet; + } + + // Use fixed storage + ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); + } + + // Destructor + ~is_any_ofF() + { + if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) + { + delete [] m_Storage.m_dynSet; + } + } + + // Assignment + is_any_ofF& operator=(const is_any_ofF& Other) + { + // Handle self assignment + if(this==&Other) return *this; + + // Prepare storage + const set_value_type* SrcStorage; + set_value_type* DestStorage; + + if(use_fixed_storage(Other.m_Size)) + { + // Use fixed storage + DestStorage=&m_Storage.m_fixSet[0]; + SrcStorage=&Other.m_Storage.m_fixSet[0]; + + // Delete old storage if was present + if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) + { + delete [] m_Storage.m_dynSet; + } + + // Set new size + m_Size=Other.m_Size; + } + else + { + // Other uses dynamic storage + SrcStorage=Other.m_Storage.m_dynSet; + + // Check what kind of storage are we using right now + if(use_fixed_storage(m_Size)) + { + // Using fixed storage, allocate new + set_value_type* pTemp=new set_value_type[Other.m_Size]; + DestStorage=pTemp; + m_Storage.m_dynSet=pTemp; + m_Size=Other.m_Size; + } + else + { + // Using dynamic storage, check if can reuse + if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size + bool operator()( Char2T Ch ) const + { + const set_value_type* Storage= + (use_fixed_storage(m_Size)) + ? &m_Storage.m_fixSet[0] + : m_Storage.m_dynSet; + + return ::std::binary_search(Storage, Storage+m_Size, Ch); + } + private: + // check if the size is eligible for fixed storage + static bool use_fixed_storage(std::size_t size) + { + return size<=sizeof(set_value_type*)*2; + } + + + private: + // storage + // The actual used storage is selected on the type + union + { + set_value_type* m_dynSet; + set_value_type m_fixSet[sizeof(set_value_type*)*2]; + } + m_Storage; + + // storage size + ::std::size_t m_Size; + }; + + // is_from_range functor + /* + returns true if the value is from the specified range. + (i.e. x>=From && x>=To) + */ + template + struct is_from_rangeF : + public predicate_facade< is_from_rangeF > + { + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {} + + // Operation + template + bool operator()( Char2T Ch ) const + { + return ( m_From <= Ch ) && ( Ch <= m_To ); + } + + private: + CharT m_From; + CharT m_To; + }; + + // class_and composition predicate + template + struct pred_andF : + public predicate_facade< pred_andF > + { + public: + + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + pred_andF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) && m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_or composition predicate + template + struct pred_orF : + public predicate_facade< pred_orF > + { + public: + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + pred_orF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) || m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_not composition predicate + template< typename PredT > + struct pred_notF : + public predicate_facade< pred_notF > + { + public: + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + pred_notF( PredT Pred ) : m_Pred(Pred) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return !m_Pred(Ch); + } + + private: + PredT m_Pred; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP diff --git a/boost/algorithm/string/detail/find_iterator.hpp b/boost/algorithm/string/detail/find_iterator.hpp new file mode 100644 index 00000000..4f90a98f --- /dev/null +++ b/boost/algorithm/string/detail/find_iterator.hpp @@ -0,0 +1,87 @@ +// Boost string_algo library find_iterator.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP +#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_iterator base -----------------------------------------------// + + // Find iterator base + template + class find_iterator_base + { + protected: + // typedefs + typedef IteratorT input_iterator_type; + typedef iterator_range match_type; + typedef function2< + match_type, + input_iterator_type, + input_iterator_type> finder_type; + + protected: + // Protected construction/destruction + + // Default constructor + find_iterator_base() {} + // Copy construction + find_iterator_base( const find_iterator_base& Other ) : + m_Finder(Other.m_Finder) {} + + // Constructor + template + find_iterator_base( FinderT Finder, int ) : + m_Finder(Finder) {} + + // Destructor + ~find_iterator_base() {} + + // Find operation + match_type do_find( + input_iterator_type Begin, + input_iterator_type End ) const + { + if (!m_Finder.empty()) + { + return m_Finder(Begin,End); + } + else + { + return match_type(End,End); + } + } + + // Check + bool is_null() const + { + return m_Finder.empty(); + } + + private: + // Finder + finder_type m_Finder; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_DETAIL_HPP diff --git a/boost/algorithm/string/detail/finder.hpp b/boost/algorithm/string/detail/finder.hpp new file mode 100644 index 00000000..a2a95821 --- /dev/null +++ b/boost/algorithm/string/detail/finder.hpp @@ -0,0 +1,639 @@ +// Boost string_algo library finder.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// 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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_FINDER_DETAIL_HPP +#define BOOST_STRING_FINDER_DETAIL_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + + +// find first functor -----------------------------------------------// + + // find a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, functor returns + */ + template + struct first_finderF + { + typedef SearchIteratorT search_iterator_type; + + // Construction + template< typename SearchT > + first_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {} + first_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=Begin; + OuterIt!=End; + ++OuterIt) + { + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + input_iterator_type InnerIt=OuterIt; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if ( SubstrIt==m_Search.end() ) + return result_type( OuterIt, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find last functor -----------------------------------------------// + + // find the last match a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct last_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + + // Construction + template< typename SearchT > + last_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {} + last_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + if( boost::empty(m_Search) ) + return result_type( End, End ); + + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return findit( Begin, End, category() ); + } + + private: + // forward iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::forward_iterator_tag ) const + { + typedef iterator_range result_type; + + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M=first_finder( Begin, End ); + result_type Last=M; + + while( M ) + { + Last=M; + M=first_finder( ::boost::end(M), End ); + } + + return Last; + } + + // bidirectional iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::bidirectional_iterator_tag ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=End; + OuterIt!=Begin; ) + { + input_iterator_type OuterIt2=--OuterIt; + + input_iterator_type InnerIt=OuterIt2; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if( SubstrIt==m_Search.end() ) + return result_type( OuterIt2, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find n-th functor -----------------------------------------------// + + // find the n-th match of a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct nth_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + typedef last_finderF< + search_iterator_type, + PredicateT> last_finder_type; + + // Construction + template< typename SearchT > + nth_finderF( + const SearchT& Search, + int Nth, + PredicateT Comp) : + m_Search(::boost::begin(Search), ::boost::end(Search)), + m_Nth(Nth), + m_Comp(Comp) {} + nth_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + int Nth, + PredicateT Comp) : + m_Search(SearchBegin, SearchEnd), + m_Nth(Nth), + m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_Nth>=0) + { + return find_forward(Begin, End, m_Nth); + } + else + { + return find_backward(Begin, End, -m_Nth); + } + + } + + private: + // Implementation helpers + template< typename ForwardIteratorT > + iterator_range + find_forward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const + { + typedef iterator_range result_type; + + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + // Instantiate find functor + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M( Begin, Begin ); + + for( unsigned int n=0; n<=N; ++n ) + { + // find next match + M=first_finder( ::boost::end(M), End ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + template< typename ForwardIteratorT > + iterator_range + find_backward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const + { + typedef iterator_range result_type; + + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + // Instantiate find functor + last_finder_type last_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M( End, End ); + + for( unsigned int n=1; n<=N; ++n ) + { + // find next match + M=last_finder( Begin, ::boost::begin(M) ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + + private: + iterator_range m_Search; + int m_Nth; + PredicateT m_Comp; + }; + +// find head/tail implementation helpers ---------------------------// + + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=Begin; + for( + unsigned int Index=0; + Index + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type(Begin,Begin+N); + } + + // Find head implementation + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() ); + } + + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + unsigned int Index=0; + input_iterator_type It=Begin; + input_iterator_type It2=Begin; + + // Advance It2 by N increments + for( Index=0; Index + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::bidirectional_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=End; + for( + unsigned int Index=0; + Index + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type( End-N, End ); + } + + // Operation + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() ); + } + + + +// find head functor -----------------------------------------------// + + + // find a head in the sequence ( functor ) + /* + This functor find a head of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct head_finderF + { + // Construction + head_finderF( int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_N>=0) + { + return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + ::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N ); + + return ::boost::make_iterator_range(Begin, Res.begin()); + } + } + + private: + int m_N; + }; + +// find tail functor -----------------------------------------------// + + + // find a tail in the sequence ( functor ) + /* + This functor find a tail of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct tail_finderF + { + // Construction + tail_finderF( int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_N>=0) + { + return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + ::boost::algorithm::detail::find_head_impl( Begin, End, -m_N ); + + return ::boost::make_iterator_range(Res.end(), End); + } + } + + private: + int m_N; + }; + +// find token functor -----------------------------------------------// + + // find a token in a sequence ( functor ) + /* + This find functor finds a token specified be a predicate + in a sequence. It is equivalent of std::find algorithm, + with an exception that it return range instead of a single + iterator. + + If bCompress is set to true, adjacent matching tokens are + concatenated into one match. + */ + template< typename PredicateT > + struct token_finderF + { + // Construction + token_finderF( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) : + m_Pred(Pred), m_eCompress(eCompress) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + ForwardIteratorT It=std::find_if( Begin, End, m_Pred ); + + if( It==End ) + { + return result_type( End, End ); + } + else + { + ForwardIteratorT It2=It; + + if( m_eCompress==token_compress_on ) + { + // Find first non-matching character + while( It2!=End && m_Pred(*It2) ) ++It2; + } + else + { + // Advance by one position + ++It2; + } + + return result_type( It, It2 ); + } + } + + private: + PredicateT m_Pred; + token_compress_mode_type m_eCompress; + }; + +// find range functor -----------------------------------------------// + + // find a range in the sequence ( functor ) + /* + This functor actually does not perform any find operation. + It always returns given iterator range as a result. + */ + template + struct range_finderF + { + typedef ForwardIterator1T input_iterator_type; + typedef iterator_range result_type; + + // Construction + range_finderF( + input_iterator_type Begin, + input_iterator_type End ) : m_Range(Begin, End) {} + + range_finderF(const iterator_range& Range) : + m_Range(Range) {} + + // Operation + template< typename ForwardIterator2T > + iterator_range + operator()( + ForwardIterator2T, + ForwardIterator2T ) const + { +#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 ) + return iterator_range(this->m_Range); +#else + return m_Range; +#endif + } + + private: + iterator_range m_Range; + }; + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FINDER_DETAIL_HPP diff --git a/boost/algorithm/string/detail/trim.hpp b/boost/algorithm/string/detail/trim.hpp new file mode 100644 index 00000000..1233e49d --- /dev/null +++ b/boost/algorithm/string/detail/trim.hpp @@ -0,0 +1,95 @@ +// Boost string_algo library trim.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_TRIM_DETAIL_HPP +#define BOOST_STRING_TRIM_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// trim iterator helper -----------------------------------------------// + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::forward_iterator_tag ) + { + ForwardIteratorT TrimIt=InBegin; + + for( ForwardIteratorT It=InBegin; It!=InEnd; ++It ) + { + if ( !IsSpace(*It) ) + { + TrimIt=It; + ++TrimIt; + } + } + + return TrimIt; + } + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::bidirectional_iterator_tag ) + { + for( ForwardIteratorT It=InEnd; It!=InBegin; ) + { + if ( !IsSpace(*(--It)) ) + return ++It; + } + + return InBegin; + } + // Search for first non matching character from the beginning of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_begin( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + ForwardIteratorT It=InBegin; + for(; It!=InEnd; ++It ) + { + if (!IsSpace(*It)) + return It; + } + + return It; + } + + // Search for first non matching character from the end of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return ::boost::algorithm::detail::trim_end_iter_select( InBegin, InEnd, IsSpace, category() ); + } + + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_TRIM_DETAIL_HPP diff --git a/boost/algorithm/string/detail/util.hpp b/boost/algorithm/string/detail/util.hpp new file mode 100644 index 00000000..7844b672 --- /dev/null +++ b/boost/algorithm/string/detail/util.hpp @@ -0,0 +1,107 @@ +// Boost string_algo library util.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_UTIL_DETAIL_HPP +#define BOOST_STRING_UTIL_DETAIL_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// empty container -----------------------------------------------// + + // empty_container + /* + This class represents always empty container, + containing elements of type CharT. + + It is supposed to be used in a const version only + */ + template< typename CharT > + struct empty_container + { + typedef empty_container type; + typedef CharT value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type& reference; + typedef const value_type& const_reference; + typedef const value_type* iterator; + typedef const value_type* const_iterator; + + + // Operations + const_iterator begin() const + { + return reinterpret_cast(0); + } + + const_iterator end() const + { + return reinterpret_cast(0); + } + + bool empty() const + { + return false; + } + + size_type size() const + { + return 0; + } + }; + +// bounded copy algorithm -----------------------------------------------// + + // Bounded version of the std::copy algorithm + template + inline OutputIteratorT bounded_copy( + InputIteratorT First, + InputIteratorT Last, + OutputIteratorT DestFirst, + OutputIteratorT DestLast ) + { + InputIteratorT InputIt=First; + OutputIteratorT OutputIt=DestFirst; + for(; InputIt!=Last && OutputIt!=DestLast; InputIt++, OutputIt++ ) + { + *OutputIt=*InputIt; + } + + return OutputIt; + } + +// iterator range utilities -----------------------------------------// + + // copy range functor + template< + typename SeqT, + typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator > + struct copy_iterator_rangeF + { + typedef iterator_range argument_type; + typedef SeqT result_type; + SeqT operator()( const iterator_range& Range ) const + { + return copy_range(Range); + } + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_UTIL_DETAIL_HPP diff --git a/boost/algorithm/string/find_iterator.hpp b/boost/algorithm/string/find_iterator.hpp new file mode 100644 index 00000000..5a52d92e --- /dev/null +++ b/boost/algorithm/string/find_iterator.hpp @@ -0,0 +1,388 @@ +// Boost string_algo library find_iterator.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_ITERATOR_HPP +#define BOOST_STRING_FIND_ITERATOR_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/*! \file + Defines find iterator classes. Find iterator repeatedly applies a Finder + to the specified input string to search for matches. Dereferencing + the iterator yields the current match or a range between the last and the current + match depending on the iterator used. +*/ + +namespace boost { + namespace algorithm { + +// find_iterator -----------------------------------------------// + + //! find_iterator + /*! + Find iterator encapsulates a Finder and allows + for incremental searching in a string. + Each increment moves the iterator to the next match. + + Find iterator is a readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class find_iterator : + public iterator_facade< + find_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class ::boost::iterator_core_access; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + find_iterator() {} + + //! Copy constructor + /*! + Construct a copy of the find_iterator + */ + find_iterator( const find_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_End(Other.m_End) {} + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + find_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_End(End) + { + increment(); + } + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + find_iterator( + RangeT& Col, + FinderT Finder ) : + detail::find_iterator_base(Finder,0) + { + iterator_range::type> lit_col(::boost::as_literal(Col)); + m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); + m_End=::boost::end(lit_col); + + increment(); + } + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + m_Match=this->do_find(m_Match.end(),m_End); + } + + // comparison + bool equal( const find_iterator& Other ) const + { + bool bEof=eof(); + bool bOtherEof=Other.eof(); + + return bEof || bOtherEof ? bEof==bOtherEof : + ( + m_Match==Other.m_Match && + m_End==Other.m_End + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return + this->is_null() || + ( + m_Match.begin() == m_End && + m_Match.end() == m_End + ); + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_End; + }; + + //! find iterator construction helper + /*! + * Construct a find iterator to iterate through the specified string + */ + template + inline find_iterator< + BOOST_STRING_TYPENAME range_iterator::type> + make_find_iterator( + RangeT& Collection, + FinderT Finder) + { + return find_iterator::type>( + Collection, Finder); + } + +// split iterator -----------------------------------------------// + + //! split_iterator + /*! + Split iterator encapsulates a Finder and allows + for incremental searching in a string. + Unlike the find iterator, split iterator iterates + through gaps between matches. + + Find iterator is a readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class split_iterator : + public iterator_facade< + split_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class ::boost::iterator_core_access; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + split_iterator() : + m_Next(), + m_End(), + m_bEof(true) + {} + + //! Copy constructor + /*! + Construct a copy of the split_iterator + */ + split_iterator( const split_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_Next(Other.m_Next), + m_End(Other.m_End), + m_bEof(Other.m_bEof) + {} + + //! Constructor + /*! + Construct new split_iterator for a given finder + and a range. + */ + template + split_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_Next(Begin), + m_End(End), + m_bEof(false) + { + // force the correct behavior for empty sequences and yield at least one token + if(Begin!=End) + { + increment(); + } + } + //! Constructor + /*! + Construct new split_iterator for a given finder + and a collection. + */ + template + split_iterator( + RangeT& Col, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_bEof(false) + { + iterator_range::type> lit_col(::boost::as_literal(Col)); + m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); + m_Next=::boost::begin(lit_col); + m_End=::boost::end(lit_col); + + // force the correct behavior for empty sequences and yield at least one token + if(m_Next!=m_End) + { + increment(); + } + } + + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + match_type FindMatch=this->do_find( m_Next, m_End ); + + if(FindMatch.begin()==m_End && FindMatch.end()==m_End) + { + if(m_Match.end()==m_End) + { + // Mark iterator as eof + m_bEof=true; + } + } + + m_Match=match_type( m_Next, FindMatch.begin() ); + m_Next=FindMatch.end(); + } + + // comparison + bool equal( const split_iterator& Other ) const + { + bool bEof=eof(); + bool bOtherEof=Other.eof(); + + return bEof || bOtherEof ? bEof==bOtherEof : + ( + m_Match==Other.m_Match && + m_Next==Other.m_Next && + m_End==Other.m_End + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return this->is_null() || m_bEof; + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_Next; + input_iterator_type m_End; + bool m_bEof; + }; + + //! split iterator construction helper + /*! + * Construct a split iterator to iterate through the specified collection + */ + template + inline split_iterator< + BOOST_STRING_TYPENAME range_iterator::type> + make_split_iterator( + RangeT& Collection, + FinderT Finder) + { + return split_iterator::type>( + Collection, Finder); + } + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_iterator; + using algorithm::make_find_iterator; + using algorithm::split_iterator; + using algorithm::make_split_iterator; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_HPP diff --git a/boost/algorithm/string/finder.hpp b/boost/algorithm/string/finder.hpp new file mode 100644 index 00000000..93f7ec30 --- /dev/null +++ b/boost/algorithm/string/finder.hpp @@ -0,0 +1,270 @@ +// Boost string_algo library finder.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// 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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_FINDER_HPP +#define BOOST_STRING_FINDER_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines Finder generators. Finder object is a functor which is able to + find a substring matching a specific criteria in the input. + Finders are used as a pluggable components for replace, find + and split facilities. This header contains generator functions + for finders provided in this library. +*/ + +namespace boost { + namespace algorithm { + +// Finder generators ------------------------------------------// + + //! "First" finder + /*! + Construct the \c first_finder. The finder searches for the first + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \param Comp An element comparison predicate + \return An instance of the \c first_finder object + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + first_finder( const RangeT& Search ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( ::boost::as_literal(Search), is_equal() ) ; + } + + //! "First" finder + /*! + \overload + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + first_finder( + const RangeT& Search, PredicateT Comp ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( ::boost::as_literal(Search), Comp ); + } + + //! "Last" finder + /*! + Construct the \c last_finder. The finder searches for the last + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \param Comp An element comparison predicate + \return An instance of the \c last_finder object + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + last_finder( const RangeT& Search ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( ::boost::as_literal(Search), is_equal() ); + } + //! "Last" finder + /*! + \overload + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + last_finder( const RangeT& Search, PredicateT Comp ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( ::boost::as_literal(Search), Comp ) ; + } + + //! "Nth" finder + /*! + Construct the \c nth_finder. The finder searches for the n-th (zero-indexed) + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \param Nth An index of the match to be find + \param Comp An element comparison predicate + \return An instance of the \c nth_finder object + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + nth_finder( + const RangeT& Search, + int Nth) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( ::boost::as_literal(Search), Nth, is_equal() ) ; + } + //! "Nth" finder + /*! + \overload + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + nth_finder( + const RangeT& Search, + int Nth, + PredicateT Comp ) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( ::boost::as_literal(Search), Nth, Comp ); + } + + //! "Head" finder + /*! + Construct the \c head_finder. The finder returns a head of a given + input. The head is a prefix of a string up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as an \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c head_finder object + */ + inline detail::head_finderF + head_finder( int N ) + { + return detail::head_finderF(N); + } + + //! "Tail" finder + /*! + Construct the \c tail_finder. The finder returns a tail of a given + input. The tail is a suffix of a string up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as an \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c tail_finder object + */ + inline detail::tail_finderF + tail_finder( int N ) + { + return detail::tail_finderF(N); + } + + //! "Token" finder + /*! + Construct the \c token_finder. The finder searches for a token + specified by a predicate. It is similar to std::find_if + algorithm, with an exception that it return a range of + instead of a single iterator. + + If "compress token mode" is enabled, adjacent matching tokens are + concatenated into one match. Thus the finder can be used to + search for continuous segments of characters satisfying the + given predicate. + + The result is given as an \c iterator_range delimiting the match. + + \param Pred An element selection predicate + \param eCompress Compress flag + \return An instance of the \c token_finder object + */ + template< typename PredicateT > + inline detail::token_finderF + token_finder( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return detail::token_finderF( Pred, eCompress ); + } + + //! "Range" finder + /*! + Construct the \c range_finder. The finder does not perform + any operation. It simply returns the given range for + any input. + + \param Begin Beginning of the range + \param End End of the range + \param Range The range. + \return An instance of the \c range_finger object + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + return detail::range_finderF( Begin, End ); + } + + //! "Range" finder + /*! + \overload + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( iterator_range Range ) + { + return detail::range_finderF( Range ); + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::first_finder; + using algorithm::last_finder; + using algorithm::nth_finder; + using algorithm::head_finder; + using algorithm::tail_finder; + using algorithm::token_finder; + using algorithm::range_finder; + +} // namespace boost + + +#endif // BOOST_STRING_FINDER_HPP diff --git a/boost/algorithm/string/iter_find.hpp b/boost/algorithm/string/iter_find.hpp new file mode 100644 index 00000000..10424abc --- /dev/null +++ b/boost/algorithm/string/iter_find.hpp @@ -0,0 +1,193 @@ +// Boost string_algo library iter_find.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_ITER_FIND_HPP +#define BOOST_STRING_ITER_FIND_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines generic split algorithms. Split algorithms can be + used to divide a sequence into several part according + to a given criteria. Result is given as a 'container + of containers' where elements are copies or references + to extracted parts. + + There are two algorithms provided. One iterates over matching + substrings, the other one over the gaps between these matches. +*/ + +namespace boost { + namespace algorithm { + +// iterate find ---------------------------------------------------// + + //! Iter find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + In each iteration new match is found and added to the result. + + \param Result A 'container container' to contain the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A Finder object used for searching + \return A reference to the result + + \note Prior content of the result will be overwritten. + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename FinderT > + inline SequenceSequenceT& + iter_find( + SequenceSequenceT& Result, + RangeT& Input, + FinderT Finder ) + { + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_iterator::type> + )); + + iterator_range::type> lit_input(::boost::as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef find_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + range_value::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=::boost::end(lit_input); + + typedef transform_iterator + transform_iter_type; + + transform_iter_type itBegin= + ::boost::make_transform_iterator( + find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), + copy_range_type()); + + transform_iter_type itEnd= + ::boost::make_transform_iterator( + find_iterator_type(), + copy_range_type()); + + SequenceSequenceT Tmp(itBegin, itEnd); + + Result.swap(Tmp); + return Result; + } + +// iterate split ---------------------------------------------------// + + //! Split find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + Each match is used as a separator of segments. These segments are then + returned in the result. + + \param Result A 'container container' to contain the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A finder object used for searching + \return A reference to the result + + \note Prior content of the result will be overwritten. + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename FinderT > + inline SequenceSequenceT& + iter_split( + SequenceSequenceT& Result, + RangeT& Input, + FinderT Finder ) + { + BOOST_CONCEPT_ASSERT(( + FinderConcept::type> + )); + + iterator_range::type> lit_input(::boost::as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef split_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + range_value::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=::boost::end(lit_input); + + typedef transform_iterator + transform_iter_type; + + transform_iter_type itBegin= + ::boost::make_transform_iterator( + find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), + copy_range_type() ); + + transform_iter_type itEnd= + ::boost::make_transform_iterator( + find_iterator_type(), + copy_range_type() ); + + SequenceSequenceT Tmp(itBegin, itEnd); + + Result.swap(Tmp); + return Result; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::iter_find; + using algorithm::iter_split; + +} // namespace boost + + +#endif // BOOST_STRING_ITER_FIND_HPP diff --git a/boost/algorithm/string/predicate_facade.hpp b/boost/algorithm/string/predicate_facade.hpp new file mode 100644 index 00000000..a9753fc2 --- /dev/null +++ b/boost/algorithm/string/predicate_facade.hpp @@ -0,0 +1,42 @@ +// Boost string_algo library predicate_facade.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_PREDICATE_FACADE_HPP +#define BOOST_STRING_PREDICATE_FACADE_HPP + +#include + +/* + \file boost/algorith/string/predicate_facade.hpp + This file contains predicate_facade definition. This template class is used + to identify classification predicates, so they can be combined using + composition operators. +*/ + +namespace boost { + namespace algorithm { + +// predicate facade ------------------------------------------------------// + + //! Predicate facade + /*! + This class allows to recognize classification + predicates, so that they can be combined using + composition operators. + Every classification predicate must be derived from this class. + */ + template + struct predicate_facade {}; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP diff --git a/boost/algorithm/string/split.hpp b/boost/algorithm/string/split.hpp new file mode 100644 index 00000000..cae712c0 --- /dev/null +++ b/boost/algorithm/string/split.hpp @@ -0,0 +1,163 @@ +// Boost string_algo library split.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// 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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_SPLIT_HPP +#define BOOST_STRING_SPLIT_HPP + +#include + +#include +#include +#include + +/*! \file + Defines basic split algorithms. + Split algorithms can be used to divide a string + into several parts according to given criteria. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> +*/ + +namespace boost { + namespace algorithm { + +// find_all ------------------------------------------------------------// + + //! Find all algorithm + /*! + This algorithm finds all occurrences of the search string + in the input. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Search A substring to be searched for. + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename Range2T > + inline SequenceSequenceT& find_all( + SequenceSequenceT& Result, + Range1T& Input, + const Range2T& Search) + { + return ::boost::algorithm::iter_find( + Result, + Input, + ::boost::algorithm::first_finder(Search) ); + } + + //! Find all algorithm ( case insensitive ) + /*! + This algorithm finds all occurrences of the search string + in the input. + Each part is copied and added as a new element to the + output container. Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + Searching is case insensitive. + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename Range2T > + inline SequenceSequenceT& ifind_all( + SequenceSequenceT& Result, + Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::iter_find( + Result, + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc) ) ); + } + + +// tokenize -------------------------------------------------------------// + + //! Split algorithm + /*! + Tokenize expression. This function is equivalent to C strtok. Input + sequence is split into tokens, separated by separators. Separators + are given by means of the predicate. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Pred A predicate to identify separators. This predicate is + supposed to return true if a given element is a separator. + \param eCompress If eCompress argument is set to token_compress_on, adjacent + separators are merged together. Otherwise, every two separators + delimit a token. + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename RangeT, typename PredicateT > + inline SequenceSequenceT& split( + SequenceSequenceT& Result, + RangeT& Input, + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return ::boost::algorithm::iter_split( + Result, + Input, + ::boost::algorithm::token_finder( Pred, eCompress ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_all; + using algorithm::ifind_all; + using algorithm::split; + +} // namespace boost + + +#endif // BOOST_STRING_SPLIT_HPP + diff --git a/boost/algorithm/string/trim.hpp b/boost/algorithm/string/trim.hpp new file mode 100644 index 00000000..e740d57d --- /dev/null +++ b/boost/algorithm/string/trim.hpp @@ -0,0 +1,398 @@ +// Boost string_algo library trim.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-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 updates, documentation, and revision history. + +#ifndef BOOST_STRING_TRIM_HPP +#define BOOST_STRING_TRIM_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines trim algorithms. + Trim algorithms are used to remove trailing and leading spaces from a + sequence (string). Space is recognized using given locales. + + Parametric (\c _if) variants use a predicate (functor) to select which characters + are to be trimmed.. + Functions take a selection predicate as a parameter, which is used to determine + whether a character is a space. Common predicates are provided in classification.hpp header. + +*/ + +namespace boost { + namespace algorithm { + + // left trim -----------------------------------------------// + + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace A unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_left_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace) + { + iterator_range::type> lit_range(::boost::as_literal(Input)); + + std::copy( + ::boost::algorithm::detail::trim_begin( + ::boost::begin(lit_range), + ::boost::end(lit_range), + IsSpace ), + ::boost::end(lit_range), + Output); + + return Output; + } + + //! Left trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_left_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + ::boost::algorithm::detail::trim_begin( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace ), + ::boost::end(Input)); + } + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. + The result is a trimmed copy of the input. + + \param Input An input sequence + \param Loc a locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_left_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + ::boost::algorithm::trim_left_copy_if( + Input, + is_space(Loc)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. The supplied predicate is + used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace A unary predicate identifying spaces + */ + template + inline void trim_left_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + ::boost::begin(Input), + ::boost::algorithm::detail::trim_begin( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. + The Input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_left(SequenceT& Input, const std::locale& Loc=std::locale()) + { + ::boost::algorithm::trim_left_if( + Input, + is_space(Loc)); + } + + // right trim -----------------------------------------------// + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace A unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_right_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace ) + { + iterator_range::type> lit_range(::boost::as_literal(Input)); + + std::copy( + ::boost::begin(lit_range), + ::boost::algorithm::detail::trim_end( + ::boost::begin(lit_range), + ::boost::end(lit_range), + IsSpace ), + Output ); + + return Output; + } + + //! Right trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_right_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + ::boost::begin(Input), + ::boost::algorithm::detail::trim_end( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace) + ); + } + + //! Right trim + /*! + Remove all trailing spaces from the input. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_right_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + ::boost::algorithm::trim_right_copy_if( + Input, + is_space(Loc)); + } + + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace A unary predicate identifying spaces + */ + template + inline void trim_right_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + ::boost::algorithm::detail::trim_end( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace ), + ::boost::end(Input) + ); + } + + + //! Right trim + /*! + Remove all trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_right(SequenceT& Input, const std::locale& Loc=std::locale()) + { + ::boost::algorithm::trim_right_if( + Input, + is_space(Loc) ); + } + + // both side trim -----------------------------------------------// + + //! Trim - parametric + /*! + Remove all trailing and leading spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace A unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace) + { + iterator_range::type> lit_range(::boost::as_literal(Input)); + + BOOST_STRING_TYPENAME + range_const_iterator::type TrimEnd= + ::boost::algorithm::detail::trim_end( + ::boost::begin(lit_range), + ::boost::end(lit_range), + IsSpace); + + std::copy( + detail::trim_begin( + ::boost::begin(lit_range), TrimEnd, IsSpace), + TrimEnd, + Output + ); + + return Output; + } + + //! Trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + BOOST_STRING_TYPENAME + range_const_iterator::type TrimEnd= + ::boost::algorithm::detail::trim_end( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace); + + return SequenceT( + detail::trim_begin( + ::boost::begin(Input), + TrimEnd, + IsSpace), + TrimEnd + ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_copy( const SequenceT& Input, const std::locale& Loc=std::locale() ) + { + return + ::boost::algorithm::trim_copy_if( + Input, + is_space(Loc) ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace A unary predicate identifying spaces + */ + template + inline void trim_if(SequenceT& Input, PredicateT IsSpace) + { + ::boost::algorithm::trim_right_if( Input, IsSpace ); + ::boost::algorithm::trim_left_if( Input, IsSpace ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim(SequenceT& Input, const std::locale& Loc=std::locale()) + { + ::boost::algorithm::trim_if( + Input, + is_space( Loc ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::trim_left; + using algorithm::trim_left_if; + using algorithm::trim_left_copy; + using algorithm::trim_left_copy_if; + using algorithm::trim_right; + using algorithm::trim_right_if; + using algorithm::trim_right_copy; + using algorithm::trim_right_copy_if; + using algorithm::trim; + using algorithm::trim_if; + using algorithm::trim_copy; + using algorithm::trim_copy_if; + +} // namespace boost + +#endif // BOOST_STRING_TRIM_HPP diff --git a/boost/aligned_storage.hpp b/boost/aligned_storage.hpp new file mode 100644 index 00000000..f400fa9e --- /dev/null +++ b/boost/aligned_storage.hpp @@ -0,0 +1,18 @@ +//----------------------------------------------------------------------------- +// boost aligned_storage.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2002-2003 +// Eric Friedman, Itay Maman +// +// 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_ALIGNED_STORAGE_HPP +#define BOOST_ALIGNED_STORAGE_HPP + +#include + +#endif // BOOST_ALIGNED_STORAGE_HPP diff --git a/boost/any.hpp b/boost/any.hpp new file mode 100644 index 00000000..9f6b3132 --- /dev/null +++ b/boost/any.hpp @@ -0,0 +1,337 @@ +// See http://www.boost.org/libs/any for Documentation. + +#ifndef BOOST_ANY_INCLUDED +#define BOOST_ANY_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +// what: variant type boost::any +// who: contributed by Kevlin Henney, +// with features contributed and bugs found by +// Antony Polukhin, Ed Brey, Mark Rodgers, +// Peter Dimov, and James Curran +// when: July 2001, April 2013 - May 2013 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + class any + { + public: // structors + + any() BOOST_NOEXCEPT + : content(0) + { + } + + template + any(const ValueType & value) + : content(new holder< + BOOST_DEDUCED_TYPENAME remove_cv::type>::type + >(value)) + { + } + + any(const any & other) + : content(other.content ? other.content->clone() : 0) + { + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Move constructor + any(any&& other) BOOST_NOEXCEPT + : content(other.content) + { + other.content = 0; + } + + // Perfect forwarding of ValueType + template + any(ValueType&& value + , typename boost::disable_if >::type* = 0 // disable if value has type `any&` + , typename boost::disable_if >::type* = 0) // disable if value has type `const ValueType&&` + : content(new holder< typename decay::type >(static_cast(value))) + { + } +#endif + + ~any() BOOST_NOEXCEPT + { + delete content; + } + + public: // modifiers + + any & swap(any & rhs) BOOST_NOEXCEPT + { + std::swap(content, rhs.content); + return *this; + } + + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + template + any & operator=(const ValueType & rhs) + { + any(rhs).swap(*this); + return *this; + } + + any & operator=(any rhs) + { + any(rhs).swap(*this); + return *this; + } + +#else + any & operator=(const any& rhs) + { + any(rhs).swap(*this); + return *this; + } + + // move assignement + any & operator=(any&& rhs) BOOST_NOEXCEPT + { + rhs.swap(*this); + any().swap(rhs); + return *this; + } + + // Perfect forwarding of ValueType + template + any & operator=(ValueType&& rhs) + { + any(static_cast(rhs)).swap(*this); + return *this; + } +#endif + + public: // queries + + bool empty() const BOOST_NOEXCEPT + { + return !content; + } + + void clear() BOOST_NOEXCEPT + { + any().swap(*this); + } + + const boost::typeindex::type_info& type() const BOOST_NOEXCEPT + { + return content ? content->type() : boost::typeindex::type_id().type_info(); + } + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + private: // types +#else + public: // types (public so any_cast can be non-friend) +#endif + + class placeholder + { + public: // structors + + virtual ~placeholder() + { + } + + public: // queries + + virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0; + + virtual placeholder * clone() const = 0; + + }; + + template + class holder : public placeholder + { + public: // structors + + holder(const ValueType & value) + : held(value) + { + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + holder(ValueType&& value) + : held(static_cast< ValueType&& >(value)) + { + } +#endif + public: // queries + + virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT + { + return boost::typeindex::type_id().type_info(); + } + + virtual placeholder * clone() const + { + return new holder(held); + } + + public: // representation + + ValueType held; + + private: // intentionally left unimplemented + holder & operator=(const holder &); + }; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + + private: // representation + + template + friend ValueType * any_cast(any *) BOOST_NOEXCEPT; + + template + friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT; + +#else + + public: // representation (public so any_cast can be non-friend) + +#endif + + placeholder * content; + + }; + + inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT + { + lhs.swap(rhs); + } + + class BOOST_SYMBOL_VISIBLE bad_any_cast : +#ifndef BOOST_NO_RTTI + public std::bad_cast +#else + public std::exception +#endif + { + public: + virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW + { + return "boost::bad_any_cast: " + "failed conversion using boost::any_cast"; + } + }; + + template + ValueType * any_cast(any * operand) BOOST_NOEXCEPT + { + return operand && operand->type() == boost::typeindex::type_id() + ? boost::addressof( + static_cast::type> *>(operand->content)->held + ) + : 0; + } + + template + inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT + { + return any_cast(const_cast(operand)); + } + + template + ValueType any_cast(any & operand) + { + typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; + + + nonref * result = any_cast(boost::addressof(operand)); + if(!result) + boost::throw_exception(bad_any_cast()); + + // Attempt to avoid construction of a temporary object in cases when + // `ValueType` is not a reference. Example: + // `static_cast(*result);` + // which is equal to `std::string(*result);` + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_reference, + ValueType, + BOOST_DEDUCED_TYPENAME boost::add_reference::type + >::type ref_type; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local! +#endif + return static_cast(*result); +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + } + + template + inline ValueType any_cast(const any & operand) + { + typedef BOOST_DEDUCED_TYPENAME remove_reference::type nonref; + return any_cast(const_cast(operand)); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + inline ValueType any_cast(any&& operand) + { + BOOST_STATIC_ASSERT_MSG( + boost::is_rvalue_reference::value /*true if ValueType is rvalue or just a value*/ + || boost::is_const< typename boost::remove_reference::type >::value, + "boost::any_cast shall not be used for getting nonconst references to temporary objects" + ); + return any_cast(operand); + } +#endif + + + // Note: The "unsafe" versions of any_cast are not part of the + // public interface and may be removed at any time. They are + // required where we know what type is stored in the any and can't + // use typeid() comparison, e.g., when our types may travel across + // different shared libraries. + template + inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT + { + return boost::addressof( + static_cast *>(operand->content)->held + ); + } + + template + inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT + { + return unsafe_any_cast(const_cast(operand)); + } +} + +// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. +// +// 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) + +#endif diff --git a/boost/array.hpp b/boost/array.hpp new file mode 100644 index 00000000..210c0721 --- /dev/null +++ b/boost/array.hpp @@ -0,0 +1,457 @@ +/* The following code declares class array, + * an STL container (as wrapper) for arrays of constant size. + * + * See + * http://www.boost.org/libs/array/ + * for documentation. + * + * The original author site is at: http://www.josuttis.com/ + * + * (C) Copyright Nicolai M. Josuttis 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) + * + * 9 Jan 2013 - (mtc) Added constexpr + * 14 Apr 2012 - (mtc) Added support for boost::hash + * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility. + * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group. + * See or Trac issue #3168 + * Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow) + * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow) + * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) + * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. + * 05 Aug 2001 - minor update (Nico Josuttis) + * 20 Jan 2001 - STLport fix (Beman Dawes) + * 29 Sep 2000 - Initial Revision (Nico Josuttis) + * + * Jan 29, 2004 + */ +#ifndef BOOST_ARRAY_HPP +#define BOOST_ARRAY_HPP + +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning(push) +# pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe +# pragma warning(disable:4510) // boost::array' : default constructor could not be generated +# pragma warning(disable:4610) // warning C4610: class 'boost::array' can never be instantiated - user defined constructor required +#endif + +#include +#include +#include +#include +#include + +// Handles broken standard libraries better than +#include +#include +#include + +// FIXES for broken compilers +#include + + +namespace boost { + + template + class array { + public: + T elems[N]; // fixed-size array of elements of type T + + public: + // type definitions + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // iterator support + iterator begin() { return elems; } + const_iterator begin() const { return elems; } + const_iterator cbegin() const { return elems; } + + iterator end() { return elems+N; } + const_iterator end() const { return elems+N; } + const_iterator cend() const { return elems+N; } + + // reverse iterator support +#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#else + // workaround for broken reverse_iterator implementations + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const { + return const_reverse_iterator(end()); + } + + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const { + return const_reverse_iterator(begin()); + } + + // operator[] + reference operator[](size_type i) + { + return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; + } + + /*BOOST_CONSTEXPR*/ const_reference operator[](size_type i) const + { + return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; + } + + // at() with range check + reference at(size_type i) { return rangecheck(i), elems[i]; } + /*BOOST_CONSTEXPR*/ const_reference at(size_type i) const { return rangecheck(i), elems[i]; } + + // front() and back() + reference front() + { + return elems[0]; + } + + BOOST_CONSTEXPR const_reference front() const + { + return elems[0]; + } + + reference back() + { + return elems[N-1]; + } + + BOOST_CONSTEXPR const_reference back() const + { + return elems[N-1]; + } + + // size is constant + static BOOST_CONSTEXPR size_type size() { return N; } + static BOOST_CONSTEXPR bool empty() { return false; } + static BOOST_CONSTEXPR size_type max_size() { return N; } + enum { static_size = N }; + + // swap (note: linear complexity) + void swap (array& y) { + for (size_type i = 0; i < N; ++i) + boost::swap(elems[i],y.elems[i]); + } + + // direct access to data (read-only) + const T* data() const { return elems; } + T* data() { return elems; } + + // use array as C array (direct read/write access to data) + T* c_array() { return elems; } + + // assignment with type conversion + template + array& operator= (const array& rhs) { + std::copy(rhs.begin(),rhs.end(), begin()); + return *this; + } + + // assign one value to all elements + void assign (const T& value) { fill ( value ); } // A synonym for fill + void fill (const T& value) + { + std::fill_n(begin(),size(),value); + } + + // check range (may be private because it is static) + static BOOST_CONSTEXPR bool rangecheck (size_type i) { + return i > size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true; + } + + }; + + template< class T > + class array< T, 0 > { + + public: + // type definitions + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // iterator support + iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); } + const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } + const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } + + iterator end() { return begin(); } + const_iterator end() const { return begin(); } + const_iterator cend() const { return cbegin(); } + + // reverse iterator support +#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#else + // workaround for broken reverse_iterator implementations + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const { + return const_reverse_iterator(end()); + } + + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const { + return const_reverse_iterator(begin()); + } + + // operator[] + reference operator[](size_type /*i*/) + { + return failed_rangecheck(); + } + + /*BOOST_CONSTEXPR*/ const_reference operator[](size_type /*i*/) const + { + return failed_rangecheck(); + } + + // at() with range check + reference at(size_type /*i*/) { return failed_rangecheck(); } + /*BOOST_CONSTEXPR*/ const_reference at(size_type /*i*/) const { return failed_rangecheck(); } + + // front() and back() + reference front() + { + return failed_rangecheck(); + } + + BOOST_CONSTEXPR const_reference front() const + { + return failed_rangecheck(); + } + + reference back() + { + return failed_rangecheck(); + } + + BOOST_CONSTEXPR const_reference back() const + { + return failed_rangecheck(); + } + + // size is constant + static BOOST_CONSTEXPR size_type size() { return 0; } + static BOOST_CONSTEXPR bool empty() { return true; } + static BOOST_CONSTEXPR size_type max_size() { return 0; } + enum { static_size = 0 }; + + void swap (array& /*y*/) { + } + + // direct access to data (read-only) + const T* data() const { return 0; } + T* data() { return 0; } + + // use array as C array (direct read/write access to data) + T* c_array() { return 0; } + + // assignment with type conversion + template + array& operator= (const array& ) { + return *this; + } + + // assign one value to all elements + void assign (const T& value) { fill ( value ); } + void fill (const T& ) {} + + // check range (may be private because it is static) + static reference failed_rangecheck () { + std::out_of_range e("attempt to access element of an empty array"); + boost::throw_exception(e); +#if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__)) + // + // We need to return something here to keep + // some compilers happy: however we will never + // actually get here.... + // + static T placeholder; + return placeholder; +#endif + } + }; + + // comparisons + template + bool operator== (const array& x, const array& y) { + return std::equal(x.begin(), x.end(), y.begin()); + } + template + bool operator< (const array& x, const array& y) { + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); + } + template + bool operator!= (const array& x, const array& y) { + return !(x==y); + } + template + bool operator> (const array& x, const array& y) { + return y + bool operator<= (const array& x, const array& y) { + return !(y + bool operator>= (const array& x, const array& y) { + return !(x + inline void swap (array& x, array& y) { + x.swap(y); + } + +#if defined(__SUNPRO_CC) +// Trac ticket #4757; the Sun Solaris compiler can't handle +// syntax like 'T(&get_c_array(boost::array& arg))[N]' +// +// We can't just use this for all compilers, because the +// borland compilers can't handle this form. + namespace detail { + template struct c_array + { + typedef T type[N]; + }; + } + + // Specific for boost::array: simply returns its elems data member. + template + typename detail::c_array::type& get_c_array(boost::array& arg) + { + return arg.elems; + } + + // Specific for boost::array: simply returns its elems data member. + template + typename detail::c_array::type const& get_c_array(const boost::array& arg) + { + return arg.elems; + } +#else +// Specific for boost::array: simply returns its elems data member. + template + T(&get_c_array(boost::array& arg))[N] + { + return arg.elems; + } + + // Const version. + template + const T(&get_c_array(const boost::array& arg))[N] + { + return arg.elems; + } +#endif + +#if 0 + // Overload for std::array, assuming that std::array will have + // explicit conversion functions as discussed at the WG21 meeting + // in Summit, March 2009. + template + T(&get_c_array(std::array& arg))[N] + { + return static_cast(arg); + } + + // Const version. + template + const T(&get_c_array(const std::array& arg))[N] + { + return static_cast(arg); + } +#endif + + template std::size_t hash_range(It, It); + + template + std::size_t hash_value(const array& arr) + { + return boost::hash_range(arr.begin(), arr.end()); + } + + template + T &get(boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" ); + return arr[Idx]; + } + + template + const T &get(const boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" ); + return arr[Idx]; + } + +} /* namespace boost */ + +#ifndef BOOST_NO_CXX11_HDR_ARRAY +// If we don't have std::array, I'm assuming that we don't have std::get +namespace std { + template + T &get(boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" ); + return arr[Idx]; + } + + template + const T &get(const boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" ); + return arr[Idx]; + } +} +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning(pop) +#endif + +#endif /*BOOST_ARRAY_HPP*/ diff --git a/boost/assert.hpp b/boost/assert.hpp new file mode 100644 index 00000000..9650d7a2 --- /dev/null +++ b/boost/assert.hpp @@ -0,0 +1,85 @@ +// +// 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 +{ + void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined + 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/boost/atomic.hpp b/boost/atomic.hpp new file mode 100644 index 00000000..cc28b1ab --- /dev/null +++ b/boost/atomic.hpp @@ -0,0 +1,18 @@ +#ifndef BOOST_ATOMIC_HPP +#define BOOST_ATOMIC_HPP + +// Copyright (c) 2011 Helge Bahmann +// +// 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) + +// This header includes all Boost.Atomic public headers + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif diff --git a/boost/atomic/atomic.hpp b/boost/atomic/atomic.hpp new file mode 100644 index 00000000..5a805882 --- /dev/null +++ b/boost/atomic/atomic.hpp @@ -0,0 +1,104 @@ +/* + * 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) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/atomic.hpp + * + * This header contains definition of \c atomic template and \c atomic_flag. + */ + +#ifndef BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ +#define BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) +#include +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { + +using atomics::atomic; + +using atomics::atomic_char; +using atomics::atomic_uchar; +using atomics::atomic_schar; +using atomics::atomic_uint8_t; +using atomics::atomic_int8_t; +using atomics::atomic_ushort; +using atomics::atomic_short; +using atomics::atomic_uint16_t; +using atomics::atomic_int16_t; +using atomics::atomic_uint; +using atomics::atomic_int; +using atomics::atomic_uint32_t; +using atomics::atomic_int32_t; +using atomics::atomic_ulong; +using atomics::atomic_long; +using atomics::atomic_uint64_t; +using atomics::atomic_int64_t; +#ifdef BOOST_HAS_LONG_LONG +using atomics::atomic_ullong; +using atomics::atomic_llong; +#endif +using atomics::atomic_address; +using atomics::atomic_bool; +using atomics::atomic_wchar_t; +#if !defined(BOOST_NO_CXX11_CHAR16_T) +using atomics::atomic_char16_t; +#endif +#if !defined(BOOST_NO_CXX11_CHAR32_T) +using atomics::atomic_char32_t; +#endif + +using atomics::atomic_int_least8_t; +using atomics::atomic_uint_least8_t; +using atomics::atomic_int_least16_t; +using atomics::atomic_uint_least16_t; +using atomics::atomic_int_least32_t; +using atomics::atomic_uint_least32_t; +using atomics::atomic_int_least64_t; +using atomics::atomic_uint_least64_t; +using atomics::atomic_int_fast8_t; +using atomics::atomic_uint_fast8_t; +using atomics::atomic_int_fast16_t; +using atomics::atomic_uint_fast16_t; +using atomics::atomic_int_fast32_t; +using atomics::atomic_uint_fast32_t; +using atomics::atomic_int_fast64_t; +using atomics::atomic_uint_fast64_t; +using atomics::atomic_intmax_t; +using atomics::atomic_uintmax_t; + +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) +using atomics::atomic_float_t; +using atomics::atomic_double_t; +using atomics::atomic_long_double_t; +#endif + +using atomics::atomic_size_t; +using atomics::atomic_ptrdiff_t; + +#if defined(BOOST_HAS_INTPTR_T) +using atomics::atomic_intptr_t; +using atomics::atomic_uintptr_t; +#endif + +} // namespace boost + +#endif // BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ diff --git a/boost/atomic/atomic_flag.hpp b/boost/atomic/atomic_flag.hpp new file mode 100644 index 00000000..ac296bcc --- /dev/null +++ b/boost/atomic/atomic_flag.hpp @@ -0,0 +1,33 @@ +/* + * 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) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/atomic_flag.hpp + * + * This header contains definition of \c atomic_flag. + */ + +#ifndef BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_ +#define BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_ + +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { + +using atomics::atomic_flag; + +} // namespace boost + +#endif // BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_ diff --git a/boost/atomic/capabilities.hpp b/boost/atomic/capabilities.hpp new file mode 100644 index 00000000..5c7434d9 --- /dev/null +++ b/boost/atomic/capabilities.hpp @@ -0,0 +1,210 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/capabilities.hpp + * + * This header defines feature capabilities macros. + */ + +#ifndef BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_ +#define BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_ + +#include +#include +#include +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) +#include +#endif + +#if !defined(BOOST_ATOMIC_EMULATED) +#include BOOST_ATOMIC_DETAIL_BACKEND_HEADER(boost/atomic/detail/caps_) +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#ifndef BOOST_ATOMIC_INT8_LOCK_FREE +#define BOOST_ATOMIC_INT8_LOCK_FREE 0 +#endif + +#ifndef BOOST_ATOMIC_INT16_LOCK_FREE +#define BOOST_ATOMIC_INT16_LOCK_FREE 0 +#endif + +#ifndef BOOST_ATOMIC_INT32_LOCK_FREE +#define BOOST_ATOMIC_INT32_LOCK_FREE 0 +#endif + +#ifndef BOOST_ATOMIC_INT64_LOCK_FREE +#define BOOST_ATOMIC_INT64_LOCK_FREE 0 +#endif + +#ifndef BOOST_ATOMIC_INT128_LOCK_FREE +#define BOOST_ATOMIC_INT128_LOCK_FREE 0 +#endif + + +#ifndef BOOST_ATOMIC_CHAR_LOCK_FREE +#define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#endif + +#ifndef BOOST_ATOMIC_CHAR16_T_LOCK_FREE +#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#endif + +#ifndef BOOST_ATOMIC_CHAR32_T_LOCK_FREE +#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#endif + +#ifndef BOOST_ATOMIC_WCHAR_T_LOCK_FREE +#if BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#else +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0 +#endif +#endif + +#ifndef BOOST_ATOMIC_SHORT_LOCK_FREE +#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1 +#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2 +#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4 +#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8 +#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#else +#define BOOST_ATOMIC_SHORT_LOCK_FREE 0 +#endif +#endif + +#ifndef BOOST_ATOMIC_INT_LOCK_FREE +#if BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1 +#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2 +#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4 +#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8 +#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#else +#define BOOST_ATOMIC_INT_LOCK_FREE 0 +#endif +#endif + +#ifndef BOOST_ATOMIC_LONG_LOCK_FREE +#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1 +#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2 +#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4 +#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8 +#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#else +#define BOOST_ATOMIC_LONG_LOCK_FREE 0 +#endif +#endif + +#ifndef BOOST_ATOMIC_LLONG_LOCK_FREE +#if BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1 +#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2 +#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4 +#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8 +#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#else +#define BOOST_ATOMIC_LLONG_LOCK_FREE 0 +#endif +#endif + +#ifndef BOOST_ATOMIC_POINTER_LOCK_FREE +#if (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 8 +#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#elif (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 4 +#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#else +#define BOOST_ATOMIC_POINTER_LOCK_FREE 0 +#endif +#endif + +#define BOOST_ATOMIC_ADDRESS_LOCK_FREE BOOST_ATOMIC_POINTER_LOCK_FREE + +#ifndef BOOST_ATOMIC_BOOL_LOCK_FREE +// We store bools in 1-byte storage in all backends +#define BOOST_ATOMIC_BOOL_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#endif + +#ifndef BOOST_ATOMIC_FLAG_LOCK_FREE +#define BOOST_ATOMIC_FLAG_LOCK_FREE BOOST_ATOMIC_BOOL_LOCK_FREE +#endif + +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) + +#if !defined(BOOST_ATOMIC_FLOAT_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) +#if BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 2 +#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 4 +#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 8 +#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 16 +#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE +#else +#define BOOST_ATOMIC_FLOAT_LOCK_FREE 0 +#endif +#endif + +#if !defined(BOOST_ATOMIC_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) +#if BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 2 +#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 4 +#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 8 +#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 16 +#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE +#else +#define BOOST_ATOMIC_DOUBLE_LOCK_FREE 0 +#endif +#endif + +#if !defined(BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE) +#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 2 +#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 4 +#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 8 +#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 16 +#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE +#else +#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE 0 +#endif +#endif + +#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT) + +#ifndef BOOST_ATOMIC_THREAD_FENCE +#define BOOST_ATOMIC_THREAD_FENCE 0 +#endif + +#ifndef BOOST_ATOMIC_SIGNAL_FENCE +#define BOOST_ATOMIC_SIGNAL_FENCE 0 +#endif + +#endif // BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_ diff --git a/boost/atomic/detail/addressof.hpp b/boost/atomic/detail/addressof.hpp new file mode 100644 index 00000000..38e876e3 --- /dev/null +++ b/boost/atomic/detail/addressof.hpp @@ -0,0 +1,58 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/addressof.hpp + * + * This header defines \c addressof helper function. It is similar to \c boost::addressof but it is more + * lightweight and also contains a workaround for some compiler warnings. + */ + +#ifndef BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +// Detection logic is based on boost/core/addressof.hpp +#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215 +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF +#elif defined(BOOST_GCC) && BOOST_GCC >= 70000 +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF +#elif defined(__has_builtin) +#if __has_builtin(__builtin_addressof) +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF +#endif +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename T > +BOOST_FORCEINLINE T* addressof(T& value) BOOST_NOEXCEPT +{ +#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF) + return __builtin_addressof(value); +#else + // Note: The point of using a local struct as the intermediate type instead of char is to avoid gcc warnings + // if T is a const volatile char*: + // warning: casting 'const volatile char* const' to 'const volatile char&' does not dereference pointer + // The local struct makes sure T is not related to the cast target type. + struct opaque_type; + return reinterpret_cast< T* >(&const_cast< opaque_type& >(reinterpret_cast< const volatile opaque_type& >(value))); +#endif +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_ diff --git a/boost/atomic/detail/atomic_flag.hpp b/boost/atomic/detail/atomic_flag.hpp new file mode 100644 index 00000000..6f5fc8ac --- /dev/null +++ b/boost/atomic/detail/atomic_flag.hpp @@ -0,0 +1,71 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/atomic_flag.hpp + * + * This header contains interface definition of \c atomic_flag. + */ + +#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_ + +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +/* + * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE, + * see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp. + */ + +namespace boost { +namespace atomics { + +#if defined(BOOST_NO_CXX11_CONSTEXPR) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) +#define BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT +#else +#define BOOST_ATOMIC_FLAG_INIT {} +#endif + +struct atomic_flag +{ + typedef atomics::detail::operations< 1u, false > operations; + typedef operations::storage_type storage_type; + + operations::aligned_storage_type m_storage; + + BOOST_FORCEINLINE BOOST_CONSTEXPR atomic_flag() BOOST_NOEXCEPT : m_storage(0) + { + } + + BOOST_FORCEINLINE bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return operations::test_and_set(m_storage.value, order); + } + + BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_consume); + BOOST_ASSERT(order != memory_order_acquire); + BOOST_ASSERT(order != memory_order_acq_rel); + operations::clear(m_storage.value, order); + } + + BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&)) + BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&)) +}; + +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_ diff --git a/boost/atomic/detail/atomic_template.hpp b/boost/atomic/detail/atomic_template.hpp new file mode 100644 index 00000000..fb0a8f58 --- /dev/null +++ b/boost/atomic/detail/atomic_template.hpp @@ -0,0 +1,1248 @@ +/* + * 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) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/atomic_template.hpp + * + * This header contains interface definition of \c atomic template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) +#include +#include +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +// 'boost::atomics::atomic' : multiple assignment operators specified +#pragma warning(disable: 4522) +#endif + +/* + * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE, + * see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp. + */ + +namespace boost { +namespace atomics { +namespace detail { + +BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order deduce_failure_order(memory_order order) BOOST_NOEXCEPT +{ + return order == memory_order_acq_rel ? memory_order_acquire : (order == memory_order_release ? memory_order_relaxed : order); +} + +BOOST_FORCEINLINE BOOST_CONSTEXPR bool cas_failure_order_must_not_be_stronger_than_success_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT +{ + // 15 == (memory_order_seq_cst | memory_order_consume), see memory_order.hpp + // Given the enum values we can test the strength of memory order requirements with this single condition. + return (static_cast< unsigned int >(failure_order) & 15u) <= (static_cast< unsigned int >(success_order) & 15u); +} + +template< typename T, bool IsFunction = atomics::detail::is_function< T >::value > +struct classify_pointer +{ + typedef void* type; +}; + +template< typename T > +struct classify_pointer< T, true > +{ + typedef void type; +}; + +template< typename T, bool IsInt = atomics::detail::is_integral< T >::value, bool IsFloat = atomics::detail::is_floating_point< T >::value > +struct classify +{ + typedef void type; +}; + +template< typename T > +struct classify< T, true, false > { typedef int type; }; + +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) +template< typename T > +struct classify< T, false, true > { typedef float type; }; +#endif + +template< typename T > +struct classify< T*, false, false > { typedef typename classify_pointer< T >::type type; }; + +template< > +struct classify< void*, false, false > { typedef void type; }; + +template< > +struct classify< const void*, false, false > { typedef void type; }; + +template< > +struct classify< volatile void*, false, false > { typedef void type; }; + +template< > +struct classify< const volatile void*, false, false > { typedef void type; }; + +template< typename T, typename U > +struct classify< T U::*, false, false > { typedef void type; }; + + +#if defined(BOOST_INTEL) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40700) ||\ + (defined(BOOST_CLANG) && !defined(__apple_build_version__) && ((__clang_major__+0) * 100 + (__clang_minor__+0)) < 302) ||\ + (defined(__clang__) && defined(__apple_build_version__) && ((__clang_major__+0) * 100 + (__clang_minor__+0)) < 402) +// Intel compiler (at least 18.0 update 1) breaks if noexcept specification is used in defaulted function declarations: +// error: the default constructor of "boost::atomics::atomic" cannot be referenced -- it is a deleted function +// GCC 4.6 doesn't seem to support that either. Clang 3.1 deduces wrong noexcept for the defaulted function and fails as well. +#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL +#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL BOOST_NOEXCEPT +#else +#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL BOOST_NOEXCEPT +#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL +#endif + +template< typename T, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value > +class base_atomic_generic; + +template< typename T > +class base_atomic_generic< T, true > +{ +public: + typedef T value_type; + +protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; + typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type; + +public: + typedef typename operations::storage_type storage_type; + +protected: + typename operations::aligned_storage_type m_storage; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic_generic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {}) + BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< storage_type >(v)) + { + } +}; + +template< typename T > +class base_atomic_generic< T, false > +{ +public: + typedef T value_type; + +protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; + typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type; + +public: + typedef typename operations::storage_type storage_type; + +protected: + typename operations::aligned_storage_type m_storage; + +public: + BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v = value_type()) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< storage_type >(v)) + { + } +}; + + +template< typename T, typename Kind > +class base_atomic; + +//! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types +template< typename T > +class base_atomic< T, void > : + public base_atomic_generic< T > +{ +private: + typedef base_atomic_generic< T > base_type; + +public: + typedef typename base_type::value_type value_type; + typedef typename base_type::storage_type storage_type; + +protected: + typedef typename base_type::operations operations; + typedef typename base_type::value_arg_type value_arg_type; + +private: + typedef atomics::detail::integral_constant< bool, sizeof(value_type) == sizeof(storage_type) > value_matches_storage; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {}) + BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v) + { + } + + BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_consume); + BOOST_ASSERT(order != memory_order_acquire); + BOOST_ASSERT(order != memory_order_acq_rel); + + operations::store(this->m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order); + } + + BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_release); + BOOST_ASSERT(order != memory_order_acq_rel); + + return atomics::detail::bitwise_cast< value_type >(operations::load(this->m_storage.value, order)); + } + + BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::bitwise_cast< value_type >(operations::exchange(this->m_storage.value, atomics::detail::bitwise_cast< storage_type >(v), order)); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_strong(this->m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); + const bool res = operations::compare_exchange_strong(this->m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); + expected = atomics::detail::bitwise_cast< value_type >(old_value); + return res; + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_weak(this->m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected); + const bool res = operations::compare_exchange_weak(this->m_storage.value, old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order); + expected = atomics::detail::bitwise_cast< value_type >(old_value); + return res; + } +}; + + +//! Implementation for integers +template< typename T > +class base_atomic< T, int > +{ +public: + typedef T value_type; + typedef T difference_type; + +protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, atomics::detail::is_signed< T >::value > operations; + typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef value_type value_arg_type; + +public: + typedef typename operations::storage_type storage_type; + +private: + typedef atomics::detail::integral_constant< bool, sizeof(value_type) == sizeof(storage_type) > value_matches_storage; + +protected: + typename operations::aligned_storage_type m_storage; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(v) {} + + // Standard methods + BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_consume); + BOOST_ASSERT(order != memory_order_acquire); + BOOST_ASSERT(order != memory_order_acq_rel); + + operations::store(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_release); + BOOST_ASSERT(order != memory_order_acq_rel); + + return atomics::detail::integral_truncate< value_type >(operations::load(m_storage.value, order)); + } + + BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(operations::fetch_add(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(operations::fetch_sub(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(operations::exchange(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(operations::fetch_and(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(operations::fetch_or(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(operations::fetch_xor(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + // Boost.Atomic extensions + BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(m_storage.value, order)); + } + + BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(m_storage.value, order)); + } + + BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::add(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::sub(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::negate(m_storage.value, order)); + } + + BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order)); + } + + BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(m_storage.value, order)); + } + + BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_add(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_sub(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_negate(m_storage.value, order); + } + + BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_and(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_or(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_xor(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_complement(m_storage.value, order); + } + + BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST + BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::add_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST + BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::sub_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::negate_and_test(m_storage.value, order); + } + + BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST + BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::and_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST + BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::or_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST + BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::xor_and_test(m_storage.value, atomics::detail::integral_extend< operations::is_signed, storage_type >(v), order); + } + + BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::complement_and_test(m_storage.value, order); + } + + BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(bit_number < sizeof(value_type) * 8u); + return extra_operations::bit_test_and_set(m_storage.value, bit_number, order); + } + + BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(bit_number < sizeof(value_type) * 8u); + return extra_operations::bit_test_and_reset(m_storage.value, bit_number, order); + } + + BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(bit_number < sizeof(value_type) * 8u); + return extra_operations::bit_test_and_complement(m_storage.value, bit_number, order); + } + + // Operators + BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT + { + return fetch_add(1); + } + + BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT + { + return add(1); + } + + BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT + { + return fetch_sub(1); + } + + BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT + { + return sub(1); + } + + BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT + { + return add(v); + } + + BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT + { + return sub(v); + } + + BOOST_FORCEINLINE value_type operator&=(value_type v) volatile BOOST_NOEXCEPT + { + return bitwise_and(v); + } + + BOOST_FORCEINLINE value_type operator|=(value_type v) volatile BOOST_NOEXCEPT + { + return bitwise_or(v); + } + + BOOST_FORCEINLINE value_type operator^=(value_type v) volatile BOOST_NOEXCEPT + { + return bitwise_xor(v); + } + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::integral_extend< operations::is_signed, storage_type >(expected); + const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order); + expected = atomics::detail::integral_truncate< value_type >(old_value); + return res; + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::integral_extend< operations::is_signed, storage_type >(expected); + const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::integral_extend< operations::is_signed, storage_type >(desired), success_order, failure_order); + expected = atomics::detail::integral_truncate< value_type >(old_value); + return res; + } +}; + +//! Implementation for bool +template< > +class base_atomic< bool, int > +{ +public: + typedef bool value_type; + +protected: + typedef atomics::detail::operations< 1u, false > operations; + typedef value_type value_arg_type; + +public: + typedef operations::storage_type storage_type; + +private: + typedef atomics::detail::integral_constant< bool, sizeof(value_type) == sizeof(storage_type) > value_matches_storage; + +protected: + operations::aligned_storage_type m_storage; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(v) {} + + // Standard methods + BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_consume); + BOOST_ASSERT(order != memory_order_acquire); + BOOST_ASSERT(order != memory_order_acq_rel); + + operations::store(m_storage.value, static_cast< storage_type >(v), order); + } + + BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_release); + BOOST_ASSERT(order != memory_order_acq_rel); + + return !!operations::load(m_storage.value, order); + } + + BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return !!operations::exchange(m_storage.value, static_cast< storage_type >(v), order); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = static_cast< storage_type >(expected); + const bool res = operations::compare_exchange_strong(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order); + expected = !!old_value; + return res; + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = static_cast< storage_type >(expected); + const bool res = operations::compare_exchange_weak(m_storage.value, old_value, static_cast< storage_type >(desired), success_order, failure_order); + expected = !!old_value; + return res; + } +}; + + +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) + +//! Implementation for floating point types +template< typename T > +class base_atomic< T, float > +{ +public: + typedef T value_type; + typedef T difference_type; + +protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; + typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef atomics::detail::fp_operations< extra_operations, value_type, operations::storage_size > fp_operations; + typedef atomics::detail::extra_fp_operations< fp_operations, value_type, operations::storage_size > extra_fp_operations; + typedef value_type value_arg_type; + +public: + typedef typename operations::storage_type storage_type; + +private: + typedef atomics::detail::integral_constant< bool, atomics::detail::value_sizeof< value_type >::value == sizeof(storage_type) > value_matches_storage; + +protected: + typename operations::aligned_storage_type m_storage; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {}) + BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_fp_cast< storage_type >(v)) {} + + BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_consume); + BOOST_ASSERT(order != memory_order_acquire); + BOOST_ASSERT(order != memory_order_acq_rel); + + operations::store(m_storage.value, atomics::detail::bitwise_fp_cast< storage_type >(v), order); + } + + BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_release); + BOOST_ASSERT(order != memory_order_acq_rel); + + return atomics::detail::bitwise_fp_cast< value_type >(operations::load(m_storage.value, order)); + } + + BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return fp_operations::fetch_add(m_storage.value, v, order); + } + + BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return fp_operations::fetch_sub(m_storage.value, v, order); + } + + BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::bitwise_fp_cast< value_type >(operations::exchange(m_storage.value, atomics::detail::bitwise_fp_cast< storage_type >(v), order)); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + // Boost.Atomic extensions + BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_fp_operations::fetch_negate(m_storage.value, order); + } + + BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_fp_operations::add(m_storage.value, v, order); + } + + BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_fp_operations::sub(m_storage.value, v, order); + } + + BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_fp_operations::negate(m_storage.value, order); + } + + BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_fp_operations::opaque_add(m_storage.value, v, order); + } + + BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_fp_operations::opaque_sub(m_storage.value, v, order); + } + + BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_fp_operations::opaque_negate(m_storage.value, order); + } + + // Operators + BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT + { + return add(v); + } + + BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT + { + return sub(v); + } + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected); + const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order); + expected = atomics::detail::bitwise_fp_cast< value_type >(old_value); + return res; + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected); + const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order); + expected = atomics::detail::bitwise_fp_cast< value_type >(old_value); + return res; + } +}; + +#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT) + + +//! Implementation for pointers to object types +template< typename T > +class base_atomic< T*, void* > +{ +public: + typedef T* value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef atomics::detail::operations< storage_size_of< value_type >::value, false > operations; + typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef value_type value_arg_type; + +public: + typedef typename operations::storage_type storage_type; + +private: + typedef atomics::detail::integral_constant< bool, sizeof(value_type) == sizeof(storage_type) > value_matches_storage; + + // uintptr_storage_type is the minimal storage type that is enough to store pointers. The actual storage_type theoretically may be larger, + // if the target architecture only supports atomic ops on larger data. Typically, though, they are the same type. +#if defined(BOOST_HAS_INTPTR_T) + typedef uintptr_t uintptr_storage_type; +#else + typedef typename atomics::detail::make_storage_type< sizeof(value_type) >::type uintptr_storage_type; +#endif + +protected: + typename operations::aligned_storage_type m_storage; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {}) + BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : m_storage(atomics::detail::bitwise_cast< uintptr_storage_type >(v)) + { + } + + // Standard methods + BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_consume); + BOOST_ASSERT(order != memory_order_acquire); + BOOST_ASSERT(order != memory_order_acq_rel); + + operations::store(m_storage.value, atomics::detail::bitwise_cast< uintptr_storage_type >(v), order); + } + + BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(order != memory_order_release); + BOOST_ASSERT(order != memory_order_acq_rel); + + return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::load(m_storage.value, order))); + } + + BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_add(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order))); + } + + BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_sub(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order))); + } + + BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::exchange(m_storage.value, atomics::detail::bitwise_cast< uintptr_storage_type >(v), order))); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT + { + BOOST_ASSERT(failure_order != memory_order_release); + BOOST_ASSERT(failure_order != memory_order_acq_rel); + BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order)); + + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, value_matches_storage()); + } + + BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order)); + } + + // Boost.Atomic extensions + BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::add(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order))); + } + + BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::sub(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order))); + } + + BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_add(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order); + } + + BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + extra_operations::opaque_sub(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order); + } + + BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST + BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::add_and_test(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order); + } + + BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST + BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return extra_operations::sub_and_test(m_storage.value, static_cast< uintptr_storage_type >(v * sizeof(T)), order); + } + + // Operators + BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT + { + return fetch_add(1); + } + + BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT + { + return add(1); + } + + BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT + { + return fetch_sub(1); + } + + BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT + { + return sub(1); + } + + BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT + { + return add(v); + } + + BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT + { + return sub(v); + } + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_strong(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected); + const bool res = operations::compare_exchange_strong(m_storage.value, old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order); + expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value)); + return res; + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS) + return operations::compare_exchange_weak(m_storage.value, reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order); +#else + return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::false_type()); +#endif + } + + BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT + { + storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected); + const bool res = operations::compare_exchange_weak(m_storage.value, old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order); + expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value)); + return res; + } +}; + +} // namespace detail + +template< typename T > +class atomic : + public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type > +{ +private: + typedef atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type > base_type; + typedef typename base_type::value_arg_type value_arg_type; + +public: + typedef typename base_type::value_type value_type; + typedef typename base_type::storage_type storage_type; + +public: + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = base_type::operations::is_always_lock_free; + +public: + BOOST_DEFAULTED_FUNCTION(atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v) {} + + BOOST_FORCEINLINE value_type operator= (value_arg_type v) BOOST_NOEXCEPT + { + this->store(v); + return v; + } + + BOOST_FORCEINLINE value_type operator= (value_arg_type v) volatile BOOST_NOEXCEPT + { + this->store(v); + return v; + } + + BOOST_FORCEINLINE operator value_type() const volatile BOOST_NOEXCEPT + { + return this->load(); + } + + BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT + { + // C++17 requires all instances of atomic<> return a value consistent with is_always_lock_free here + return is_always_lock_free; + } + + BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return this->m_storage.value; } + BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return this->m_storage.value; } + BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return this->m_storage.value; } + BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return this->m_storage.value; } + + BOOST_DELETED_FUNCTION(atomic(atomic const&)) + BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&)) + BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&) volatile) +}; + +template< typename T > +BOOST_CONSTEXPR_OR_CONST bool atomic< T >::is_always_lock_free; + +#undef BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL +#undef BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL + +typedef atomic< char > atomic_char; +typedef atomic< unsigned char > atomic_uchar; +typedef atomic< signed char > atomic_schar; +typedef atomic< uint8_t > atomic_uint8_t; +typedef atomic< int8_t > atomic_int8_t; +typedef atomic< unsigned short > atomic_ushort; +typedef atomic< short > atomic_short; +typedef atomic< uint16_t > atomic_uint16_t; +typedef atomic< int16_t > atomic_int16_t; +typedef atomic< unsigned int > atomic_uint; +typedef atomic< int > atomic_int; +typedef atomic< uint32_t > atomic_uint32_t; +typedef atomic< int32_t > atomic_int32_t; +typedef atomic< unsigned long > atomic_ulong; +typedef atomic< long > atomic_long; +typedef atomic< uint64_t > atomic_uint64_t; +typedef atomic< int64_t > atomic_int64_t; +#ifdef BOOST_HAS_LONG_LONG +typedef atomic< boost::ulong_long_type > atomic_ullong; +typedef atomic< boost::long_long_type > atomic_llong; +#endif +typedef atomic< void* > atomic_address; +typedef atomic< bool > atomic_bool; +typedef atomic< wchar_t > atomic_wchar_t; +#if !defined(BOOST_NO_CXX11_CHAR16_T) +typedef atomic< char16_t > atomic_char16_t; +#endif +#if !defined(BOOST_NO_CXX11_CHAR32_T) +typedef atomic< char32_t > atomic_char32_t; +#endif + +typedef atomic< int_least8_t > atomic_int_least8_t; +typedef atomic< uint_least8_t > atomic_uint_least8_t; +typedef atomic< int_least16_t > atomic_int_least16_t; +typedef atomic< uint_least16_t > atomic_uint_least16_t; +typedef atomic< int_least32_t > atomic_int_least32_t; +typedef atomic< uint_least32_t > atomic_uint_least32_t; +typedef atomic< int_least64_t > atomic_int_least64_t; +typedef atomic< uint_least64_t > atomic_uint_least64_t; +typedef atomic< int_fast8_t > atomic_int_fast8_t; +typedef atomic< uint_fast8_t > atomic_uint_fast8_t; +typedef atomic< int_fast16_t > atomic_int_fast16_t; +typedef atomic< uint_fast16_t > atomic_uint_fast16_t; +typedef atomic< int_fast32_t > atomic_int_fast32_t; +typedef atomic< uint_fast32_t > atomic_uint_fast32_t; +typedef atomic< int_fast64_t > atomic_int_fast64_t; +typedef atomic< uint_fast64_t > atomic_uint_fast64_t; +typedef atomic< intmax_t > atomic_intmax_t; +typedef atomic< uintmax_t > atomic_uintmax_t; + +#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) +typedef atomic< float > atomic_float_t; +typedef atomic< double > atomic_double_t; +typedef atomic< long double > atomic_long_double_t; +#endif + +typedef atomic< std::size_t > atomic_size_t; +typedef atomic< std::ptrdiff_t > atomic_ptrdiff_t; + +#if defined(BOOST_HAS_INTPTR_T) +typedef atomic< intptr_t > atomic_intptr_t; +typedef atomic< uintptr_t > atomic_uintptr_t; +#endif + +} // namespace atomics +} // namespace boost + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif // BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_ diff --git a/boost/atomic/detail/bitwise_cast.hpp b/boost/atomic/detail/bitwise_cast.hpp new file mode 100644 index 00000000..10d165e7 --- /dev/null +++ b/boost/atomic/detail/bitwise_cast.hpp @@ -0,0 +1,68 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2013 - 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/bitwise_cast.hpp + * + * This header defines \c bitwise_cast used to convert between storage and value types + */ + +#ifndef BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_ + +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< std::size_t FromSize, typename To > +BOOST_FORCEINLINE void clear_padding(To& to, atomics::detail::true_type) BOOST_NOEXCEPT +{ + BOOST_ATOMIC_DETAIL_MEMSET(reinterpret_cast< unsigned char* >(atomics::detail::addressof(to)) + FromSize, 0, sizeof(To) - FromSize); +} + +template< std::size_t FromSize, typename To > +BOOST_FORCEINLINE void clear_padding(To&, atomics::detail::false_type) BOOST_NOEXCEPT +{ +} + +template< typename To, std::size_t FromSize, typename From > +BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT +{ + To to; + BOOST_ATOMIC_DETAIL_MEMCPY + ( + atomics::detail::addressof(to), + atomics::detail::addressof(from), + (FromSize < sizeof(To) ? FromSize : sizeof(To)) + ); + atomics::detail::clear_padding< FromSize >(to, atomics::detail::integral_constant< bool, FromSize < sizeof(To) >()); + return to; +} + +template< typename To, typename From > +BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT +{ + return atomics::detail::bitwise_cast< To, sizeof(From) >(from); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_ diff --git a/boost/atomic/detail/bitwise_fp_cast.hpp b/boost/atomic/detail/bitwise_fp_cast.hpp new file mode 100644 index 00000000..a74b20b9 --- /dev/null +++ b/boost/atomic/detail/bitwise_fp_cast.hpp @@ -0,0 +1,86 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/bitwise_fp_cast.hpp + * + * This header defines \c bitwise_fp_cast used to convert between storage and floating point value types + */ + +#ifndef BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_ + +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +/*! + * \brief The type trait returns the size of the value of the specified floating point type + * + * This size may be less than sizeof(T) if the implementation uses padding bytes for a particular FP type. This is + * often the case with 80-bit extended double, which is stored in 12 or 16 bytes with padding filled with garbage. + */ +template< typename T > +struct value_sizeof +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t value = sizeof(T); +}; + +#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE) +template< > +struct value_sizeof< float > +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE; +}; +#endif + +#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE) +template< > +struct value_sizeof< double > +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE; +}; +#endif + +#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE) +template< > +struct value_sizeof< long double > +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE; +}; +#endif + +template< typename T > +struct value_sizeof< const T > : value_sizeof< T > {}; + +template< typename T > +struct value_sizeof< volatile T > : value_sizeof< T > {}; + +template< typename T > +struct value_sizeof< const volatile T > : value_sizeof< T > {}; + + +template< typename To, typename From > +BOOST_FORCEINLINE To bitwise_fp_cast(From const& from) BOOST_NOEXCEPT +{ + return atomics::detail::bitwise_cast< To, atomics::detail::value_sizeof< From >::value >(from); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_gcc_alpha.hpp b/boost/atomic/detail/caps_gcc_alpha.hpp new file mode 100644 index 00000000..861432f5 --- /dev/null +++ b/boost/atomic/detail/caps_gcc_alpha.hpp @@ -0,0 +1,34 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_gcc_alpha.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_gcc_arm.hpp b/boost/atomic/detail/caps_gcc_arm.hpp new file mode 100644 index 00000000..a26ea56e --- /dev/null +++ b/boost/atomic/detail/caps_gcc_arm.hpp @@ -0,0 +1,39 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2009 Phil Endecott + * Copyright (c) 2013 Tim Blechmann + * ARM Code by Phil Endecott, based on other architectures. + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_gcc_arm.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#endif +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_gcc_atomic.hpp b/boost/atomic/detail/caps_gcc_atomic.hpp new file mode 100644 index 00000000..3b518cf4 --- /dev/null +++ b/boost/atomic/detail/caps_gcc_atomic.hpp @@ -0,0 +1,133 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_gcc_atomic.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_ + +#include +#include +#if defined(__i386__) || defined(__x86_64__) +#include +#elif defined(__arm__) +#include +#elif defined(__POWERPC__) || defined(__PPC__) +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 +#else +#define BOOST_ATOMIC_INT128_LOCK_FREE 0 +#endif + +#if (__GCC_ATOMIC_LLONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8) +#define BOOST_ATOMIC_LLONG_LOCK_FREE 2 +#else +#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE +#endif + +#if (__GCC_ATOMIC_LONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8) +#define BOOST_ATOMIC_LONG_LOCK_FREE 2 +#else +#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE +#endif + +#if __GCC_ATOMIC_INT_LOCK_FREE == 2 +#define BOOST_ATOMIC_INT_LOCK_FREE 2 +#else +#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE +#endif + +#if __GCC_ATOMIC_SHORT_LOCK_FREE == 2 +#define BOOST_ATOMIC_SHORT_LOCK_FREE 2 +#else +#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE +#endif + +#if __GCC_ATOMIC_CHAR_LOCK_FREE == 2 +#define BOOST_ATOMIC_CHAR_LOCK_FREE 2 +#else +#define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE +#endif + +#if __GCC_ATOMIC_POINTER_LOCK_FREE == 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 +#else +#define BOOST_ATOMIC_POINTER_LOCK_FREE 0 +#endif + + +#define BOOST_ATOMIC_INT8_LOCK_FREE BOOST_ATOMIC_CHAR_LOCK_FREE + +#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE +#else +#define BOOST_ATOMIC_INT16_LOCK_FREE 0 +#endif + +#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4 +#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4 +#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4 +#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4 +#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE +#else +#define BOOST_ATOMIC_INT32_LOCK_FREE 0 +#endif + +#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8 +#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8 +#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8 +#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8 +#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE +#else +#define BOOST_ATOMIC_INT64_LOCK_FREE 0 +#endif + + +#if __GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2 +#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE +#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE +#else +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0 +#endif + +#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE +#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_gcc_ppc.hpp b/boost/atomic/detail/caps_gcc_ppc.hpp new file mode 100644 index 00000000..3e20fdee --- /dev/null +++ b/boost/atomic/detail/caps_gcc_ppc.hpp @@ -0,0 +1,37 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_gcc_ppc.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX) +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#endif +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_gcc_sparc.hpp b/boost/atomic/detail/caps_gcc_sparc.hpp new file mode 100644 index 00000000..58066849 --- /dev/null +++ b/boost/atomic/detail/caps_gcc_sparc.hpp @@ -0,0 +1,34 @@ +/* + * 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) + * + * Copyright (c) 2010 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_gcc_sparc.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_gcc_sync.hpp b/boost/atomic/detail/caps_gcc_sync.hpp new file mode 100644 index 00000000..ffbe605a --- /dev/null +++ b/boost/atomic/detail/caps_gcc_sync.hpp @@ -0,0 +1,61 @@ +/* + * 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) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_gcc_sync.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_ + +#include +#if defined(__i386__) || defined(__x86_64__) +#include +#elif defined(__arm__) +#include +#elif defined(__POWERPC__) || defined(__PPC__) +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#endif +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#endif +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#endif +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\ + || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#endif +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 +#endif + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_gcc_x86.hpp b/boost/atomic/detail/caps_gcc_x86.hpp new file mode 100644 index 00000000..70c64628 --- /dev/null +++ b/boost/atomic/detail/caps_gcc_x86.hpp @@ -0,0 +1,40 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2013 - 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_gcc_x86.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#if defined(__x86_64__) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#endif +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 +#endif +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_linux_arm.hpp b/boost/atomic/detail/caps_linux_arm.hpp new file mode 100644 index 00000000..abe6fb81 --- /dev/null +++ b/boost/atomic/detail/caps_linux_arm.hpp @@ -0,0 +1,35 @@ +/* + * 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) + * + * Copyright (c) 2009, 2011 Helge Bahmann + * Copyright (c) 2009 Phil Endecott + * Copyright (c) 2013 Tim Blechmann + * Linux-specific code by Phil Endecott + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_linux_arm.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_msvc_arm.hpp b/boost/atomic/detail/caps_msvc_arm.hpp new file mode 100644 index 00000000..6b3c61fb --- /dev/null +++ b/boost/atomic/detail/caps_msvc_arm.hpp @@ -0,0 +1,34 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2012 - 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_msvc_arm.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_msvc_x86.hpp b/boost/atomic/detail/caps_msvc_x86.hpp new file mode 100644 index 00000000..2ee4c921 --- /dev/null +++ b/boost/atomic/detail/caps_msvc_x86.hpp @@ -0,0 +1,55 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2012 - 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_msvc_x86.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(_M_IX86) && _M_IX86 >= 500 +#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1 +#endif + +#if _MSC_VER >= 1500 && defined(_M_AMD64) && !defined(BOOST_ATOMIC_NO_CMPXCHG16B) +#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 +#endif + +#if defined(_MSC_VER) && (defined(_M_AMD64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2)) +// Use mfence only if SSE2 is available +#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1 +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 + +#if defined(_M_AMD64) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) +#define BOOST_ATOMIC_INT64_LOCK_FREE 2 +#endif + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 +#endif + +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_ diff --git a/boost/atomic/detail/caps_windows.hpp b/boost/atomic/detail/caps_windows.hpp new file mode 100644 index 00000000..1cc0ded8 --- /dev/null +++ b/boost/atomic/detail/caps_windows.hpp @@ -0,0 +1,33 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2012 - 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/caps_windows.hpp + * + * This header defines feature capabilities macros + */ + +#ifndef BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_INT8_LOCK_FREE 2 +#define BOOST_ATOMIC_INT16_LOCK_FREE 2 +#define BOOST_ATOMIC_INT32_LOCK_FREE 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 + +#define BOOST_ATOMIC_THREAD_FENCE 2 +#define BOOST_ATOMIC_SIGNAL_FENCE 2 + +#endif // BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/config.hpp b/boost/atomic/detail/config.hpp new file mode 100644 index 00000000..d2a6afd2 --- /dev/null +++ b/boost/atomic/detail/config.hpp @@ -0,0 +1,150 @@ +/* + * 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) + * + * Copyright (c) 2012 Hartmut Kaiser + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/config.hpp + * + * This header defines configuraion macros for Boost.Atomic + */ + +#ifndef BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__CUDACC__) +// nvcc does not support alternatives ("q,m") in asm statement constraints +#define BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES +// nvcc does not support condition code register ("cc") clobber in asm statements +#define BOOST_ATOMIC_DETAIL_NO_ASM_CLOBBER_CC +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CLOBBER_CC) +#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC "cc" +#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "cc", +#else +#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC +#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA +#endif + +#if (defined(__i386__) || defined(__x86_64__)) && (defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40500) || defined(__SUNPRO_CC)) +// This macro indicates that the compiler does not support allocating eax:edx or rax:rdx register pairs ("A") in asm blocks +#define BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS +#endif + +#if defined(__i386__) && (defined(__PIC__) || defined(__PIE__)) && !(defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) >= 50100)) +// This macro indicates that asm blocks should preserve ebx value unchanged. Some compilers are able to maintain ebx themselves +// around the asm blocks. For those compilers we don't need to save/restore ebx in asm blocks. +#define BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX +#endif + +#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +#if !(defined(BOOST_LIBSTDCXX11) && (BOOST_LIBSTDCXX_VERSION+0) >= 40700) /* libstdc++ from gcc >= 4.7 in C++11 mode */ +// This macro indicates that there is not even a basic standard header that is sufficient for most Boost.Atomic needs. +#define BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS +#endif +#endif // defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + +// Enable pointer/reference casts between storage and value when possible. +// Note: Despite that MSVC does not employ strict aliasing rules for optimizations +// and does not require an explicit markup for types that may alias, we still don't +// enable the optimization for this compiler because at least MSVC-8 and 9 are known +// to generate broken code sometimes when casts are used. +#define BOOST_ATOMIC_DETAIL_MAY_ALIAS BOOST_MAY_ALIAS +#if !defined(BOOST_NO_MAY_ALIAS) +#define BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS +#endif + +#if defined(__GCC_ASM_FLAG_OUTPUTS__) +// The compiler supports output values in flag registers. +// See: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html, Section 6.44.3. +#define BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS +#endif + +#if defined(__has_builtin) +#if __has_builtin(__builtin_constant_p) +#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x) +#endif +#elif defined(__GNUC__) +#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x) +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_IS_CONSTANT) +#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) false +#endif + +#if (defined(__BYTE_ORDER__) && defined(__FLOAT_WORD_ORDER__) && (__BYTE_ORDER__+0) == (__FLOAT_WORD_ORDER__+0)) ||\ + defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) +// This macro indicates that integer and floating point endianness is the same +#define BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH +#endif + +// Deprecated symbols markup +#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(_MSC_VER) +#if (_MSC_VER) >= 1400 +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __declspec(deprecated(msg)) +#else +// MSVC 7.1 only supports the attribute without a message +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __declspec(deprecated) +#endif +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__has_extension) +#if __has_extension(attribute_deprecated_with_message) +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif +#endif + +// gcc since 4.5 supports deprecated attribute with a message; older versions support the attribute without a message. +// Oracle Studio 12.4 supports deprecated attribute with a message; this is the first release that supports the attribute. +#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && (\ + (defined(__GNUC__) && ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0)) >= 405) ||\ + (defined(__SUNPRO_CC) && (__SUNPRO_CC + 0) >= 0x5130)) +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && __cplusplus >= 201402 +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) [[deprecated(msg)]] +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__GNUC__) +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated)) +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__has_attribute) +#if __has_attribute(deprecated) +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated)) +#endif +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) +#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) +#endif + +// In Boost.Atomic 1.67 we changed (op)_and_test methods to return true when the result is non-zero. This would be more consistent +// with the other names used in Boost.Atomic and the C++ standard library. Since the methods were announced as experimental and +// the previous behavior was released only in Boost 1.66, it was decided to change the result without changing the method names. +// By defining BOOST_ATOMIC_HIGHLIGHT_OP_AND_TEST the user has a way to highlight all uses of the affected functions so +// that it is easier to find and update the affected code (which is typically adding or removing negation of the result). This +// highlighting functionality is a temporary measure to help users upgrade from Boost 1.66 to newer Boost versions. It will +// be removed eventually. +// +// More info at: +// https://github.com/boostorg/atomic/issues/11 +// http://boost.2283326.n4.nabble.com/atomic-op-and-test-naming-tc4701445.html +#if defined(BOOST_ATOMIC_HIGHLIGHT_OP_AND_TEST) +#define BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST BOOST_ATOMIC_DETAIL_DEPRECATED("Boost.Atomic 1.67 has changed (op)_and_test result to the opposite. The functions now return true when the result is non-zero. Please, verify your use of the operation and undefine BOOST_ATOMIC_HIGHLIGHT_OP_AND_TEST.") +#else +#define BOOST_ATOMIC_DETAIL_HIGHLIGHT_OP_AND_TEST +#endif + +#endif // BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_fp_operations.hpp b/boost/atomic/detail/extra_fp_operations.hpp new file mode 100644 index 00000000..854d8c9b --- /dev/null +++ b/boost/atomic/detail/extra_fp_operations.hpp @@ -0,0 +1,28 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_fp_operations.hpp + * + * This header defines extra floating point atomic operations, including the generic version. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_ + +#include +#include + +#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_GENERIC) +#include BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_HEADER(boost/atomic/detail/extra_fp_ops_) +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_fp_operations_fwd.hpp b/boost/atomic/detail/extra_fp_operations_fwd.hpp new file mode 100644 index 00000000..79bca9d2 --- /dev/null +++ b/boost/atomic/detail/extra_fp_operations_fwd.hpp @@ -0,0 +1,35 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_fp_operations_fwd.hpp + * + * This header contains forward declaration of the \c extra_fp_operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base, typename Value, std::size_t Size, bool = Base::is_always_lock_free > +struct extra_fp_operations; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_fp_ops_emulated.hpp b/boost/atomic/detail/extra_fp_ops_emulated.hpp new file mode 100644 index 00000000..e04b2f50 --- /dev/null +++ b/boost/atomic/detail/extra_fp_ops_emulated.hpp @@ -0,0 +1,107 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_fp_ops_emulated.hpp + * + * This header contains emulated (lock-based) implementation of the extra floating point atomic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +//! Generic implementation of extra floating point operations +template< typename Base, typename Value, std::size_t Size > +struct emulated_extra_fp_operations : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + typedef Value value_type; + + static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); + value_type new_val = -old_val; + s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + return old_val; + } + + static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); + value_type new_val = -old_val; + s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + return new_val; + } + + static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); + value_type new_val = old_val + v; + s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + return new_val; + } + + static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); + value_type new_val = old_val - v; + s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + return new_val; + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_negate(storage, order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_add(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_sub(storage, v, order); + } +}; + +template< typename Base, typename Value, std::size_t Size > +struct extra_fp_operations< Base, Value, Size, false > : + public emulated_extra_fp_operations< Base, Value, Size > +{ +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_fp_ops_generic.hpp b/boost/atomic/detail/extra_fp_ops_generic.hpp new file mode 100644 index 00000000..34902c47 --- /dev/null +++ b/boost/atomic/detail/extra_fp_ops_generic.hpp @@ -0,0 +1,189 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_fp_ops_generic.hpp + * + * This header contains generic implementation of the extra floating point atomic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 60000 +#pragma GCC diagnostic push +// ignoring attributes on template argument X - this warning is because we need to pass storage_type as a template argument; no problem in this case +#pragma GCC diagnostic ignored "-Wignored-attributes" +#endif + +namespace boost { +namespace atomics { +namespace detail { + +//! Negate implementation +template< + typename Base, + typename Value, + std::size_t Size +#if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH) + , bool = atomics::detail::is_iec559< Value >::value && atomics::detail::is_integral< typename Base::storage_type >::value +#endif +> +struct generic_extra_fp_negate : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + typedef Value value_type; + + static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type old_storage, new_storage; + value_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_storage); + do + { + old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage); + new_val = -old_val; + new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + } + while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed)); + return old_val; + } + + static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type old_storage, new_storage; + value_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_storage); + do + { + old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage); + new_val = -old_val; + new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + } + while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_negate(storage, order); + } +}; + +#if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH) + +//! Negate implementation for IEEE 754 / IEC 559 floating point types. We leverage the fact that the sign bit is the most significant bit in the value. +template< typename Base, typename Value, std::size_t Size > +struct generic_extra_fp_negate< Base, Value, Size, true > : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + typedef Value value_type; + + //! The mask with only one sign bit set to 1 + static BOOST_CONSTEXPR_OR_CONST storage_type sign_mask = static_cast< storage_type >(1u) << (atomics::detail::value_sizeof< value_type >::value * 8u - 1u); + + static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return atomics::detail::bitwise_fp_cast< value_type >(base_type::fetch_xor(storage, sign_mask, order)); + } + + static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return atomics::detail::bitwise_fp_cast< value_type >(base_type::bitwise_xor(storage, sign_mask, order)); + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::opaque_xor(storage, sign_mask, order); + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH) + +//! Generic implementation of floating point operations +template< typename Base, typename Value, std::size_t Size > +struct generic_extra_fp_operations : + public generic_extra_fp_negate< Base, Value, Size > +{ + typedef generic_extra_fp_negate< Base, Value, Size > base_type; + typedef typename base_type::storage_type storage_type; + typedef Value value_type; + + static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_storage, new_storage; + value_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_storage); + do + { + old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage); + new_val = old_val + v; + new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + } + while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_storage, new_storage; + value_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_storage); + do + { + old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage); + new_val = old_val - v; + new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + } + while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_add(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_sub(storage, v, order); + } +}; + +// Default extra_fp_operations template definition will be used unless specialized for a specific platform +template< typename Base, typename Value, std::size_t Size > +struct extra_fp_operations< Base, Value, Size, true > : + public generic_extra_fp_operations< Base, Value, Size > +{ +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 60000 +#pragma GCC diagnostic pop +#endif + +#endif // BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_operations.hpp b/boost/atomic/detail/extra_operations.hpp new file mode 100644 index 00000000..c04f55cd --- /dev/null +++ b/boost/atomic/detail/extra_operations.hpp @@ -0,0 +1,28 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_operations.hpp + * + * This header defines extra atomic operations, including the generic version. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_ + +#include +#include + +#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_GENERIC) +#include BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_HEADER(boost/atomic/detail/extra_ops_) +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_operations_fwd.hpp b/boost/atomic/detail/extra_operations_fwd.hpp new file mode 100644 index 00000000..399a8233 --- /dev/null +++ b/boost/atomic/detail/extra_operations_fwd.hpp @@ -0,0 +1,35 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_operations_fwd.hpp + * + * This header contains forward declaration of the \c extra_operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base, std::size_t Size, bool Signed, bool = Base::is_always_lock_free > +struct extra_operations; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_ops_emulated.hpp b/boost/atomic/detail/extra_ops_emulated.hpp new file mode 100644 index 00000000..c0e48329 --- /dev/null +++ b/boost/atomic/detail/extra_ops_emulated.hpp @@ -0,0 +1,238 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_ops_emulated.hpp + * + * This header contains emulated (lock-based) implementation of the extra atomic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +// unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable: 4146) +#endif + +namespace boost { +namespace atomics { +namespace detail { + +//! Generic implementation of extra operations +template< typename Base, std::size_t Size, bool Signed > +struct emulated_extra_operations : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s = static_cast< storage_type >(-old_val); + return old_val; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type new_val = static_cast< storage_type >(-s); + s = new_val; + return new_val; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type new_val = s; + new_val += v; + s = new_val; + return new_val; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type new_val = s; + new_val -= v; + s = new_val; + return new_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type new_val = s; + new_val &= v; + s = new_val; + return new_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type new_val = s; + new_val |= v; + s = new_val; + return new_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type new_val = s; + new_val ^= v; + s = new_val; + return new_val; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s = static_cast< storage_type >(~old_val); + return old_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type new_val = static_cast< storage_type >(~s); + s = new_val; + return new_val; + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + Base::fetch_add(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + Base::fetch_sub(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_negate(storage, order); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + Base::fetch_and(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + Base::fetch_or(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + Base::fetch_xor(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_complement(storage, order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!add(storage, v, order); + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!sub(storage, v, order); + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!negate(storage, order); + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_and(storage, v, order); + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_or(storage, v, order); + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_xor(storage, v, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_complement(storage, order); + } + + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number); + storage_type old_val = Base::fetch_or(storage, mask, order); + return !!(old_val & mask); + } + + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number); + storage_type old_val = Base::fetch_and(storage, ~mask, order); + return !!(old_val & mask); + } + + static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number); + storage_type old_val = Base::fetch_xor(storage, mask, order); + return !!(old_val & mask); + } +}; + +template< typename Base, std::size_t Size, bool Signed > +struct extra_operations< Base, Size, Signed, false > : + public emulated_extra_operations< Base, Size, Signed > +{ +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_ops_gcc_arm.hpp b/boost/atomic/detail/extra_ops_gcc_arm.hpp new file mode 100644 index 00000000..e84f1771 --- /dev/null +++ b/boost/atomic/detail/extra_ops_gcc_arm.hpp @@ -0,0 +1,1111 @@ +/* + * 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) + * + * Copyright (c) 2017 - 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_ops_gcc_arm.hpp + * + * This header contains implementation of the extra atomic operations for ARM. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base > +struct gcc_arm_extra_operations_common : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_negate(storage, order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_complement(storage, order); + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::negate(storage, order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::add(storage, v, order); + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::sub(storage, v, order); + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_and(storage, v, order); + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_or(storage, v, order); + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_xor(storage, v, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_complement(storage, order); + } +}; + +template< typename Base, std::size_t Size, bool Signed > +struct gcc_arm_extra_operations; + +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB) + +template< typename Base, bool Signed > +struct gcc_arm_extra_operations< Base, 1u, Signed > : + public generic_extra_operations< Base, 1u, Signed > +{ + typedef generic_extra_operations< Base, 1u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 4u >::type extended_storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "rsb %[result], %[original], #0\n" // result = 0 - original + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "rsb %[result], %[original], #0\n" // result = 0 - original + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "add %[result], %[original], %[value]\n" // result = original + value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "sub %[result], %[original], %[value]\n" // result = original - value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "and %[result], %[original], %[value]\n" // result = original & value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "orr %[result], %[original], %[value]\n" // result = original | value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "eor %[result], %[original], %[value]\n" // result = original ^ value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "mvn %[result], %[original]\n" // result = NOT original + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "mvn %[result], %[original]\n" // result = NOT original + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 1u, Signed, true > : + public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 1u, Signed > > +{ +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB) + +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH) + +template< typename Base, bool Signed > +struct gcc_arm_extra_operations< Base, 2u, Signed > : + public generic_extra_operations< Base, 2u, Signed > +{ + typedef generic_extra_operations< Base, 2u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 4u >::type extended_storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "rsb %[result], %[original], #0\n" // result = 0 - original + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "rsb %[result], %[original], #0\n" // result = 0 - original + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "add %[result], %[original], %[value]\n" // result = original + value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "sub %[result], %[original], %[value]\n" // result = original - value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "and %[result], %[original], %[value]\n" // result = original & value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "orr %[result], %[original], %[value]\n" // result = original | value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "eor %[result], %[original], %[value]\n" // result = original ^ value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "mvn %[result], %[original]\n" // result = NOT original + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "mvn %[result], %[original]\n" // result = NOT original + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return static_cast< storage_type >(result); + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 2u, Signed, true > : + public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 2u, Signed > > +{ +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH) + +template< typename Base, bool Signed > +struct gcc_arm_extra_operations< Base, 4u, Signed > : + public generic_extra_operations< Base, 4u, Signed > +{ + typedef generic_extra_operations< Base, 4u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "rsb %[result], %[original], #0\n" // result = 0 - original + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "rsb %[result], %[original], #0\n" // result = 0 - original + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "add %[result], %[original], %[value]\n" // result = original + value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "sub %[result], %[original], %[value]\n" // result = original - value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "and %[result], %[original], %[value]\n" // result = original & value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "orr %[result], %[original], %[value]\n" // result = original | value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "eor %[result], %[original], %[value]\n" // result = original ^ value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "mvn %[result], %[original]\n" // result = NOT original + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "mvn %[result], %[original]\n" // result = NOT original + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_arm_operations_base::fence_after(order); + return result; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 4u, Signed, true > : + public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 4u, Signed > > +{ +}; + +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) + +template< typename Base, bool Signed > +struct gcc_arm_extra_operations< Base, 8u, Signed > : + public generic_extra_operations< Base, 8u, Signed > +{ + typedef generic_extra_operations< Base, 8u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "mvn %2, %1\n" // result = NOT original + "mvn %H2, %H1\n" + "adds %2, %2, #1\n" // result = result + 1 + "adc %H2, %H2, #0\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "mvn %2, %1\n" // result = NOT original + "mvn %H2, %H1\n" + "adds %2, %2, #1\n" // result = result + 1 + "adc %H2, %H2, #0\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "adds %2, %1, %4\n" // result = original + value + "adc %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "subs %2, %1, %4\n" // result = original - value + "sbc %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "and %2, %1, %4\n" // result = original & value + "and %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "orr %2, %1, %4\n" // result = original | value + "orr %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "eor %2, %1, %4\n" // result = original ^ value + "eor %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "mvn %2, %1\n" // result = NOT original + "mvn %H2, %H1\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_arm_operations_base::fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "mvn %2, %1\n" // result = NOT original + "mvn %H2, %H1\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + gcc_arm_operations_base::fence_after(order); + return result; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 8u, Signed, true > : + public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 8u, Signed > > +{ +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_ops_gcc_ppc.hpp b/boost/atomic/detail/extra_ops_gcc_ppc.hpp new file mode 100644 index 00000000..dc4bbdbf --- /dev/null +++ b/boost/atomic/detail/extra_ops_gcc_ppc.hpp @@ -0,0 +1,840 @@ +/* + * 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) + * + * Copyright (c) 2017 - 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_ops_gcc_ppc.hpp + * + * This header contains implementation of the extra atomic operations for PowerPC. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base > +struct gcc_ppc_extra_operations_common : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_negate(storage, order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_complement(storage, order); + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::negate(storage, order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::add(storage, v, order); + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::sub(storage, v, order); + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_and(storage, v, order); + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_or(storage, v, order); + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_xor(storage, v, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!base_type::bitwise_complement(storage, order); + } +}; + +template< typename Base, std::size_t Size, bool Signed > +struct gcc_ppc_extra_operations; + +#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX) + +template< typename Base, bool Signed > +struct gcc_ppc_extra_operations< Base, 1u, Signed > : + public generic_extra_operations< Base, 1u, Signed > +{ + typedef generic_extra_operations< Base, 1u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "neg %1,%0\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "neg %1,%0\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 1u, Signed, true > : + public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 1u, Signed > > +{ +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX) + +#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX) + +template< typename Base, bool Signed > +struct gcc_ppc_extra_operations< Base, 2u, Signed > : + public generic_extra_operations< Base, 2u, Signed > +{ + typedef generic_extra_operations< Base, 2u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "neg %1,%0\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "neg %1,%0\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX) + +template< typename Base, bool Signed > +struct gcc_ppc_extra_operations< Base, 4u, Signed > : + public generic_extra_operations< Base, 4u, Signed > +{ + typedef generic_extra_operations< Base, 4u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "neg %1,%0\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "neg %1,%0\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 4u, Signed, true > : + public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 4u, Signed > > +{ +}; + +#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX) + +template< typename Base, bool Signed > +struct gcc_ppc_extra_operations< Base, 8u, Signed > : + public generic_extra_operations< Base, 8u, Signed > +{ + typedef generic_extra_operations< Base, 8u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "neg %1,%0\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "neg %1,%0\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + gcc_ppc_operations_base::fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + gcc_ppc_operations_base::fence_before(order); + storage_type original, result; + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "nor %1,%0,%0\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + gcc_ppc_operations_base::fence_after(order); + return result; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 8u, Signed, true > : + public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 8u, Signed > > +{ +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX) + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_PPC_INCLUDED_ diff --git a/boost/atomic/detail/extra_ops_gcc_x86.hpp b/boost/atomic/detail/extra_ops_gcc_x86.hpp new file mode 100644 index 00000000..ee2cd02a --- /dev/null +++ b/boost/atomic/detail/extra_ops_gcc_x86.hpp @@ -0,0 +1,1656 @@ +/* + * 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) + * + * Copyright (c) 2015 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_ops_gcc_x86.hpp + * + * This header contains implementation of the extra atomic operations for x86. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base > +struct gcc_x86_extra_operations_common : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(Base::fetch_add(storage, v, order) + v); + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(Base::fetch_sub(storage, v, order) - v); + } + + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; bts %[bit_number], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccc" (res) + : [bit_number] "Kq" (bit_number) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; bts %[bit_number], %[storage]\n\t" + "setc %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [bit_number] "Kq" (bit_number) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; btr %[bit_number], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccc" (res) + : [bit_number] "Kq" (bit_number) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; btr %[bit_number], %[storage]\n\t" + "setc %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [bit_number] "Kq" (bit_number) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; btc %[bit_number], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccc" (res) + : [bit_number] "Kq" (bit_number) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; btc %[bit_number], %[storage]\n\t" + "setc %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [bit_number] "Kq" (bit_number) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 1u, Signed, true > : + public gcc_x86_extra_operations_common< Base > +{ + typedef gcc_x86_extra_operations_common< Base > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 4u >::type temp_storage_type; + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: movzbl %[orig], %2\n\t"\ + op " %b2\n\t"\ + "lock; cmpxchgb %b2, %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\ + : \ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", original, result); + return static_cast< storage_type >(result); + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[arg], %2\n\t"\ + op " %%al, %b2\n\t"\ + "lock; cmpxchgb %b2, %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\ + : [arg] "ir" ((temp_storage_type)argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andb", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orb", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorb", v, original, result); + return static_cast< storage_type >(result); + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!negate(storage, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_complement(storage, order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incb %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addb %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decb %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subb %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; negb %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; andb %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; orb %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xorb %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; notb %[storage]\n\t" + : [storage] "+m" (storage) + : + : "memory" + ); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incb %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addb %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incb %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addb %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decb %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subb %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decb %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subb %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; andb %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; andb %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; orb %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; orb %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; xorb %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; xorb %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 2u, Signed, true > : + public gcc_x86_extra_operations_common< Base > +{ + typedef gcc_x86_extra_operations_common< Base > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 4u >::type temp_storage_type; + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: movzwl %[orig], %2\n\t"\ + op " %w2\n\t"\ + "lock; cmpxchgw %w2, %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\ + : \ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", original, result); + return static_cast< storage_type >(result); + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[arg], %2\n\t"\ + op " %%ax, %w2\n\t"\ + "lock; cmpxchgw %w2, %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\ + : [arg] "ir" ((temp_storage_type)argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andw", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orw", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + temp_storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorw", v, original, result); + return static_cast< storage_type >(result); + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!negate(storage, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_complement(storage, order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incw %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addw %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decw %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subw %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; negw %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; andw %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; orw %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xorw %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; notw %[storage]\n\t" + : [storage] "+m" (storage) + : + : "memory" + ); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incw %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addw %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incw %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addw %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decw %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subw %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decw %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subw %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; andw %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; andw %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; orw %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; orw %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; xorw %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "iq" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; xorw %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "iq" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 4u, Signed, true > : + public gcc_x86_extra_operations_common< Base > +{ + typedef gcc_x86_extra_operations_common< Base > base_type; + typedef typename base_type::storage_type storage_type; + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[orig], %[res]\n\t"\ + op " %[res]\n\t"\ + "lock; cmpxchgl %[res], %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\ + : \ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", original, result); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", original, result); + return result; + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[arg], %[res]\n\t"\ + op " %%eax, %[res]\n\t"\ + "lock; cmpxchgl %[res], %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\ + : [arg] "ir" (argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andl", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orl", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorl", v, original, result); + return static_cast< storage_type >(result); + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!negate(storage, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_complement(storage, order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incl %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addl %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decl %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subl %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; negl %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; andl %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; orl %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xorl %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; notl %[storage]\n\t" + : [storage] "+m" (storage) + : + : "memory" + ); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incl %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addl %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "ir" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incl %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addl %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decl %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subl %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "ir" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decl %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subl %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; andl %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "ir" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; andl %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; orl %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "ir" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; orl %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; xorl %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "ir" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; xorl %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "ir" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } +}; + +#if defined(__x86_64__) + +template< typename Base, bool Signed > +struct extra_operations< Base, 8u, Signed, true > : + public gcc_x86_extra_operations_common< Base > +{ + typedef gcc_x86_extra_operations_common< Base > base_type; + typedef typename base_type::storage_type storage_type; + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[orig], %[res]\n\t"\ + op " %[res]\n\t"\ + "lock; cmpxchgq %[res], %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\ + : \ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", original, result); + return original; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", original, result); + return result; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", original, result); + return result; + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[arg], %[res]\n\t"\ + op " %%rax, %[res]\n\t"\ + "lock; cmpxchgq %[res], %[storage]\n\t"\ + "jne 1b"\ + : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\ + : [arg] "r" (argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andq", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orq", v, original, result); + return static_cast< storage_type >(result); + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type original = storage; + storage_type result; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorq", v, original, result); + return static_cast< storage_type >(result); + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!negate(storage, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_complement(storage, order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incq %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addq %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decq %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subq %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; negq %[storage]\n\t" + : [storage] "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; andq %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; orq %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xorq %[argument], %[storage]\n\t" + : [storage] "+m" (storage) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; notq %[storage]\n\t" + : [storage] "+m" (storage) + : + : "memory" + ); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incq %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addq %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "er" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; incq %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; addq %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decq %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : + : "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subq %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "er" (v) + : "memory" + ); + } +#else + if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1) + { + __asm__ __volatile__ + ( + "lock; decq %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lock; subq %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + } +#endif + return res; + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; andq %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "er" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; andq %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; orq %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "er" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; orq %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + bool res; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; xorq %[argument], %[storage]\n\t" + : [storage] "+m" (storage), [result] "=@ccnz" (res) + : [argument] "er" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "lock; xorq %[argument], %[storage]\n\t" + "setnz %[result]\n\t" + : [storage] "+m" (storage), [result] "=q" (res) + : [argument] "er" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif + return res; + } +}; + +#endif // defined(__x86_64__) + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_ops_generic.hpp b/boost/atomic/detail/extra_ops_generic.hpp new file mode 100644 index 00000000..43842628 --- /dev/null +++ b/boost/atomic/detail/extra_ops_generic.hpp @@ -0,0 +1,402 @@ +/* + * 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) + * + * Copyright (c) 2015 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_ops_generic.hpp + * + * This header contains generic implementation of the extra atomic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +// unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable: 4146) +#endif + +namespace boost { +namespace atomics { +namespace detail { + +//! Generic implementation of extra operations +template< typename Base, std::size_t Size, bool Signed, bool = Base::full_cas_based > +struct generic_extra_operations : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< Size >::type emulated_storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {} + return old_val; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_val); + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)); + } + while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return base_type::fetch_add(storage, v, order) + v; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return base_type::fetch_sub(storage, v, order) - v; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return base_type::fetch_and(storage, v, order) & v; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return base_type::fetch_or(storage, v, order) | v; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return base_type::fetch_xor(storage, v, order) ^ v; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order); + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))); + return base_type::fetch_xor(storage, mask, order) ^ mask; + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_add(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_sub(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_negate(storage, order); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_and(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_or(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_xor(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_complement(storage, order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!static_cast< emulated_storage_type >(add(storage, v, order)); + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!static_cast< emulated_storage_type >(sub(storage, v, order)); + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!negate(storage, order); + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_and(storage, v, order); + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_or(storage, v, order); + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_xor(storage, v, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order)); + } + + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number)); + storage_type old_val = base_type::fetch_or(storage, mask, order); + return !!(old_val & mask); + } + + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number)); + storage_type old_val = base_type::fetch_and(storage, ~mask, order); + return !!(old_val & mask); + } + + static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number)); + storage_type old_val = base_type::fetch_xor(storage, mask, order); + return !!(old_val & mask); + } +}; + +//! Specialization for cases when the platform only natively supports CAS +template< typename Base, std::size_t Size, bool Signed > +struct generic_extra_operations< Base, Size, Signed, true > : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< Size >::type emulated_storage_type; + + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {} + return old_val; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_val); + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)); + } + while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_val); + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v)); + } + while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_val); + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v)); + } + while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_val); + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val & v)); + } + while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_val); + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val | v)); + } + while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_val); + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val ^ v)); + } + while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return new_val; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order); + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return bitwise_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_add(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_sub(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_negate(storage, order); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_and(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_or(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fetch_xor(storage, v, order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + fetch_complement(storage, order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!static_cast< emulated_storage_type >(add(storage, v, order)); + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!static_cast< emulated_storage_type >(sub(storage, v, order)); + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!negate(storage, order); + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_and(storage, v, order); + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_or(storage, v, order); + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return !!bitwise_xor(storage, v, order); + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order)); + } + + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number)); + storage_type old_val = base_type::fetch_or(storage, mask, order); + return !!(old_val & mask); + } + + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number)); + storage_type old_val = base_type::fetch_and(storage, ~mask, order); + return !!(old_val & mask); + } + + static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number)); + storage_type old_val = base_type::fetch_xor(storage, mask, order); + return !!(old_val & mask); + } +}; + +// Default extra_operations template definition will be used unless specialized for a specific platform +template< typename Base, std::size_t Size, bool Signed > +struct extra_operations< Base, Size, Signed, true > : + public generic_extra_operations< Base, Size, Signed > +{ +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_ops_msvc_arm.hpp b/boost/atomic/detail/extra_ops_msvc_arm.hpp new file mode 100644 index 00000000..b8eb5bcb --- /dev/null +++ b/boost/atomic/detail/extra_ops_msvc_arm.hpp @@ -0,0 +1,106 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_ops_msvc_arm.hpp + * + * This header contains implementation of the extra atomic operations for ARM. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR) + +template< typename Base, std::size_t Size, bool Signed > +struct extra_operations< Base, 4u, Signed, true > : + public generic_extra_operations< Base, 4u, Signed > +{ + typedef generic_extra_operations< Base, 4u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED) && defined(BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE) && defined(BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE) + bool result; + switch (order) + { + case memory_order_relaxed: + result = !!BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED(&storage, bit_number); + break; + case memory_order_consume: + case memory_order_acquire: + result = !!BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE(&storage, bit_number); + break; + case memory_order_release: + result = !!BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE(&storage, bit_number); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + result = !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number); + break; + } + return result; +#else + return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number); +#endif + } + + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED) && defined(BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE) && defined(BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE) + bool result; + switch (order) + { + case memory_order_relaxed: + result = !!BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED(&storage, bit_number); + break; + case memory_order_consume: + case memory_order_acquire: + result = !!BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE(&storage, bit_number); + break; + case memory_order_release: + result = !!BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE(&storage, bit_number); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + result = !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number); + break; + } + return result; +#else + return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number); +#endif + } +}; + +#endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR) + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/extra_ops_msvc_x86.hpp b/boost/atomic/detail/extra_ops_msvc_x86.hpp new file mode 100644 index 00000000..17451a83 --- /dev/null +++ b/boost/atomic/detail/extra_ops_msvc_x86.hpp @@ -0,0 +1,1301 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/extra_ops_msvc_x86.hpp + * + * This header contains implementation of the extra atomic operations for x86. + */ + +#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +// frame pointer register 'ebx' modified by inline assembly code +#pragma warning(disable: 4731) +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR)) + +template< typename Base, std::size_t Size, bool Signed > +struct msvc_x86_extra_operations_common : + public generic_extra_operations< Base, Size, Signed > +{ + typedef generic_extra_operations< Base, Size, Signed > base_type; + typedef typename base_type::storage_type storage_type; + +#if defined(BOOST_ATOMIC_INTERLOCKED_BTS) + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT + { + return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number); + } +#else + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, bit_number + lock bts [edx], eax + setc result + }; + base_type::fence_after(order); + return result; + } +#endif + +#if defined(BOOST_ATOMIC_INTERLOCKED_BTR) + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT + { + return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number); + } +#else + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, bit_number + lock btr [edx], eax + setc result + }; + base_type::fence_after(order); + return result; + } +#endif + +#if defined(_M_IX86) + static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, bit_number + lock btc [edx], eax + setc result + }; + base_type::fence_after(order); + return result; + } +#endif +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 1u, Signed, true > : + public msvc_x86_extra_operations_common< Base, 1u, Signed > +{ + typedef msvc_x86_extra_operations_common< Base, 1u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + +#if defined(_M_IX86) + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type old_val; + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + neg dl + lock cmpxchg byte ptr [ecx], dl + jne again + mov old_val, al + }; + base_type::fence_after(order); + return old_val; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type new_val; + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + neg dl + lock cmpxchg byte ptr [ecx], dl + jne again + mov new_val, dl + }; + base_type::fence_after(order); + return new_val; + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + neg dl + lock cmpxchg byte ptr [ecx], dl + jne again + test dl, dl + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + neg dl + lock cmpxchg byte ptr [ecx], dl + jne again + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, byte ptr [edi] + align 16 + again: + mov dl, al + and dl, cl + lock cmpxchg byte ptr [edi], dl + jne again + mov v, dl + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, byte ptr [edi] + align 16 + again: + mov dl, al + or dl, cl + lock cmpxchg byte ptr [edi], dl + jne again + mov v, dl + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, byte ptr [edi] + align 16 + again: + mov dl, al + xor dl, cl + lock cmpxchg byte ptr [edi], dl + jne again + mov v, dl + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type old_val; + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + not dl + lock cmpxchg byte ptr [ecx], dl + jne again + mov old_val, al + }; + base_type::fence_after(order); + return old_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type new_val; + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + not dl + lock cmpxchg byte ptr [ecx], dl + jne again + mov new_val, dl + }; + base_type::fence_after(order); + return new_val; + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + not dl + lock cmpxchg byte ptr [ecx], dl + jne again + test dl, dl + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov ecx, storage + movzx eax, byte ptr [ecx] + align 16 + again: + mov edx, eax + not dl + lock cmpxchg byte ptr [ecx], dl + jne again + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock add byte ptr [edx], al + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock sub byte ptr [edx], al + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + lock neg byte ptr [edx] + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock and byte ptr [edx], al + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock or byte ptr [edx], al + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock xor byte ptr [edx], al + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + lock not byte ptr [edx] + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock add byte ptr [edx], al + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock sub byte ptr [edx], al + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock and byte ptr [edx], al + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock or byte ptr [edx], al + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock xor byte ptr [edx], al + setnz result + }; + base_type::fence_after(order); + return result; + } +#endif // defined(_M_IX86) +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 2u, Signed, true > : + public msvc_x86_extra_operations_common< Base, 2u, Signed > +{ + typedef msvc_x86_extra_operations_common< Base, 2u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + +#if defined(_M_IX86) + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type old_val; + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + neg dx + lock cmpxchg word ptr [ecx], dx + jne again + mov old_val, ax + }; + base_type::fence_after(order); + return old_val; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type new_val; + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + neg dx + lock cmpxchg word ptr [ecx], dx + jne again + mov new_val, dx + }; + base_type::fence_after(order); + return new_val; + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + neg dx + lock cmpxchg word ptr [ecx], dx + jne again + test dx, dx + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + neg dx + lock cmpxchg word ptr [ecx], dx + jne again + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, word ptr [edi] + align 16 + again: + mov dx, ax + and dx, cx + lock cmpxchg word ptr [edi], dx + jne again + mov v, dx + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, word ptr [edi] + align 16 + again: + mov dx, ax + or dx, cx + lock cmpxchg word ptr [edi], dx + jne again + mov v, dx + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, word ptr [edi] + align 16 + again: + mov dx, ax + xor dx, cx + lock cmpxchg word ptr [edi], dx + jne again + mov v, dx + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type old_val; + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + not dx + lock cmpxchg word ptr [ecx], dx + jne again + mov old_val, ax + }; + base_type::fence_after(order); + return old_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type new_val; + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + not dx + lock cmpxchg word ptr [ecx], dx + jne again + mov new_val, dx + }; + base_type::fence_after(order); + return new_val; + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + not dx + lock cmpxchg word ptr [ecx], dx + jne again + test dx, dx + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov ecx, storage + movzx eax, word ptr [ecx] + align 16 + again: + mov edx, eax + not dx + lock cmpxchg word ptr [ecx], dx + jne again + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock add word ptr [edx], ax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock sub word ptr [edx], ax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + lock neg word ptr [edx] + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock and word ptr [edx], ax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock or word ptr [edx], ax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock xor word ptr [edx], ax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + lock not word ptr [edx] + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock add word ptr [edx], ax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock sub word ptr [edx], ax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock and word ptr [edx], ax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock or word ptr [edx], ax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + movzx eax, v + lock xor word ptr [edx], ax + setnz result + }; + base_type::fence_after(order); + return result; + } +#endif // defined(_M_IX86) +}; + +template< typename Base, bool Signed > +struct extra_operations< Base, 4u, Signed, true > : + public msvc_x86_extra_operations_common< Base, 4u, Signed > +{ + typedef msvc_x86_extra_operations_common< Base, 4u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + +#if defined(_M_IX86) + static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type old_val; + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + neg edx + lock cmpxchg dword ptr [ecx], edx + jne again + mov old_val, eax + }; + base_type::fence_after(order); + return old_val; + } + + static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type new_val; + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + neg edx + lock cmpxchg dword ptr [ecx], edx + jne again + mov new_val, edx + }; + base_type::fence_after(order); + return new_val; + } + + static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + neg edx + lock cmpxchg dword ptr [ecx], edx + jne again + test edx, edx + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + neg edx + lock cmpxchg dword ptr [ecx], edx + jne again + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + mov ecx, v + xor edx, edx + mov eax, dword ptr [edi] + align 16 + again: + mov edx, eax + and edx, ecx + lock cmpxchg dword ptr [edi], edx + jne again + mov v, edx + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + mov ecx, v + xor edx, edx + mov eax, dword ptr [edi] + align 16 + again: + mov edx, eax + or edx, ecx + lock cmpxchg dword ptr [edi], edx + jne again + mov v, edx + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + mov ecx, v + xor edx, edx + mov eax, dword ptr [edi] + align 16 + again: + mov edx, eax + xor edx, ecx + lock cmpxchg dword ptr [edi], edx + jne again + mov v, edx + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type old_val; + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + not edx + lock cmpxchg dword ptr [ecx], edx + jne again + mov old_val, eax + }; + base_type::fence_after(order); + return old_val; + } + + static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + storage_type new_val; + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + not edx + lock cmpxchg dword ptr [ecx], edx + jne again + mov new_val, edx + }; + base_type::fence_after(order); + return new_val; + } + + static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + not edx + lock cmpxchg dword ptr [ecx], edx + jne again + test edx, edx + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov ecx, storage + mov eax, dword ptr [ecx] + align 16 + again: + mov edx, eax + not edx + lock cmpxchg dword ptr [ecx], edx + jne again + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + mov eax, v + lock add dword ptr [edx], eax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + mov eax, v + lock sub dword ptr [edx], eax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + lock neg dword ptr [edx] + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + mov eax, v + lock and dword ptr [edx], eax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + mov eax, v + lock or dword ptr [edx], eax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + mov eax, v + lock xor dword ptr [edx], eax + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + lock not dword ptr [edx] + }; + base_type::fence_after(order); + } + + static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, v + lock add dword ptr [edx], eax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, v + lock sub dword ptr [edx], eax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, v + lock and dword ptr [edx], eax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, v + lock or dword ptr [edx], eax + setnz result + }; + base_type::fence_after(order); + return result; + } + + static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + bool result; + __asm + { + mov edx, storage + mov eax, v + lock xor dword ptr [edx], eax + setnz result + }; + base_type::fence_after(order); + return result; + } +#endif // defined(_M_IX86) +}; + +#endif // defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR)) + +#if defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64) + +template< typename Base, bool Signed > +struct extra_operations< Base, 8u, Signed, true > : + public generic_extra_operations< Base, 8u, Signed > +{ + typedef generic_extra_operations< Base, 8u, Signed > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + return !!BOOST_ATOMIC_INTERLOCKED_BTS64(&storage, bit_number); + } + + static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT + { + return !!BOOST_ATOMIC_INTERLOCKED_BTR64(&storage, bit_number); + } +}; + +#endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64) + +} // namespace detail +} // namespace atomics +} // namespace boost + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_ diff --git a/boost/atomic/detail/float_sizes.hpp b/boost/atomic/detail/float_sizes.hpp new file mode 100644 index 00000000..4c3a346f --- /dev/null +++ b/boost/atomic/detail/float_sizes.hpp @@ -0,0 +1,142 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/float_sizes.hpp + * + * This header defines macros for testing buitin floating point type sizes + */ + +#ifndef BOOST_ATOMIC_DETAIL_FLOAT_SIZES_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_FLOAT_SIZES_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +// Detect value sizes of the different floating point types. The value sizes may be less than the corresponding type sizes +// if the type contains padding bits. This is typical e.g. with 80-bit extended float types, which are often represented as 128-bit types. +// See: https://en.wikipedia.org/wiki/IEEE_754 +// For Intel x87 extended double see: https://en.wikipedia.org/wiki/Extended_precision#x86_Architecture_Extended_Precision_Format +// For IBM extended double (a.k.a. double-double) see: https://en.wikipedia.org/wiki/Long_double#Implementations, https://gcc.gnu.org/wiki/Ieee128PowerPC +#if (FLT_RADIX+0) == 2 + +#if ((FLT_MANT_DIG+0) == 11) && ((FLT_MAX_EXP+0) == 16) // IEEE 754 binary16 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 2 +#elif ((FLT_MANT_DIG+0) == 24) && ((FLT_MAX_EXP+0) == 128) // IEEE 754 binary32 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 4 +#elif ((FLT_MANT_DIG+0) == 53) && ((FLT_MAX_EXP+0) == 1024) // IEEE 754 binary64 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 8 +#elif ((FLT_MANT_DIG+0) == 64) && ((FLT_MAX_EXP+0) == 16384) // x87 extended double +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 10 +#elif ((FLT_MANT_DIG+0) == 106) && ((FLT_MAX_EXP+0) == 1024) // IBM extended double +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 16 +#elif ((FLT_MANT_DIG+0) == 113) && ((FLT_MAX_EXP+0) == 16384) // IEEE 754 binary128 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 16 +#elif ((FLT_MANT_DIG+0) == 237) && ((FLT_MAX_EXP+0) == 262144) // IEEE 754 binary256 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 32 +#endif + +#if ((DBL_MANT_DIG+0) == 11) && ((DBL_MAX_EXP+0) == 16) // IEEE 754 binary16 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 2 +#elif ((DBL_MANT_DIG+0) == 24) && ((DBL_MAX_EXP+0) == 128) // IEEE 754 binary32 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 4 +#elif ((DBL_MANT_DIG+0) == 53) && ((DBL_MAX_EXP+0) == 1024) // IEEE 754 binary64 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 8 +#elif ((DBL_MANT_DIG+0) == 64) && ((DBL_MAX_EXP+0) == 16384) // x87 extended double +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 10 +#elif ((DBL_MANT_DIG+0) == 106) && ((DBL_MAX_EXP+0) == 1024) // IBM extended double +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 16 +#elif ((DBL_MANT_DIG+0) == 113) && ((DBL_MAX_EXP+0) == 16384) // IEEE 754 binary128 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 16 +#elif ((DBL_MANT_DIG+0) == 237) && ((DBL_MAX_EXP+0) == 262144) // IEEE 754 binary256 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 32 +#endif + +#if ((LDBL_MANT_DIG+0) == 11) && ((LDBL_MAX_EXP+0) == 16) // IEEE 754 binary16 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 2 +#elif ((LDBL_MANT_DIG+0) == 24) && ((LDBL_MAX_EXP+0) == 128) // IEEE 754 binary32 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 4 +#elif ((LDBL_MANT_DIG+0) == 53) && ((LDBL_MAX_EXP+0) == 1024) // IEEE 754 binary64 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 8 +#elif ((LDBL_MANT_DIG+0) == 64) && ((LDBL_MAX_EXP+0) == 16384) // x87 extended double +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 10 +#elif ((LDBL_MANT_DIG+0) == 106) && ((LDBL_MAX_EXP+0) == 1024) // IBM extended double +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 16 +#elif ((LDBL_MANT_DIG+0) == 113) && ((LDBL_MAX_EXP+0) == 16384) // IEEE 754 binary128 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 16 +#elif ((LDBL_MANT_DIG+0) == 237) && ((LDBL_MAX_EXP+0) == 262144) // IEEE 754 binary256 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 32 +#endif + +#elif (FLT_RADIX+0) == 10 + +#if ((FLT_MANT_DIG+0) == 7) && ((FLT_MAX_EXP+0) == 97) // IEEE 754 decimal32 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 4 +#elif ((FLT_MANT_DIG+0) == 16) && ((FLT_MAX_EXP+0) == 385) // IEEE 754 decimal64 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 8 +#elif ((FLT_MANT_DIG+0) == 34) && ((FLT_MAX_EXP+0) == 6145) // IEEE 754 decimal128 +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 16 +#endif + +#if ((DBL_MANT_DIG+0) == 7) && ((DBL_MAX_EXP+0) == 97) // IEEE 754 decimal32 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 4 +#elif ((DBL_MANT_DIG+0) == 16) && ((DBL_MAX_EXP+0) == 385) // IEEE 754 decimal64 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 8 +#elif ((DBL_MANT_DIG+0) == 34) && ((DBL_MAX_EXP+0) == 6145) // IEEE 754 decimal128 +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 16 +#endif + +#if ((LDBL_MANT_DIG+0) == 7) && ((LDBL_MAX_EXP+0) == 97) // IEEE 754 decimal32 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 4 +#elif ((LDBL_MANT_DIG+0) == 16) && ((LDBL_MAX_EXP+0) == 385) // IEEE 754 decimal64 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 8 +#elif ((LDBL_MANT_DIG+0) == 34) && ((LDBL_MAX_EXP+0) == 6145) // IEEE 754 decimal128 +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 16 +#endif + +#endif + +// GCC and compatible compilers define internal macros with builtin type traits +#if defined(__SIZEOF_FLOAT__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT __SIZEOF_FLOAT__ +#endif +#if defined(__SIZEOF_DOUBLE__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE __SIZEOF_DOUBLE__ +#endif +#if defined(__SIZEOF_LONG_DOUBLE__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE __SIZEOF_LONG_DOUBLE__ +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE) + +#define BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(x)\ + ((x) == 1u ? 1u : ((x) == 2u ? 2u : ((x) <= 4u ? 4u : ((x) <= 8u ? 8u : ((x) <= 16u ? 16u : ((x) <= 32u ? 32u : (x))))))) + +// Make our best guess. These sizes may not be accurate, but they are good enough to estimate the size of the storage required to hold these types. +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE) +#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE) +#endif +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE) +#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE) +#endif +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE) +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE) +#endif + +#endif // !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE) + +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) ||\ + !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) ||\ + !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE) +#error Boost.Atomic: Failed to determine builtin floating point type sizes, the target platform is not supported. Please, report to the developers (patches are welcome). +#endif + +#endif // BOOST_ATOMIC_DETAIL_FLOAT_SIZES_HPP_INCLUDED_ diff --git a/boost/atomic/detail/fp_operations.hpp b/boost/atomic/detail/fp_operations.hpp new file mode 100644 index 00000000..69cb0d19 --- /dev/null +++ b/boost/atomic/detail/fp_operations.hpp @@ -0,0 +1,28 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/fp_operations.hpp + * + * This header defines floating point atomic operations, including the generic version. + */ + +#ifndef BOOST_ATOMIC_DETAIL_FP_OPERATIONS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_FP_OPERATIONS_HPP_INCLUDED_ + +#include +#include + +#if !defined(BOOST_ATOMIC_DETAIL_FP_BACKEND_GENERIC) +#include BOOST_ATOMIC_DETAIL_FP_BACKEND_HEADER(boost/atomic/detail/fp_ops_) +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_ATOMIC_DETAIL_FP_OPERATIONS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/fp_operations_fwd.hpp b/boost/atomic/detail/fp_operations_fwd.hpp new file mode 100644 index 00000000..8696de31 --- /dev/null +++ b/boost/atomic/detail/fp_operations_fwd.hpp @@ -0,0 +1,35 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/fp_operations_fwd.hpp + * + * This header contains forward declaration of the \c fp_operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_FP_OPERATIONS_FWD_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_FP_OPERATIONS_FWD_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base, typename Value, std::size_t Size, bool = Base::is_always_lock_free > +struct fp_operations; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_FP_OPERATIONS_FWD_HPP_INCLUDED_ diff --git a/boost/atomic/detail/fp_ops_emulated.hpp b/boost/atomic/detail/fp_ops_emulated.hpp new file mode 100644 index 00000000..a87f1814 --- /dev/null +++ b/boost/atomic/detail/fp_ops_emulated.hpp @@ -0,0 +1,72 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/fp_ops_emulated.hpp + * + * This header contains emulated (lock-based) implementation of the floating point atomic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +//! Generic implementation of floating point operations +template< typename Base, typename Value, std::size_t Size > +struct emulated_fp_operations : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + typedef Value value_type; + + static BOOST_FORCEINLINE value_type fetch_add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); + value_type new_val = old_val + v; + s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + return old_val; + } + + static BOOST_FORCEINLINE value_type fetch_sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); + value_type new_val = old_val - v; + s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + return old_val; + } +}; + +template< typename Base, typename Value, std::size_t Size > +struct fp_operations< Base, Value, Size, false > : + public emulated_fp_operations< Base, Value, Size > +{ +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/fp_ops_generic.hpp b/boost/atomic/detail/fp_ops_generic.hpp new file mode 100644 index 00000000..b83e85a3 --- /dev/null +++ b/boost/atomic/detail/fp_ops_generic.hpp @@ -0,0 +1,83 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/fp_ops_generic.hpp + * + * This header contains generic implementation of the floating point atomic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +//! Generic implementation of floating point operations +template< typename Base, typename Value, std::size_t Size > +struct generic_fp_operations : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + typedef Value value_type; + + static BOOST_FORCEINLINE value_type fetch_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_storage, new_storage; + value_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_storage); + do + { + old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage); + new_val = old_val + v; + new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + } + while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed)); + return old_val; + } + + static BOOST_FORCEINLINE value_type fetch_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_storage, new_storage; + value_type old_val, new_val; + atomics::detail::non_atomic_load(storage, old_storage); + do + { + old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage); + new_val = old_val - v; + new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val); + } + while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed)); + return old_val; + } +}; + +// Default fp_operations template definition will be used unless specialized for a specific platform +template< typename Base, typename Value, std::size_t Size > +struct fp_operations< Base, Value, Size, true > : + public generic_fp_operations< Base, Value, Size > +{ +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/hwcaps_gcc_arm.hpp b/boost/atomic/detail/hwcaps_gcc_arm.hpp new file mode 100644 index 00000000..6d0c3386 --- /dev/null +++ b/boost/atomic/detail/hwcaps_gcc_arm.hpp @@ -0,0 +1,67 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/hwcaps_gcc_arm.hpp + * + * This header defines hardware capabilities macros for ARM + */ + +#ifndef BOOST_ATOMIC_DETAIL_HWCAPS_GCC_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_HWCAPS_GCC_ARM_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH+0) >= 6 + +#if BOOST_ATOMIC_DETAIL_ARM_ARCH > 6 +// ARMv7 and later have dmb instruction +#define BOOST_ATOMIC_DETAIL_ARM_HAS_DMB 1 +#endif + +#if defined(__ARM_FEATURE_LDREX) + +#if (__ARM_FEATURE_LDREX & 1) +#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1 +#endif +#if (__ARM_FEATURE_LDREX & 2) +#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1 +#endif +#if (__ARM_FEATURE_LDREX & 8) +#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1 +#endif + +#else // defined(__ARM_FEATURE_LDREX) + +#if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__)) + +// ARMv6k and ARMv7 have 8 and 16-bit ldrex/strex variants, but at least GCC 4.7 fails to compile them. GCC 4.9 is known to work. +#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 +#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1 +#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1 +#endif + +#if !(((defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)) && defined(__thumb__)) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7M__)) +// ARMv6k and ARMv7 except ARMv7-M have 64-bit ldrex/strex variants. +// Unfortunately, GCC (at least 4.7.3 on Ubuntu) does not allocate register pairs properly when targeting ARMv6k Thumb, +// which is required for ldrexd/strexd instructions, so we disable 64-bit support. When targeting ARMv6k ARM +// or ARMv7 (both ARM and Thumb 2) it works as expected. +#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1 +#endif + +#endif // !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__)) + +#endif // defined(__ARM_FEATURE_LDREX) + +#endif // defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH+0) >= 6 + +#endif // BOOST_ATOMIC_DETAIL_HWCAPS_GCC_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/hwcaps_gcc_ppc.hpp b/boost/atomic/detail/hwcaps_gcc_ppc.hpp new file mode 100644 index 00000000..2ec1e327 --- /dev/null +++ b/boost/atomic/detail/hwcaps_gcc_ppc.hpp @@ -0,0 +1,42 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/hwcaps_gcc_ppc.hpp + * + * This header defines hardware capabilities macros for PowerPC + */ + +#ifndef BOOST_ATOMIC_DETAIL_HWCAPS_GCC_PPC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_HWCAPS_GCC_PPC_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__POWERPC__) || defined(__PPC__) + +#if defined(_ARCH_PWR8) +// Power8 and later architectures have 8 and 16-bit instructions +#define BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX +#define BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX +#endif + +#if defined(__powerpc64__) || defined(__PPC64__) +// Power7 and later architectures in 64-bit mode have 64-bit instructions +#define BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX +#if defined(_ARCH_PWR8) +// Power8 also has 128-bit instructions +#define BOOST_ATOMIC_DETAIL_PPC_HAS_LQARX_STQCX +#endif +#endif + +#endif // defined(__POWERPC__) || defined(__PPC__) + +#endif // BOOST_ATOMIC_DETAIL_HWCAPS_GCC_PPC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/hwcaps_gcc_x86.hpp b/boost/atomic/detail/hwcaps_gcc_x86.hpp new file mode 100644 index 00000000..91a1aee3 --- /dev/null +++ b/boost/atomic/detail/hwcaps_gcc_x86.hpp @@ -0,0 +1,58 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/hwcaps_gcc_x86.hpp + * + * This header defines hardware capabilities macros for x86 + */ + +#ifndef BOOST_ATOMIC_DETAIL_HWCAPS_GCC_X86_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_HWCAPS_GCC_X86_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__GNUC__) + +#if defined(__i386__) &&\ + (\ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\ + defined(__i586__) || defined(__i686__) || defined(__SSE__)\ + ) +#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1 +#endif + +#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 +#endif + +#if defined(__x86_64__) || defined(__SSE2__) +// Use mfence only if SSE2 is available +#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1 +#endif + +#else // defined(__GNUC__) + +#if defined(__i386__) && !defined(BOOST_ATOMIC_NO_CMPXCHG8B) +#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1 +#endif + +#if defined(__x86_64__) && !defined(BOOST_ATOMIC_NO_CMPXCHG16B) +#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1 +#endif + +#if !defined(BOOST_ATOMIC_NO_MFENCE) +#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1 +#endif + +#endif // defined(__GNUC__) + +#endif // BOOST_ATOMIC_DETAIL_HWCAPS_GCC_X86_HPP_INCLUDED_ diff --git a/boost/atomic/detail/int_sizes.hpp b/boost/atomic/detail/int_sizes.hpp new file mode 100644 index 00000000..2a9757c1 --- /dev/null +++ b/boost/atomic/detail/int_sizes.hpp @@ -0,0 +1,140 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/int_sizes.hpp + * + * This header defines macros for testing buitin integer type sizes + */ + +#ifndef BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +// GCC and compatible compilers define internal macros with builtin type traits +#if defined(__SIZEOF_SHORT__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT __SIZEOF_SHORT__ +#endif +#if defined(__SIZEOF_INT__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_INT __SIZEOF_INT__ +#endif +#if defined(__SIZEOF_LONG__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG __SIZEOF_LONG__ +#endif +#if defined(__SIZEOF_LONG_LONG__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG __SIZEOF_LONG_LONG__ +#endif +#if defined(__SIZEOF_WCHAR_T__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__ +#endif +#if defined(__SIZEOF_POINTER__) +#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER __SIZEOF_POINTER__ +#elif defined(_MSC_VER) +#if defined(_M_AMD64) || defined(_M_ARM64) || defined(_M_IA64) +#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 8 +#else +#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 4 +#endif +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\ + !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG) + +// Try to deduce sizes from limits +#include +#include + +#if (USHRT_MAX + 0) == 0xff +#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 1 +#elif (USHRT_MAX + 0) == 0xffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 2 +#elif (USHRT_MAX + 0) == 0xffffffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 4 +#elif (USHRT_MAX + 0) == UINT64_C(0xffffffffffffffff) +#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 8 +#endif + +#if (UINT_MAX + 0) == 0xff +#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 1 +#elif (UINT_MAX + 0) == 0xffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 2 +#elif (UINT_MAX + 0) == 0xffffffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 4 +#elif (UINT_MAX + 0) == UINT64_C(0xffffffffffffffff) +#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 8 +#endif + +#if (ULONG_MAX + 0) == 0xff +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 1 +#elif (ULONG_MAX + 0) == 0xffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 2 +#elif (ULONG_MAX + 0) == 0xffffffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 4 +#elif (ULONG_MAX + 0) == UINT64_C(0xffffffffffffffff) +#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 8 +#endif + +#if defined(__hpux) // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8 +#else + +// The list of the non-standard macros (the ones except ULLONG_MAX) is taken from cstdint.hpp +#if defined(ULLONG_MAX) +#define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULLONG_MAX +#elif defined(ULONG_LONG_MAX) +#define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONG_LONG_MAX +#elif defined(ULONGLONG_MAX) +#define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONGLONG_MAX +#elif defined(_LLONG_MAX) // strangely enough, this one seems to be holding the limit for the unsigned integer +#define BOOST_ATOMIC_DETAIL_ULLONG_MAX _LLONG_MAX +#endif + +#if (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xff +#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 1 +#elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 2 +#elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffffffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 4 +#elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == UINT64_C(0xffffffffffffffff) +#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8 +#endif + +#endif // defined(__hpux) + +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T) + +#include +#include + +#if defined(_MSC_VER) && (_MSC_VER <= 1310 || defined(UNDER_CE) && _MSC_VER <= 1500) +// MSVC 7.1 and MSVC 8 (arm) define WCHAR_MAX to a value not suitable for constant expressions +#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2 +#elif (WCHAR_MAX + 0) == 0xff || (WCHAR_MAX + 0) == 0x7f +#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 1 +#elif (WCHAR_MAX + 0) == 0xffff || (WCHAR_MAX + 0) == 0x7fff +#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2 +#elif (WCHAR_MAX + 0) == 0xffffffff || (WCHAR_MAX + 0) == 0x7fffffff +#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 4 +#elif (WCHAR_MAX + 0) == UINT64_C(0xffffffffffffffff) || (WCHAR_MAX + 0) == INT64_C(0x7fffffffffffffff) +#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 8 +#endif +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\ + !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG) ||\ + !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T) +#error Boost.Atomic: Failed to determine builtin integer sizes, the target platform is not supported. Please, report to the developers (patches are welcome). +#endif + +#endif // BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_ diff --git a/boost/atomic/detail/integral_extend.hpp b/boost/atomic/detail/integral_extend.hpp new file mode 100644 index 00000000..dea48ac6 --- /dev/null +++ b/boost/atomic/detail/integral_extend.hpp @@ -0,0 +1,105 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/integral_extend.hpp + * + * This header defines sign/zero extension utilities for Boost.Atomic. The tools assume two's complement signed integer representation. + */ + +#ifndef BOOST_ATOMIC_DETAIL_INTEGRAL_EXTEND_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_INTEGRAL_EXTEND_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Output, typename Input > +BOOST_FORCEINLINE Output zero_extend_impl(Input input, atomics::detail::true_type) BOOST_NOEXCEPT +{ + // Note: If we are casting with truncation or to the same-sized output, don't cause signed integer overflow by this chain of conversions + return atomics::detail::bitwise_cast< Output >(static_cast< typename atomics::detail::make_unsigned< Output >::type >( + static_cast< typename atomics::detail::make_unsigned< Input >::type >(input))); +} + +template< typename Output, typename Input > +BOOST_FORCEINLINE Output zero_extend_impl(Input input, atomics::detail::false_type) BOOST_NOEXCEPT +{ + return static_cast< Output >(static_cast< typename atomics::detail::make_unsigned< Input >::type >(input)); +} + +//! Zero-extends or truncates (wraps) input operand to fit in the output type +template< typename Output, typename Input > +BOOST_FORCEINLINE Output zero_extend(Input input) BOOST_NOEXCEPT +{ + return atomics::detail::zero_extend_impl< Output >(input, atomics::detail::integral_constant< bool, atomics::detail::is_signed< Output >::value >()); +} + +//! Truncates (wraps) input operand to fit in the output type +template< typename Output, typename Input > +BOOST_FORCEINLINE Output integral_truncate(Input input) BOOST_NOEXCEPT +{ + // zero_extend does the truncation + return atomics::detail::zero_extend< Output >(input); +} + +template< typename Output, typename Input > +BOOST_FORCEINLINE Output sign_extend_impl(Input input, atomics::detail::true_type) BOOST_NOEXCEPT +{ + return atomics::detail::integral_truncate< Output >(input); +} + +template< typename Output, typename Input > +BOOST_FORCEINLINE Output sign_extend_impl(Input input, atomics::detail::false_type) BOOST_NOEXCEPT +{ + return static_cast< Output >(atomics::detail::bitwise_cast< typename atomics::detail::make_signed< Input >::type >(input)); +} + +//! Sign-extends or truncates (wraps) input operand to fit in the output type +template< typename Output, typename Input > +BOOST_FORCEINLINE Output sign_extend(Input input) BOOST_NOEXCEPT +{ + return atomics::detail::sign_extend_impl< Output >(input, atomics::detail::integral_constant< bool, sizeof(Output) <= sizeof(Input) >()); +} + +//! Sign-extends or truncates (wraps) input operand to fit in the output type +template< typename Output, typename Input > +BOOST_FORCEINLINE Output integral_extend(Input input, atomics::detail::true_type) BOOST_NOEXCEPT +{ + return atomics::detail::sign_extend< Output >(input); +} + +//! Zero-extends or truncates (wraps) input operand to fit in the output type +template< typename Output, typename Input > +BOOST_FORCEINLINE Output integral_extend(Input input, atomics::detail::false_type) BOOST_NOEXCEPT +{ + return atomics::detail::zero_extend< Output >(input); +} + +//! Sign- or zero-extends or truncates (wraps) input operand to fit in the output type +template< bool Signed, typename Output, typename Input > +BOOST_FORCEINLINE Output integral_extend(Input input) BOOST_NOEXCEPT +{ + return atomics::detail::integral_extend< Output >(input, atomics::detail::integral_constant< bool, Signed >()); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_INTEGRAL_EXTEND_HPP_INCLUDED_ diff --git a/boost/atomic/detail/interlocked.hpp b/boost/atomic/detail/interlocked.hpp new file mode 100644 index 00000000..774354fb --- /dev/null +++ b/boost/atomic/detail/interlocked.hpp @@ -0,0 +1,522 @@ +#ifndef BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP +#define BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP + +// Copyright (c) 2009 Helge Bahmann +// Copyright (c) 2012 - 2014, 2017 Andrey Semashev +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(_WIN32_WCE) + +#if _WIN32_WCE >= 0x600 + +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), exchange, compare) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval)) + +#else // _WIN32_WCE >= 0x600 + +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) InterlockedCompareExchange((long*)(dest), exchange, compare) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) InterlockedExchangeAdd((long*)(dest), (long)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) InterlockedExchange((long*)(dest), (long)(newval)) + +#endif // _WIN32_WCE >= 0x600 + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), (long)(exchange), (long)(compare))) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE((long*)(dest), (long)(exchange))) + +#elif defined(_MSC_VER) && _MSC_VER >= 1310 + +#if _MSC_VER < 1400 + +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchange) +#pragma intrinsic(_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedExchange) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), exchange, compare) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval)) + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), (long)(exchange), (long)(compare))) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE((long*)(dest), (long)(exchange))) + +#else // _MSC_VER < 1400 + +#include + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchange) +#pragma intrinsic(_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedExchange) +#pragma intrinsic(_InterlockedAnd) +#pragma intrinsic(_InterlockedOr) +#pragma intrinsic(_InterlockedXor) +#pragma intrinsic(_interlockedbittestandset) +#pragma intrinsic(_interlockedbittestandreset) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_AND(dest, arg) _InterlockedAnd((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR(dest, arg) _InterlockedXor((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_BTS(dest, arg) _interlockedbittestandset((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_BTR(dest, arg) _interlockedbittestandreset((long*)(dest), (long)(arg)) + +#if defined(_M_AMD64) +#if defined(BOOST_MSVC) +#pragma intrinsic(_interlockedbittestandset64) +#pragma intrinsic(_interlockedbittestandreset64) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_BTS64(dest, arg) _interlockedbittestandset64((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_BTR64(dest, arg) _interlockedbittestandreset64((__int64*)(dest), (__int64)(arg)) +#endif // defined(_M_AMD64) + +#if (defined(_M_IX86) && _M_IX86 >= 500) || defined(_M_AMD64) || defined(_M_IA64) +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchange64) +#endif +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#endif + +#if _MSC_VER >= 1500 && defined(_M_AMD64) +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchange128) +#endif +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(dest, exchange, compare) _InterlockedCompareExchange128((__int64*)(dest), ((const __int64*)(&exchange))[1], ((const __int64*)(&exchange))[0], (__int64*)(compare)) +#endif + +#if _MSC_VER >= 1600 + +// MSVC 2010 and later provide intrinsics for 8 and 16 bit integers. +// Note that for each bit count these macros must be either all defined or all not defined. +// Otherwise atomic<> operations will be implemented inconsistently. + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchange8) +#pragma intrinsic(_InterlockedExchangeAdd8) +#pragma intrinsic(_InterlockedExchange8) +#pragma intrinsic(_InterlockedAnd8) +#pragma intrinsic(_InterlockedOr8) +#pragma intrinsic(_InterlockedXor8) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(dest, exchange, compare) _InterlockedCompareExchange8((char*)(dest), (char)(exchange), (char)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(dest, addend) _InterlockedExchangeAdd8((char*)(dest), (char)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(dest, newval) _InterlockedExchange8((char*)(dest), (char)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_AND8(dest, arg) _InterlockedAnd8((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR8(dest, arg) _InterlockedOr8((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR8(dest, arg) _InterlockedXor8((char*)(dest), (char)(arg)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchange16) +#pragma intrinsic(_InterlockedExchangeAdd16) +#pragma intrinsic(_InterlockedExchange16) +#pragma intrinsic(_InterlockedAnd16) +#pragma intrinsic(_InterlockedOr16) +#pragma intrinsic(_InterlockedXor16) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(dest, exchange, compare) _InterlockedCompareExchange16((short*)(dest), (short)(exchange), (short)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(dest, addend) _InterlockedExchangeAdd16((short*)(dest), (short)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(dest, newval) _InterlockedExchange16((short*)(dest), (short)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_AND16(dest, arg) _InterlockedAnd16((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR16(dest, arg) _InterlockedOr16((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR16(dest, arg) _InterlockedXor16((short*)(dest), (short)(arg)) + +#endif // _MSC_VER >= 1600 + +#if defined(_M_AMD64) || defined(_M_IA64) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedExchangeAdd64) +#pragma intrinsic(_InterlockedExchange64) +#pragma intrinsic(_InterlockedAnd64) +#pragma intrinsic(_InterlockedOr64) +#pragma intrinsic(_InterlockedXor64) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR64(dest, arg) _InterlockedOr64((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR64(dest, arg) _InterlockedXor64((__int64*)(dest), (__int64)(arg)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchangePointer) +#pragma intrinsic(_InterlockedExchangePointer) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) _InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) _InterlockedExchangePointer((void**)(dest), (void*)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64((long*)(dest), byte_offset)) + +#elif defined(_M_IX86) + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)_InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)_InterlockedExchange((long*)(dest), (long)(newval))) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset)) + +#endif + +#if _MSC_VER >= 1700 && (defined(_M_ARM) || defined(_M_ARM64)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedExchangeAdd64) +#pragma intrinsic(_InterlockedExchange64) +#pragma intrinsic(_InterlockedAnd64) +#pragma intrinsic(_InterlockedOr64) +#pragma intrinsic(_InterlockedXor64) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR64(dest, arg) _InterlockedOr64((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR64(dest, arg) _InterlockedXor64((__int64*)(dest), (__int64)(arg)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedCompareExchange8_nf) +#pragma intrinsic(_InterlockedCompareExchange8_acq) +#pragma intrinsic(_InterlockedCompareExchange8_rel) +#pragma intrinsic(_InterlockedCompareExchange16_nf) +#pragma intrinsic(_InterlockedCompareExchange16_acq) +#pragma intrinsic(_InterlockedCompareExchange16_rel) +#pragma intrinsic(_InterlockedCompareExchange_nf) +#pragma intrinsic(_InterlockedCompareExchange_acq) +#pragma intrinsic(_InterlockedCompareExchange_rel) +#pragma intrinsic(_InterlockedCompareExchange64) +#pragma intrinsic(_InterlockedCompareExchange64_nf) +#pragma intrinsic(_InterlockedCompareExchange64_acq) +#pragma intrinsic(_InterlockedCompareExchange64_rel) +#pragma intrinsic(_InterlockedCompareExchangePointer) +#pragma intrinsic(_InterlockedCompareExchangePointer_nf) +#pragma intrinsic(_InterlockedCompareExchangePointer_acq) +#pragma intrinsic(_InterlockedCompareExchangePointer_rel) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELAXED(dest, exchange, compare) _InterlockedCompareExchange8_nf((char*)(dest), (char)(exchange), (char)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange8_acq((char*)(dest), (char)(exchange), (char)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELEASE(dest, exchange, compare) _InterlockedCompareExchange8_rel((char*)(dest), (char)(exchange), (char)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELAXED(dest, exchange, compare) _InterlockedCompareExchange16_nf((short*)(dest), (short)(exchange), (short)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange16_acq((short*)(dest), (short)(exchange), (short)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELEASE(dest, exchange, compare) _InterlockedCompareExchange16_rel((short*)(dest), (short)(exchange), (short)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELAXED(dest, exchange, compare) _InterlockedCompareExchange_nf((long*)(dest), (long)(exchange), (long)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange_acq((long*)(dest), (long)(exchange), (long)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELEASE(dest, exchange, compare) _InterlockedCompareExchange_rel((long*)(dest), (long)(exchange), (long)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELAXED(dest, exchange, compare) _InterlockedCompareExchange64_nf((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange64_acq((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELEASE(dest, exchange, compare) _InterlockedCompareExchange64_rel((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) _InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_RELAXED(dest, exchange, compare) _InterlockedCompareExchangePointer_nf((void**)(dest), (void*)(exchange), (void*)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchangePointer_acq((void**)(dest), (void*)(exchange), (void*)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_RELEASE(dest, exchange, compare) _InterlockedCompareExchangePointer_rel((void**)(dest), (void*)(exchange), (void*)(compare)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedExchangeAdd8_nf) +#pragma intrinsic(_InterlockedExchangeAdd8_acq) +#pragma intrinsic(_InterlockedExchangeAdd8_rel) +#pragma intrinsic(_InterlockedExchangeAdd16_nf) +#pragma intrinsic(_InterlockedExchangeAdd16_acq) +#pragma intrinsic(_InterlockedExchangeAdd16_rel) +#pragma intrinsic(_InterlockedExchangeAdd_nf) +#pragma intrinsic(_InterlockedExchangeAdd_acq) +#pragma intrinsic(_InterlockedExchangeAdd_rel) +#pragma intrinsic(_InterlockedExchangeAdd64_nf) +#pragma intrinsic(_InterlockedExchangeAdd64_acq) +#pragma intrinsic(_InterlockedExchangeAdd64_rel) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELAXED(dest, addend) _InterlockedExchangeAdd8_nf((char*)(dest), (char)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_ACQUIRE(dest, addend) _InterlockedExchangeAdd8_acq((char*)(dest), (char)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELEASE(dest, addend) _InterlockedExchangeAdd8_rel((char*)(dest), (char)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELAXED(dest, addend) _InterlockedExchangeAdd16_nf((short*)(dest), (short)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_ACQUIRE(dest, addend) _InterlockedExchangeAdd16_acq((short*)(dest), (short)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELEASE(dest, addend) _InterlockedExchangeAdd16_rel((short*)(dest), (short)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED(dest, addend) _InterlockedExchangeAdd_nf((long*)(dest), (long)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE(dest, addend) _InterlockedExchangeAdd_acq((long*)(dest), (long)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE(dest, addend) _InterlockedExchangeAdd_rel((long*)(dest), (long)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED(dest, addend) _InterlockedExchangeAdd64_nf((__int64*)(dest), (__int64)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE(dest, addend) _InterlockedExchangeAdd64_acq((__int64*)(dest), (__int64)(addend)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE(dest, addend) _InterlockedExchangeAdd64_rel((__int64*)(dest), (__int64)(addend)) + +#if defined(_M_ARM64) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64((__int64*)(dest), byte_offset)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELAXED(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED((__int64*)(dest), byte_offset)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_ACQUIRE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE((__int64*)(dest), byte_offset)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELEASE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE((__int64*)(dest), byte_offset)) +#else +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELAXED(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED((long*)(dest), byte_offset)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_ACQUIRE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE((long*)(dest), byte_offset)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELEASE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE((long*)(dest), byte_offset)) +#endif + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedExchange8_nf) +#pragma intrinsic(_InterlockedExchange8_acq) +#pragma intrinsic(_InterlockedExchange16_nf) +#pragma intrinsic(_InterlockedExchange16_acq) +#pragma intrinsic(_InterlockedExchange_nf) +#pragma intrinsic(_InterlockedExchange_acq) +#pragma intrinsic(_InterlockedExchange64_nf) +#pragma intrinsic(_InterlockedExchange64_acq) +#pragma intrinsic(_InterlockedExchangePointer) +#pragma intrinsic(_InterlockedExchangePointer_nf) +#pragma intrinsic(_InterlockedExchangePointer_acq) +#if _MSC_VER >= 1800 +#pragma intrinsic(_InterlockedExchange8_rel) +#pragma intrinsic(_InterlockedExchange16_rel) +#pragma intrinsic(_InterlockedExchange_rel) +#pragma intrinsic(_InterlockedExchange64_rel) +#pragma intrinsic(_InterlockedExchangePointer_rel) +#endif +#endif + +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELAXED(dest, newval) _InterlockedExchange8_nf((char*)(dest), (char)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_ACQUIRE(dest, newval) _InterlockedExchange8_acq((char*)(dest), (char)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELAXED(dest, newval) _InterlockedExchange16_nf((short*)(dest), (short)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_ACQUIRE(dest, newval) _InterlockedExchange16_acq((short*)(dest), (short)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELAXED(dest, newval) _InterlockedExchange_nf((long*)(dest), (long)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ACQUIRE(dest, newval) _InterlockedExchange_acq((long*)(dest), (long)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELAXED(dest, newval) _InterlockedExchange64_nf((__int64*)(dest), (__int64)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_ACQUIRE(dest, newval) _InterlockedExchange64_acq((__int64*)(dest), (__int64)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) _InterlockedExchangePointer((void**)(dest), (void*)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELAXED(dest, newval) _InterlockedExchangePointer_nf((void**)(dest), (void*)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_ACQUIRE(dest, newval) _InterlockedExchangePointer_acq((void**)(dest), (void*)(newval)) + +#if _MSC_VER >= 1800 +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(dest, newval) _InterlockedExchange8_rel((char*)(dest), (char)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(dest, newval) _InterlockedExchange16_rel((short*)(dest), (short)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(dest, newval) _InterlockedExchange_rel((long*)(dest), (long)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(dest, newval) _InterlockedExchange64_rel((__int64*)(dest), (__int64)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELEASE(dest, newval) _InterlockedExchangePointer_rel((void**)(dest), (void*)(newval)) +#else +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(dest, newval) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(dest, newval) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) +#endif + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedAnd8_nf) +#pragma intrinsic(_InterlockedAnd8_acq) +#pragma intrinsic(_InterlockedAnd8_rel) +#pragma intrinsic(_InterlockedAnd16_nf) +#pragma intrinsic(_InterlockedAnd16_acq) +#pragma intrinsic(_InterlockedAnd16_rel) +#pragma intrinsic(_InterlockedAnd_nf) +#pragma intrinsic(_InterlockedAnd_acq) +#pragma intrinsic(_InterlockedAnd_rel) +#pragma intrinsic(_InterlockedAnd64_nf) +#pragma intrinsic(_InterlockedAnd64_acq) +#pragma intrinsic(_InterlockedAnd64_rel) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_AND8_RELAXED(dest, arg) _InterlockedAnd8_nf((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND8_ACQUIRE(dest, arg) _InterlockedAnd8_acq((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND8_RELEASE(dest, arg) _InterlockedAnd8_rel((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND16_RELAXED(dest, arg) _InterlockedAnd16_nf((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND16_ACQUIRE(dest, arg) _InterlockedAnd16_acq((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND16_RELEASE(dest, arg) _InterlockedAnd16_rel((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND_RELAXED(dest, arg) _InterlockedAnd_nf((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND_ACQUIRE(dest, arg) _InterlockedAnd_acq((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND_RELEASE(dest, arg) _InterlockedAnd_rel((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND64_RELAXED(dest, arg) _InterlockedAnd64_nf((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND64_ACQUIRE(dest, arg) _InterlockedAnd64_acq((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_AND64_RELEASE(dest, arg) _InterlockedAnd64_rel((__int64*)(dest), (__int64)(arg)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedOr8_nf) +#pragma intrinsic(_InterlockedOr8_acq) +#pragma intrinsic(_InterlockedOr8_rel) +#pragma intrinsic(_InterlockedOr16_nf) +#pragma intrinsic(_InterlockedOr16_acq) +#pragma intrinsic(_InterlockedOr16_rel) +#pragma intrinsic(_InterlockedOr_nf) +#pragma intrinsic(_InterlockedOr_acq) +#pragma intrinsic(_InterlockedOr_rel) +#pragma intrinsic(_InterlockedOr64_nf) +#pragma intrinsic(_InterlockedOr64_acq) +#pragma intrinsic(_InterlockedOr64_rel) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_OR8_RELAXED(dest, arg) _InterlockedOr8_nf((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR8_ACQUIRE(dest, arg) _InterlockedOr8_acq((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR8_RELEASE(dest, arg) _InterlockedOr8_rel((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR16_RELAXED(dest, arg) _InterlockedOr16_nf((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR16_ACQUIRE(dest, arg) _InterlockedOr16_acq((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR16_RELEASE(dest, arg) _InterlockedOr16_rel((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR_RELAXED(dest, arg) _InterlockedOr_nf((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR_ACQUIRE(dest, arg) _InterlockedOr_acq((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR_RELEASE(dest, arg) _InterlockedOr_rel((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR64_RELAXED(dest, arg) _InterlockedOr64_nf((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR64_ACQUIRE(dest, arg) _InterlockedOr64_acq((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_OR64_RELEASE(dest, arg) _InterlockedOr64_rel((__int64*)(dest), (__int64)(arg)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_InterlockedXor8_nf) +#pragma intrinsic(_InterlockedXor8_acq) +#pragma intrinsic(_InterlockedXor8_rel) +#pragma intrinsic(_InterlockedXor16_nf) +#pragma intrinsic(_InterlockedXor16_acq) +#pragma intrinsic(_InterlockedXor16_rel) +#pragma intrinsic(_InterlockedXor_nf) +#pragma intrinsic(_InterlockedXor_acq) +#pragma intrinsic(_InterlockedXor_rel) +#pragma intrinsic(_InterlockedXor64_nf) +#pragma intrinsic(_InterlockedXor64_acq) +#pragma intrinsic(_InterlockedXor64_rel) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_XOR8_RELAXED(dest, arg) _InterlockedXor8_nf((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR8_ACQUIRE(dest, arg) _InterlockedXor8_acq((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR8_RELEASE(dest, arg) _InterlockedXor8_rel((char*)(dest), (char)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR16_RELAXED(dest, arg) _InterlockedXor16_nf((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR16_ACQUIRE(dest, arg) _InterlockedXor16_acq((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR16_RELEASE(dest, arg) _InterlockedXor16_rel((short*)(dest), (short)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR_RELAXED(dest, arg) _InterlockedXor_nf((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR_ACQUIRE(dest, arg) _InterlockedXor_acq((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR_RELEASE(dest, arg) _InterlockedXor_rel((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR64_RELAXED(dest, arg) _InterlockedXor64_nf((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR64_ACQUIRE(dest, arg) _InterlockedXor64_acq((__int64*)(dest), (__int64)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_XOR64_RELEASE(dest, arg) _InterlockedXor64_rel((__int64*)(dest), (__int64)(arg)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_interlockedbittestandset_nf) +#pragma intrinsic(_interlockedbittestandset_acq) +#pragma intrinsic(_interlockedbittestandset_rel) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED(dest, arg) _interlockedbittestandset_nf((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE(dest, arg) _interlockedbittestandset_acq((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE(dest, arg) _interlockedbittestandset_rel((long*)(dest), (long)(arg)) + +#if defined(BOOST_MSVC) +#pragma intrinsic(_interlockedbittestandreset_nf) +#pragma intrinsic(_interlockedbittestandreset_acq) +#pragma intrinsic(_interlockedbittestandreset_rel) +#endif + +#define BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED(dest, arg) _interlockedbittestandreset_nf((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE(dest, arg) _interlockedbittestandreset_acq((long*)(dest), (long)(arg)) +#define BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE(dest, arg) _interlockedbittestandreset_rel((long*)(dest), (long)(arg)) + +#endif // _MSC_VER >= 1700 && defined(_M_ARM) + +#endif // _MSC_VER < 1400 + +#else // defined(_MSC_VER) && _MSC_VER >= 1310 + +#if defined(BOOST_USE_WINDOWS_H) + +#include + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) InterlockedExchange((long*)(dest), (long)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) InterlockedExchangeAdd((long*)(dest), (long)(addend)) + +#if defined(_WIN64) + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) InterlockedExchange64((__int64*)(dest), (__int64)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) InterlockedExchangePointer((void**)(dest), (void*)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset)) + +#else // defined(_WIN64) + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset)) + +#endif // defined(_WIN64) + +#else // defined(BOOST_USE_WINDOWS_H) + +#if defined(__MINGW64__) +#define BOOST_ATOMIC_INTERLOCKED_IMPORT +#else +#define BOOST_ATOMIC_INTERLOCKED_IMPORT __declspec(dllimport) +#endif + +namespace boost { +namespace atomics { +namespace detail { + +extern "C" { + +BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange(long volatile*, long, long); +BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchange(long volatile*, long); +BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd(long volatile*, long); + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) boost::atomics::detail::InterlockedExchange((long*)(dest), (long)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) boost::atomics::detail::InterlockedExchangeAdd((long*)(dest), (long)(addend)) + +#if defined(_WIN64) + +BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedCompareExchange64(__int64 volatile*, __int64, __int64); +BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchange64(__int64 volatile*, __int64); +BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchangeAdd64(__int64 volatile*, __int64); + +BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer(void* volatile *, void*, void*); +BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer(void* volatile *, void*); + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) boost::atomics::detail::InterlockedExchange64((__int64*)(dest), (__int64)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) boost::atomics::detail::InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) boost::atomics::detail::InterlockedExchangePointer((void**)(dest), (void*)(newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset)) + +#else // defined(_WIN64) + +#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval)) +#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset)) + +#endif // defined(_WIN64) + +} // extern "C" + +} // namespace detail +} // namespace atomics +} // namespace boost + +#undef BOOST_ATOMIC_INTERLOCKED_IMPORT + +#endif // defined(BOOST_USE_WINDOWS_H) + +#endif // defined(_MSC_VER) + +#endif diff --git a/boost/atomic/detail/link.hpp b/boost/atomic/detail/link.hpp new file mode 100644 index 00000000..4f522acb --- /dev/null +++ b/boost/atomic/detail/link.hpp @@ -0,0 +1,58 @@ +/* + * 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) + * + * Copyright (c) 2012 Hartmut Kaiser + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/config.hpp + * + * This header defines macros for linking with compiled library of Boost.Atomic + */ + +#ifndef BOOST_ATOMIC_DETAIL_LINK_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_LINK_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Set up dll import/export options +#if (defined(BOOST_ATOMIC_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \ + !defined(BOOST_ATOMIC_STATIC_LINK) + +#if defined(BOOST_ATOMIC_SOURCE) +#define BOOST_ATOMIC_DECL BOOST_SYMBOL_EXPORT +#define BOOST_ATOMIC_BUILD_DLL +#else +#define BOOST_ATOMIC_DECL BOOST_SYMBOL_IMPORT +#endif + +#endif // building a shared library + +#ifndef BOOST_ATOMIC_DECL +#define BOOST_ATOMIC_DECL +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Auto library naming +#if !defined(BOOST_ATOMIC_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_ATOMIC_NO_LIB) + +#define BOOST_LIB_NAME boost_atomic + +// tell the auto-link code to select a dll when required: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ATOMIC_DYN_LINK) +#define BOOST_DYN_LINK +#endif + +#include + +#endif // auto-linking disabled + +#endif diff --git a/boost/atomic/detail/lockpool.hpp b/boost/atomic/detail/lockpool.hpp new file mode 100644 index 00000000..4e249aa0 --- /dev/null +++ b/boost/atomic/detail/lockpool.hpp @@ -0,0 +1,51 @@ +/* + * 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) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013-2014 Andrey Semashev + */ +/*! + * \file atomic/detail/lockpool.hpp + * + * This header contains declaration of the lockpool used to emulate atomic ops. + */ + +#ifndef BOOST_ATOMIC_DETAIL_LOCKPOOL_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_LOCKPOOL_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +struct lockpool +{ + class scoped_lock + { + void* m_lock; + + public: + explicit BOOST_ATOMIC_DECL scoped_lock(const volatile void* addr) BOOST_NOEXCEPT; + BOOST_ATOMIC_DECL ~scoped_lock() BOOST_NOEXCEPT; + + BOOST_DELETED_FUNCTION(scoped_lock(scoped_lock const&)) + BOOST_DELETED_FUNCTION(scoped_lock& operator=(scoped_lock const&)) + }; + + static BOOST_ATOMIC_DECL void thread_fence() BOOST_NOEXCEPT; + static BOOST_ATOMIC_DECL void signal_fence() BOOST_NOEXCEPT; +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_LOCKPOOL_HPP_INCLUDED_ diff --git a/boost/atomic/detail/operations.hpp b/boost/atomic/detail/operations.hpp new file mode 100644 index 00000000..d81399a8 --- /dev/null +++ b/boost/atomic/detail/operations.hpp @@ -0,0 +1,24 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/operations.hpp + * + * This header defines atomic operations, including the emulated version. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/operations_fwd.hpp b/boost/atomic/detail/operations_fwd.hpp new file mode 100644 index 00000000..efd49707 --- /dev/null +++ b/boost/atomic/detail/operations_fwd.hpp @@ -0,0 +1,35 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/operations_fwd.hpp + * + * This header contains forward declaration of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< std::size_t Size, bool Signed > +struct operations; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_ diff --git a/boost/atomic/detail/operations_lockfree.hpp b/boost/atomic/detail/operations_lockfree.hpp new file mode 100644 index 00000000..62b45836 --- /dev/null +++ b/boost/atomic/detail/operations_lockfree.hpp @@ -0,0 +1,30 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/operations_lockfree.hpp + * + * This header defines lockfree atomic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_ + +#include +#include + +#if !defined(BOOST_ATOMIC_EMULATED) +#include BOOST_ATOMIC_DETAIL_BACKEND_HEADER(boost/atomic/detail/ops_) +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_cas_based.hpp b/boost/atomic/detail/ops_cas_based.hpp new file mode 100644 index 00000000..e2e18aa3 --- /dev/null +++ b/boost/atomic/detail/ops_cas_based.hpp @@ -0,0 +1,107 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_cas_based.hpp + * + * This header contains CAS-based implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_ + +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base > +struct cas_based_exchange : + public Base +{ + typedef typename Base::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!Base::compare_exchange_weak(storage, old_val, v, order, memory_order_relaxed)) {} + return old_val; + } +}; + +template< typename Base > +struct cas_based_operations : + public Base +{ + typedef typename Base::storage_type storage_type; + + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!Base::compare_exchange_weak(storage, old_val, old_val + v, order, memory_order_relaxed)) {} + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!Base::compare_exchange_weak(storage, old_val, old_val - v, order, memory_order_relaxed)) {} + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!Base::compare_exchange_weak(storage, old_val, old_val & v, order, memory_order_relaxed)) {} + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!Base::compare_exchange_weak(storage, old_val, old_val | v, order, memory_order_relaxed)) {} + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!Base::compare_exchange_weak(storage, old_val, old_val ^ v, order, memory_order_relaxed)) {} + return old_val; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!Base::exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + Base::store(storage, (storage_type)0, order); + } +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_emulated.hpp b/boost/atomic/detail/ops_emulated.hpp new file mode 100644 index 00000000..f30fbdab --- /dev/null +++ b/boost/atomic/detail/ops_emulated.hpp @@ -0,0 +1,162 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_emulated.hpp + * + * This header contains lockpool-based implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< std::size_t Size, bool Signed > +struct emulated_operations +{ + typedef typename make_storage_type< Size >::type storage_type; + typedef typename make_storage_type< Size >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = false; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + lockpool::scoped_lock lock(&storage); + const_cast< storage_type& >(storage) = v; + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT + { + lockpool::scoped_lock lock(&storage); + return const_cast< storage_type const& >(storage); + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s += v; + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s -= v; + return old_val; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s = v; + return old_val; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + const bool res = old_val == expected; + if (res) + s = desired; + expected = old_val; + + return res; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + // Note: This function is the exact copy of compare_exchange_strong. The reason we're not just forwarding the call + // is that MSVC-12 ICEs in this case. + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + const bool res = old_val == expected; + if (res) + s = desired; + expected = old_val; + + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s &= v; + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s |= v; + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type& s = const_cast< storage_type& >(storage); + lockpool::scoped_lock lock(&storage); + storage_type old_val = s; + s ^= v; + return old_val; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, (storage_type)0, order); + } +}; + +template< std::size_t Size, bool Signed > +struct operations : + public emulated_operations< Size, Signed > +{ +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_extending_cas_based.hpp b/boost/atomic/detail/ops_extending_cas_based.hpp new file mode 100644 index 00000000..5f197cea --- /dev/null +++ b/boost/atomic/detail/ops_extending_cas_based.hpp @@ -0,0 +1,69 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_extending_cas_based.hpp + * + * This header contains a boilerplate of the \c operations template implementation that requires sign/zero extension in arithmetic operations. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ + +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base, std::size_t Size, bool Signed > +struct extending_cas_based_operations : + public Base +{ + typedef typename Base::storage_type storage_type; + typedef typename make_storage_type< Size >::type emulated_storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + storage_type new_val; + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v)); + } + while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return old_val; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + storage_type new_val; + do + { + new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v)); + } + while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); + return old_val; + } +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_alpha.hpp b/boost/atomic/detail/ops_gcc_alpha.hpp new file mode 100644 index 00000000..85b13429 --- /dev/null +++ b/boost/atomic/detail/ops_gcc_alpha.hpp @@ -0,0 +1,876 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_alpha.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +/* + Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html + (HP OpenVMS systems documentation) and the Alpha Architecture Reference Manual. + */ + +/* + NB: The most natural thing would be to write the increment/decrement + operators along the following lines: + + __asm__ __volatile__ + ( + "1: ldl_l %0,%1 \n" + "addl %0,1,%0 \n" + "stl_c %0,%1 \n" + "beq %0,1b\n" + : "=&b" (tmp) + : "m" (value) + : "cc" + ); + + However according to the comments on the HP website and matching + comments in the Linux kernel sources this defies branch prediction, + as the cpu assumes that backward branches are always taken; so + instead copy the trick from the Linux kernel, introduce a forward + branch and back again. + + I have, however, had a hard time measuring the difference between + the two versions in microbenchmarks -- I am leaving it in nevertheless + as it apparently does not hurt either. +*/ + +struct gcc_alpha_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __asm__ __volatile__ ("mb" ::: "memory"); + } + + static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + __asm__ __volatile__ ("mb" ::: "memory"); + } + + static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("mb" ::: "memory"); + } +}; + + +template< bool Signed > +struct operations< 4u, Signed > : + public gcc_alpha_operations_base +{ + typedef typename make_storage_type< 4u >::type storage_type; + typedef typename make_storage_type< 4u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, tmp; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "mov %3, %1\n" + "ldl_l %0, %2\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (tmp) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + int success; + storage_type current; + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %2, %4\n" // current = *(&storage) + "cmpeq %2, %0, %3\n" // success = current == expected + "mov %2, %0\n" // expected = current + "beq %3, 2f\n" // if (success == 0) goto end + "stl_c %1, %4\n" // storage = desired; desired = store succeeded + "mov %1, %3\n" // success = desired + "2:\n" + : "+&r" (expected), // %0 + "+&r" (desired), // %1 + "=&r" (current), // %2 + "=&r" (success) // %3 + : "m" (storage) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + storage_type current, tmp; + fence_before(success_order); + __asm__ __volatile__ + ( + "1:\n" + "mov %5, %1\n" // tmp = desired + "ldl_l %2, %4\n" // current = *(&storage) + "cmpeq %2, %0, %3\n" // success = current == expected + "mov %2, %0\n" // expected = current + "beq %3, 2f\n" // if (success == 0) goto end + "stl_c %1, %4\n" // storage = tmp; tmp = store succeeded + "beq %1, 3f\n" // if (tmp == 0) goto retry + "mov %1, %3\n" // success = tmp + "2:\n" + + ".subsection 2\n" + "3: br 1b\n" + ".previous\n" + + : "+&r" (expected), // %0 + "=&r" (tmp), // %1 + "=&r" (current), // %2 + "=&r" (success) // %3 + : "m" (storage), // %4 + "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "addl %0, %3, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "subl %0, %3, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "and %0, %3, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "bis %0, %3, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "xor %0, %3, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + + +template< > +struct operations< 1u, false > : + public operations< 4u, false > +{ + typedef operations< 4u, false > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "addl %0, %3, %1\n" + "zapnot %1, #1, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "subl %0, %3, %1\n" + "zapnot %1, #1, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +template< > +struct operations< 1u, true > : + public operations< 4u, true > +{ + typedef operations< 4u, true > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "addl %0, %3, %1\n" + "sextb %1, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "subl %0, %3, %1\n" + "sextb %1, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + + +template< > +struct operations< 2u, false > : + public operations< 4u, false > +{ + typedef operations< 4u, false > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "addl %0, %3, %1\n" + "zapnot %1, #3, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "subl %0, %3, %1\n" + "zapnot %1, #3, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +template< > +struct operations< 2u, true > : + public operations< 4u, true > +{ + typedef operations< 4u, true > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "addl %0, %3, %1\n" + "sextw %1, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldl_l %0, %2\n" + "subl %0, %3, %1\n" + "sextw %1, %1\n" + "stl_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + + +template< bool Signed > +struct operations< 8u, Signed > : + public gcc_alpha_operations_base +{ + typedef typename make_storage_type< 8u >::type storage_type; + typedef typename make_storage_type< 8u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, tmp; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "mov %3, %1\n" + "ldq_l %0, %2\n" + "stq_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (tmp) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + int success; + storage_type current; + __asm__ __volatile__ + ( + "1:\n" + "ldq_l %2, %4\n" // current = *(&storage) + "cmpeq %2, %0, %3\n" // success = current == expected + "mov %2, %0\n" // expected = current + "beq %3, 2f\n" // if (success == 0) goto end + "stq_c %1, %4\n" // storage = desired; desired = store succeeded + "mov %1, %3\n" // success = desired + "2:\n" + : "+&r" (expected), // %0 + "+&r" (desired), // %1 + "=&r" (current), // %2 + "=&r" (success) // %3 + : "m" (storage) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + storage_type current, tmp; + fence_before(success_order); + __asm__ __volatile__ + ( + "1:\n" + "mov %5, %1\n" // tmp = desired + "ldq_l %2, %4\n" // current = *(&storage) + "cmpeq %2, %0, %3\n" // success = current == expected + "mov %2, %0\n" // expected = current + "beq %3, 2f\n" // if (success == 0) goto end + "stq_c %1, %4\n" // storage = tmp; tmp = store succeeded + "beq %1, 3f\n" // if (tmp == 0) goto retry + "mov %1, %3\n" // success = tmp + "2:\n" + + ".subsection 2\n" + "3: br 1b\n" + ".previous\n" + + : "+&r" (expected), // %0 + "=&r" (tmp), // %1 + "=&r" (current), // %2 + "=&r" (success) // %3 + : "m" (storage), // %4 + "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldq_l %0, %2\n" + "addq %0, %3, %1\n" + "stq_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldq_l %0, %2\n" + "subq %0, %3, %1\n" + "stq_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldq_l %0, %2\n" + "and %0, %3, %1\n" + "stq_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldq_l %0, %2\n" + "bis %0, %3, %1\n" + "stq_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, modified; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n" + "ldq_l %0, %2\n" + "xor %0, %3, %1\n" + "stq_c %1, %2\n" + "beq %1, 2f\n" + + ".subsection 2\n" + "2: br 1b\n" + ".previous\n" + + : "=&r" (original), // %0 + "=&r" (modified) // %1 + : "m" (storage), // %2 + "r" (v) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __asm__ __volatile__ ("mb" ::: "memory"); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __asm__ __volatile__ ("" ::: "memory"); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_arm.hpp b/boost/atomic/detail/ops_gcc_arm.hpp new file mode 100644 index 00000000..b3215953 --- /dev/null +++ b/boost/atomic/detail/ops_gcc_arm.hpp @@ -0,0 +1,1397 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_arm.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +// From the ARM Architecture Reference Manual for architecture v6: +// +// LDREX{} , [] +// Specifies the destination register for the memory word addressed by +// Specifies the register containing the address. +// +// STREX{} , , [] +// Specifies the destination register for the returned status value. +// 0 if the operation updates memory +// 1 if the operation fails to update memory +// Specifies the register containing the word to be stored to memory. +// Specifies the register containing the address. +// Rd must not be the same register as Rm or Rn. +// +// ARM v7 is like ARM v6 plus: +// There are half-word and byte versions of the LDREX and STREX instructions, +// LDREXH, LDREXB, STREXH and STREXB. +// There are also double-word versions, LDREXD and STREXD. +// (Actually it looks like these are available from version 6k onwards.) +// FIXME these are not yet used; should be mostly a matter of copy-and-paste. +// I think you can supply an immediate offset to the address. + +template< bool Signed > +struct operations< 4u, Signed > : + public gcc_arm_operations_base +{ + typedef typename make_storage_type< 4u >::type storage_type; + typedef typename make_storage_type< 4u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original; + fence_before(order); + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // load the original value + "strex %[tmp], %[value], %[storage]\n" // store the replacement, tmp = store failed + "teq %[tmp], #0\n" // check if store succeeded + "bne 1b\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [tmp] "=&l" (tmp), [original] "=&r" (original), [storage] "+Q" (storage) + : [value] "r" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t success; + uint32_t tmp; + storage_type original; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "mov %[success], #0\n" // success = 0 + "ldrex %[original], %[storage]\n" // original = *(&storage) + "cmp %[original], %[expected]\n" // flags = original==expected + "itt eq\n" // [hint that the following 2 instructions are conditional on flags.equal] + "strexeq %[success], %[desired], %[storage]\n" // if (flags.equal) *(&storage) = desired, success = store failed + "eoreq %[success], %[success], #1\n" // if (flags.equal) success ^= 1 (i.e. make it 1 if store succeeded) + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [success] "=&r" (success), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [expected] "Ir" (expected), // %4 + [desired] "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = original; + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t success; + uint32_t tmp; + storage_type original; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "mov %[success], #0\n" // success = 0 + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "cmp %[original], %[expected]\n" // flags = original==expected + "bne 2f\n" // if (!flags.equal) goto end + "strex %[success], %[desired], %[storage]\n" // *(&storage) = desired, success = store failed + "eors %[success], %[success], #1\n" // success ^= 1 (i.e. make it 1 if store succeeded); flags.equal = success == 0 + "beq 1b\n" // if (flags.equal) goto retry + "2:\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [success] "=&r" (success), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [expected] "Ir" (expected), // %4 + [desired] "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = original; + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "add %[result], %[original], %[value]\n" // result = original + value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "sub %[result], %[original], %[value]\n" // result = original - value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "and %[result], %[original], %[value]\n" // result = original & value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "orr %[result], %[original], %[value]\n" // result = original | value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "eor %[result], %[original], %[value]\n" // result = original ^ value + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB) + +template< bool Signed > +struct operations< 1u, Signed > : + public gcc_arm_operations_base +{ + typedef typename make_storage_type< 1u >::type storage_type; + typedef typename make_storage_type< 1u >::aligned aligned_storage_type; + typedef typename make_storage_type< 4u >::type extended_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + extended_storage_type original; + fence_before(order); + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // load the original value and zero-extend to 32 bits + "strexb %[tmp], %[value], %[storage]\n" // store the replacement, tmp = store failed + "teq %[tmp], #0\n" // check if store succeeded + "bne 1b\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [tmp] "=&l" (tmp), [original] "=&r" (original), [storage] "+Q" (storage) + : [value] "r" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t success; + uint32_t tmp; + extended_storage_type original; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "mov %[success], #0\n" // success = 0 + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "cmp %[original], %[expected]\n" // flags = original==expected + "itt eq\n" // [hint that the following 2 instructions are conditional on flags.equal] + "strexbeq %[success], %[desired], %[storage]\n" // if (flags.equal) *(&storage) = desired, success = store failed + "eoreq %[success], %[success], #1\n" // if (flags.equal) success ^= 1 (i.e. make it 1 if store succeeded) + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [success] "=&r" (success), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)), // %4 + [desired] "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = static_cast< storage_type >(original); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t success; + uint32_t tmp; + extended_storage_type original; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "mov %[success], #0\n" // success = 0 + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "cmp %[original], %[expected]\n" // flags = original==expected + "bne 2f\n" // if (!flags.equal) goto end + "strexb %[success], %[desired], %[storage]\n" // *(&storage) = desired, success = store failed + "eors %[success], %[success], #1\n" // success ^= 1 (i.e. make it 1 if store succeeded); flags.equal = success == 0 + "beq 1b\n" // if (flags.equal) goto retry + "2:\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [success] "=&r" (success), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)), // %4 + [desired] "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = static_cast< storage_type >(original); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "add %[result], %[original], %[value]\n" // result = original + value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "sub %[result], %[original], %[value]\n" // result = original - value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "and %[result], %[original], %[value]\n" // result = original & value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "orr %[result], %[original], %[value]\n" // result = original | value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexb %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "eor %[result], %[original], %[value]\n" // result = original ^ value + "strexb %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#else // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB) + +template< > +struct operations< 1u, false > : + public operations< 4u, false > +{ + typedef operations< 4u, false > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "add %[result], %[original], %[value]\n" // result = original + value + "uxtb %[result], %[result]\n" // zero extend result from 8 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "sub %[result], %[original], %[value]\n" // result = original - value + "uxtb %[result], %[result]\n" // zero extend result from 8 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +template< > +struct operations< 1u, true > : + public operations< 4u, true > +{ + typedef operations< 4u, true > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "add %[result], %[original], %[value]\n" // result = original + value + "sxtb %[result], %[result]\n" // sign extend result from 8 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "sub %[result], %[original], %[value]\n" // result = original - value + "sxtb %[result], %[result]\n" // sign extend result from 8 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB) + +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH) + +template< bool Signed > +struct operations< 2u, Signed > : + public gcc_arm_operations_base +{ + typedef typename make_storage_type< 2u >::type storage_type; + typedef typename make_storage_type< 2u >::aligned aligned_storage_type; + typedef typename make_storage_type< 4u >::type extended_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + extended_storage_type original; + fence_before(order); + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // load the original value and zero-extend to 32 bits + "strexh %[tmp], %[value], %[storage]\n" // store the replacement, tmp = store failed + "teq %[tmp], #0\n" // check if store succeeded + "bne 1b\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [tmp] "=&l" (tmp), [original] "=&r" (original), [storage] "+Q" (storage) + : [value] "r" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t success; + uint32_t tmp; + extended_storage_type original; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "mov %[success], #0\n" // success = 0 + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "cmp %[original], %[expected]\n" // flags = original==expected + "itt eq\n" // [hint that the following 2 instructions are conditional on flags.equal] + "strexheq %[success], %[desired], %[storage]\n" // if (flags.equal) *(&storage) = desired, success = store failed + "eoreq %[success], %[success], #1\n" // if (flags.equal) success ^= 1 (i.e. make it 1 if store succeeded) + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [success] "=&r" (success), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)), // %4 + [desired] "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = static_cast< storage_type >(original); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t success; + uint32_t tmp; + extended_storage_type original; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "mov %[success], #0\n" // success = 0 + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "cmp %[original], %[expected]\n" // flags = original==expected + "bne 2f\n" // if (!flags.equal) goto end + "strexh %[success], %[desired], %[storage]\n" // *(&storage) = desired, success = store failed + "eors %[success], %[success], #1\n" // success ^= 1 (i.e. make it 1 if store succeeded); flags.equal = success == 0 + "beq 1b\n" // if (flags.equal) goto retry + "2:\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [success] "=&r" (success), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)), // %4 + [desired] "r" (desired) // %5 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = static_cast< storage_type >(original); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "add %[result], %[original], %[value]\n" // result = original + value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "sub %[result], %[original], %[value]\n" // result = original - value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "and %[result], %[original], %[value]\n" // result = original & value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "orr %[result], %[original], %[value]\n" // result = original | value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + extended_storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrexh %[original], %[storage]\n" // original = zero_extend(*(&storage)) + "eor %[result], %[original], %[value]\n" // result = original ^ value + "strexh %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return static_cast< storage_type >(original); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#else // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH) + +template< > +struct operations< 2u, false > : + public operations< 4u, false > +{ + typedef operations< 4u, false > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "add %[result], %[original], %[value]\n" // result = original + value + "uxth %[result], %[result]\n" // zero extend result from 16 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "sub %[result], %[original], %[value]\n" // result = original - value + "uxth %[result], %[result]\n" // zero extend result from 16 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +template< > +struct operations< 2u, true > : + public operations< 4u, true > +{ + typedef operations< 4u, true > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "add %[result], %[original], %[value]\n" // result = original + value + "sxth %[result], %[result]\n" // sign extend result from 16 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + uint32_t tmp; + storage_type original, result; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp]) + "1:\n" + "ldrex %[original], %[storage]\n" // original = *(&storage) + "sub %[result], %[original], %[value]\n" // result = original - value + "sxth %[result], %[result]\n" // sign extend result from 16 to 32 bits + "strex %[tmp], %[result], %[storage]\n" // *(&storage) = result, tmp = store failed + "teq %[tmp], #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp]) + : [original] "=&r" (original), // %0 + [result] "=&r" (result), // %1 + [tmp] "=&l" (tmp), // %2 + [storage] "+Q" (storage) // %3 + : [value] "Ir" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH) + +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) + +// Unlike 32-bit operations, for 64-bit loads and stores we must use ldrexd/strexd. +// Any other instructions result in a non-atomic sequence of 32-bit accesses. +// See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition", +// Section A3.5.3 "Atomicity in the ARM architecture". + +// In the asm blocks below we have to use 32-bit register pairs to compose 64-bit values. +// In order to pass the 64-bit operands to/from asm blocks, we use undocumented gcc feature: +// the lower half (Rt) of the operand is accessible normally, via the numbered placeholder (e.g. %0), +// and the upper half (Rt2) - via the same placeholder with an 'H' after the '%' sign (e.g. %H0). +// See: http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/ + +template< bool Signed > +struct operations< 8u, Signed > : + public gcc_arm_operations_base +{ + typedef typename make_storage_type< 8u >::type storage_type; + typedef typename make_storage_type< 8u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + exchange(storage, v, order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type original; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "ldrexd %1, %H1, [%2]\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original) // %1 + : "r" (&storage) // %2 + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original; + fence_before(order); + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // load the original value + "strexd %0, %2, %H2, [%3]\n" // store the replacement, tmp = store failed + "teq %0, #0\n" // check if store succeeded + "bne 1b\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original) // %1 + : "r" (v), // %2 + "r" (&storage) // %3 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t tmp; + storage_type original, old_val = expected; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "cmp %1, %2\n" // flags = original.lo==old_val.lo + "ittt eq\n" // [hint that the following 3 instructions are conditional on flags.equal] + "cmpeq %H1, %H2\n" // if (flags.equal) flags = original.hi==old_val.hi + "strexdeq %0, %4, %H4, [%3]\n" // if (flags.equal) *(&storage) = desired, tmp = store failed + "teqeq %0, #0\n" // if (flags.equal) flags = tmp==0 + "ite eq\n" // [hint that the following 2 instructions are conditional on flags.equal] + "moveq %2, #1\n" // if (flags.equal) old_val.lo = 1 + "movne %2, #0\n" // if (!flags.equal) old_val.lo = 0 + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "+r" (old_val) // %2 + : "r" (&storage), // %3 + "r" (desired) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + const uint32_t success = (uint32_t)old_val; + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = original; + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + uint32_t tmp; + storage_type original, old_val = expected; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "cmp %1, %2\n" // flags = original.lo==old_val.lo + "it eq\n" // [hint that the following instruction is conditional on flags.equal] + "cmpeq %H1, %H2\n" // if (flags.equal) flags = original.hi==old_val.hi + "bne 2f\n" // if (!flags.equal) goto end + "strexd %0, %4, %H4, [%3]\n" // *(&storage) = desired, tmp = store failed + "teq %0, #0\n" // flags.equal = tmp == 0 + "bne 1b\n" // if (flags.equal) goto retry + "2:\n" + "ite eq\n" // [hint that the following 2 instructions are conditional on flags.equal] + "moveq %2, #1\n" // if (flags.equal) old_val.lo = 1 + "movne %2, #0\n" // if (!flags.equal) old_val.lo = 0 + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "+r" (old_val) // %2 + : "r" (&storage), // %3 + "r" (desired) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + const uint32_t success = (uint32_t)old_val; + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = original; + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "adds %2, %1, %4\n" // result = original + value + "adc %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "subs %2, %1, %4\n" // result = original - value + "sbc %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "and %2, %1, %4\n" // result = original & value + "and %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "orr %2, %1, %4\n" // result = original | value + "orr %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage_type original, result; + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "1:\n" + "ldrexd %1, %H1, [%3]\n" // original = *(&storage) + "eor %2, %1, %4\n" // result = original ^ value + "eor %H2, %H1, %H4\n" + "strexd %0, %2, %H2, [%3]\n" // *(&storage) = result, tmp = store failed + "teq %0, #0\n" // flags = tmp==0 + "bne 1b\n" // if (!flags.equal) goto retry + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0 + "=&r" (original), // %1 + "=&r" (result) // %2 + : "r" (&storage), // %3 + "r" (v) // %4 + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD) + + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + gcc_arm_operations_base::hardware_full_fence(); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __asm__ __volatile__ ("" ::: "memory"); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_arm_common.hpp b/boost/atomic/detail/ops_gcc_arm_common.hpp new file mode 100644 index 00000000..73c04ffe --- /dev/null +++ b/boost/atomic/detail/ops_gcc_arm_common.hpp @@ -0,0 +1,134 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_arm_common.hpp + * + * This header contains basic utilities for gcc ARM backend. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_COMMON_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_COMMON_HPP_INCLUDED_ + +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +// A memory barrier is effected using a "co-processor 15" instruction, +// though a separate assembler mnemonic is available for it in v7. +// +// "Thumb 1" is a subset of the ARM instruction set that uses a 16-bit encoding. It +// doesn't include all instructions and in particular it doesn't include the co-processor +// instruction used for the memory barrier or the load-locked/store-conditional +// instructions. So, if we're compiling in "Thumb 1" mode, we need to wrap all of our +// asm blocks with code to temporarily change to ARM mode. +// +// You can only change between ARM and Thumb modes when branching using the bx instruction. +// bx takes an address specified in a register. The least significant bit of the address +// indicates the mode, so 1 is added to indicate that the destination code is Thumb. +// A temporary register is needed for the address and is passed as an argument to these +// macros. It must be one of the "low" registers accessible to Thumb code, specified +// using the "l" attribute in the asm statement. +// +// Architecture v7 introduces "Thumb 2", which does include (almost?) all of the ARM +// instruction set. (Actually, there was an extension of v6 called v6T2 which supported +// "Thumb 2" mode, but its architecture manual is no longer available, referring to v7.) +// So in v7 we don't need to change to ARM mode; we can write "universal +// assembler" which will assemble to Thumb 2 or ARM code as appropriate. The only thing +// we need to do to make this "universal" assembler mode work is to insert "IT" instructions +// to annotate the conditional instructions. These are ignored in other modes (e.g. v6), +// so they can always be present. + +// A note about memory_order_consume. Technically, this architecture allows to avoid +// unnecessary memory barrier after consume load since it supports data dependency ordering. +// However, some compiler optimizations may break a seemingly valid code relying on data +// dependency tracking by injecting bogus branches to aid out of order execution. +// This may happen not only in Boost.Atomic code but also in user's code, which we have no +// control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php. +// For this reason we promote memory_order_consume to memory_order_acquire. + +#if defined(__thumb__) && !defined(__thumb2__) +#define BOOST_ATOMIC_DETAIL_ARM_ASM_START(TMPREG) "adr " #TMPREG ", 8f\n" "bx " #TMPREG "\n" ".arm\n" ".align 4\n" "8:\n" +#define BOOST_ATOMIC_DETAIL_ARM_ASM_END(TMPREG) "adr " #TMPREG ", 9f + 1\n" "bx " #TMPREG "\n" ".thumb\n" ".align 2\n" "9:\n" +#define BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(var) "=&l" (var) +#else +// The tmpreg may be wasted in this case, which is non-optimal. +#define BOOST_ATOMIC_DETAIL_ARM_ASM_START(TMPREG) +#define BOOST_ATOMIC_DETAIL_ARM_ASM_END(TMPREG) +#define BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(var) "=&r" (var) +#endif + +struct gcc_arm_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + hardware_full_fence(); + } + + static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + hardware_full_fence(); + } + + static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + hardware_full_fence(); + } + + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_DMB) + // Older binutils (supposedly, older than 2.21.1) didn't support symbolic or numeric arguments of the "dmb" instruction such as "ish" or "#11". + // As a workaround we have to inject encoded bytes of the instruction. There are two encodings for the instruction: ARM and Thumb. See ARM Architecture Reference Manual, A8.8.43. + // Since we cannot detect binutils version at compile time, we'll have to always use this hack. + __asm__ __volatile__ + ( +#if defined(__thumb2__) + ".short 0xF3BF, 0x8F5B\n" // dmb ish +#else + ".word 0xF57FF05B\n" // dmb ish +#endif + : + : + : "memory" + ); +#else + uint32_t tmp; + __asm__ __volatile__ + ( + BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0) + "mcr\tp15, 0, r0, c7, c10, 5\n" + BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0) + : "=&l" (tmp) + : + : "memory" + ); +#endif + } +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_COMMON_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_atomic.hpp b/boost/atomic/detail/ops_gcc_atomic.hpp new file mode 100644 index 00000000..ce40e3b2 --- /dev/null +++ b/boost/atomic/detail/ops_gcc_atomic.hpp @@ -0,0 +1,392 @@ +/* + * 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) + * + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_atomic.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#if (defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) >= 70000)) && (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)) +#include +#include +#endif + +#if __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE || __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE ||\ + __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE || __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE ||\ + __GCC_ATOMIC_CHAR_LOCK_FREE != BOOST_ATOMIC_CHAR_LOCK_FREE || __GCC_ATOMIC_BOOL_LOCK_FREE != BOOST_ATOMIC_BOOL_LOCK_FREE ||\ + __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE +// There are platforms where we need to use larger storage types +#include +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__INTEL_COMPILER) +// This is used to suppress warning #32013 described below for Intel Compiler. +// In debug builds the compiler does not inline any functions, so basically +// every atomic function call results in this warning. I don't know any other +// way to selectively disable just this one warning. +#pragma system_header +#endif + +namespace boost { +namespace atomics { +namespace detail { + +/*! + * The function converts \c boost::memory_order values to the compiler-specific constants. + * + * NOTE: The intention is that the function is optimized away by the compiler, and the + * compiler-specific constants are passed to the intrinsics. Unfortunately, constexpr doesn't + * work in this case because the standard atomics interface require memory ordering + * constants to be passed as function arguments, at which point they stop being constexpr. + * However, it is crucial that the compiler sees constants and not runtime values, + * because otherwise it just ignores the ordering value and always uses seq_cst. + * This is the case with Intel C++ Compiler 14.0.3 (Composer XE 2013 SP1, update 3) and + * gcc 4.8.2. Intel Compiler issues a warning in this case: + * + * warning #32013: Invalid memory order specified. Defaulting to seq_cst memory order. + * + * while gcc acts silently. + * + * To mitigate the problem ALL functions, including the atomic<> members must be + * declared with BOOST_FORCEINLINE. In this case the compilers are able to see that + * all functions are called with constant orderings and call intrinstcts properly. + * + * Unfortunately, this still doesn't work in debug mode as the compiler doesn't + * propagate constants even when functions are marked with BOOST_FORCEINLINE. In this case + * all atomic operaions will be executed with seq_cst semantics. + */ +BOOST_FORCEINLINE BOOST_CONSTEXPR int convert_memory_order_to_gcc(memory_order order) BOOST_NOEXCEPT +{ + return (order == memory_order_relaxed ? __ATOMIC_RELAXED : (order == memory_order_consume ? __ATOMIC_CONSUME : + (order == memory_order_acquire ? __ATOMIC_ACQUIRE : (order == memory_order_release ? __ATOMIC_RELEASE : + (order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_SEQ_CST))))); +} + +template< std::size_t Size, bool Signed > +struct gcc_atomic_operations +{ + typedef typename make_storage_type< Size >::type storage_type; + typedef typename make_storage_type< Size >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + + // Note: In the current implementation, gcc_atomic_operations are used only when the particularly sized __atomic + // intrinsics are always lock-free (i.e. the corresponding LOCK_FREE macro is 2). Therefore it is safe to + // always set is_always_lock_free to true here. + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + __atomic_store_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return __atomic_load_n(&storage, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return __atomic_fetch_add(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return __atomic_exchange_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n + ( + &storage, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order) + ); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n + ( + &storage, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order) + ); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return __atomic_fetch_and(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return __atomic_fetch_or(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&storage, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return __atomic_test_and_set(&storage, atomics::detail::convert_memory_order_to_gcc(order)); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + __atomic_clear(const_cast< storage_type* >(&storage), atomics::detail::convert_memory_order_to_gcc(order)); + } +}; + +#if BOOST_ATOMIC_INT128_LOCK_FREE > 0 +#if (defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) >= 70000)) && defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) + +// Workaround for clang bug: http://llvm.org/bugs/show_bug.cgi?id=19149 +// Clang 3.4 does not implement 128-bit __atomic* intrinsics even though it defines __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 +// A similar problem exists with gcc 7 as well, as it requires to link with libatomic to use 16-byte intrinsics: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878 +template< bool Signed > +struct operations< 16u, Signed > : + public cas_based_operations< gcc_dcas_x86_64< Signed > > +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 16u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; +}; + +#else + +template< bool Signed > +struct operations< 16u, Signed > : + public gcc_atomic_operations< 16u, Signed > +{ +}; + +#endif +#endif + + +#if BOOST_ATOMIC_INT64_LOCK_FREE > 0 +#if defined(__clang__) && defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) + +// Workaround for clang bug http://llvm.org/bugs/show_bug.cgi?id=19355 +template< bool Signed > +struct operations< 8u, Signed > : + public cas_based_operations< gcc_dcas_x86< Signed > > +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; +}; + +#elif (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) + +#define BOOST_ATOMIC_DETAIL_INT64_EXTENDED + +template< bool Signed > +struct operations< 8u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 8u, Signed > +{ +}; + +#else + +template< bool Signed > +struct operations< 8u, Signed > : + public gcc_atomic_operations< 8u, Signed > +{ +}; + +#endif +#endif + +#if BOOST_ATOMIC_INT32_LOCK_FREE > 0 +#if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) + +#define BOOST_ATOMIC_DETAIL_INT32_EXTENDED + +#if !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) + +template< bool Signed > +struct operations< 4u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 4u, Signed > +{ +}; + +#else // !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) + +template< bool Signed > +struct operations< 4u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 4u, Signed > +{ +}; + +#endif // !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) + +#else + +template< bool Signed > +struct operations< 4u, Signed > : + public gcc_atomic_operations< 4u, Signed > +{ +}; + +#endif +#endif + +#if BOOST_ATOMIC_INT16_LOCK_FREE > 0 +#if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) + +#define BOOST_ATOMIC_DETAIL_INT16_EXTENDED + +#if !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED) + +template< bool Signed > +struct operations< 2u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed >, 2u, Signed > +{ +}; + +#elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) + +template< bool Signed > +struct operations< 2u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 2u, Signed > +{ +}; + +#else + +template< bool Signed > +struct operations< 2u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 2u, Signed > +{ +}; + +#endif + +#else + +template< bool Signed > +struct operations< 2u, Signed > : + public gcc_atomic_operations< 2u, Signed > +{ +}; + +#endif +#endif + +#if BOOST_ATOMIC_INT8_LOCK_FREE > 0 +#if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\ + (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) ||\ + (__GCC_ATOMIC_CHAR_LOCK_FREE != BOOST_ATOMIC_CHAR_LOCK_FREE) ||\ + (__GCC_ATOMIC_BOOL_LOCK_FREE != BOOST_ATOMIC_BOOL_LOCK_FREE) + +#if !defined(BOOST_ATOMIC_DETAIL_INT16_EXTENDED) + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 2u, Signed >, 1u, Signed > +{ +}; + +#elif !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED) + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed >, 1u, Signed > +{ +}; + +#elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED) + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 1u, Signed > +{ +}; + +#else + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 1u, Signed > +{ +}; + +#endif + +#else + +template< bool Signed > +struct operations< 1u, Signed > : + public gcc_atomic_operations< 1u, Signed > +{ +}; + +#endif +#endif + +#undef BOOST_ATOMIC_DETAIL_INT16_EXTENDED +#undef BOOST_ATOMIC_DETAIL_INT32_EXTENDED +#undef BOOST_ATOMIC_DETAIL_INT64_EXTENDED + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + __atomic_thread_fence(atomics::detail::convert_memory_order_to_gcc(order)); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + __atomic_signal_fence(atomics::detail::convert_memory_order_to_gcc(order)); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_ppc.hpp b/boost/atomic/detail/ops_gcc_ppc.hpp new file mode 100644 index 00000000..a826736d --- /dev/null +++ b/boost/atomic/detail/ops_gcc_ppc.hpp @@ -0,0 +1,1232 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_ppc.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +// The implementation below uses information from this document: +// http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2010.02.19a.html + +/* + Refer to: Motorola: "Programming Environments Manual for 32-Bit + Implementations of the PowerPC Architecture", Appendix E: + "Synchronization Programming Examples" for an explanation of what is + going on here (can be found on the web at various places by the + name "MPCFPE32B.pdf", Google is your friend...) + + Most of the atomic operations map to instructions in a relatively + straight-forward fashion, but "load"s may at first glance appear + a bit strange as they map to: + + lwz %rX, addr + cmpw %rX, %rX + bne- 1f + 1: + + That is, the CPU is forced to perform a branch that "formally" depends + on the value retrieved from memory. This scheme has an overhead of + about 1-2 clock cycles per load, but it allows to map "acquire" to + the "isync" instruction instead of "sync" uniformly and for all type + of atomic operations. Since "isync" has a cost of about 15 clock + cycles, while "sync" hast a cost of about 50 clock cycles, the small + penalty to atomic loads more than compensates for this. + + Byte- and halfword-sized atomic values are implemented in two ways. + When 8 and 16-bit instructions are available (in Power8 and later), + they are used. Otherwise operations are realized by encoding the + value to be represented into a word, performing sign/zero extension + as appropriate. This means that after add/sub operations the value + needs fixing up to accurately preserve the wrap-around semantic of + the smaller type. (Nothing special needs to be done for the bit-wise + and the "exchange type" operators as the compiler already sees to + it that values carried in registers are extended appropriately and + everything falls into place naturally). + + The register constraint "b" instructs gcc to use any register + except r0; this is sometimes required because the encoding for + r0 is used to signify "constant zero" in a number of instructions, + making r0 unusable in this place. For simplicity this constraint + is used everywhere since I am to lazy to look this up on a + per-instruction basis, and ppc has enough registers for this not + to pose a problem. +*/ + +template< bool Signed > +struct operations< 4u, Signed > : + public gcc_ppc_operations_base +{ + typedef typename make_storage_type< 4u >::type storage_type; + typedef typename make_storage_type< 4u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + __asm__ __volatile__ + ( + "stw %1, %0\n\t" + : "+m" (storage) + : "r" (v) + ); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v; + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("sync" ::: "memory"); + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + { + __asm__ __volatile__ + ( + "lwz %0, %1\n\t" + "cmpw %0, %0\n\t" + "bne- 1f\n\t" + "1:\n\t" + "isync\n\t" + : "=&r" (v) + : "m" (storage) + : "cr0", "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lwz %0, %1\n\t" + : "=&r" (v) + : "m" (storage) + ); + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y1\n\t" + "stwcx. %2,%y1\n\t" + "bne- 1b\n\t" + : "=&b" (original), "+Z" (storage) + : "b" (v) + : "cr0" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "lwarx %0,%y2\n\t" + "cmpw %0, %3\n\t" + "bne- 1f\n\t" + "stwcx. %4,%y2\n\t" + "bne- 1f\n\t" + "li %1, 1\n\t" + "1:\n\t" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "0: lwarx %0,%y2\n\t" + "cmpw %0, %3\n\t" + "bne- 1f\n\t" + "stwcx. %4,%y2\n\t" + "bne- 0b\n\t" + "li %1, 1\n\t" + "1:\n\t" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX) + +template< bool Signed > +struct operations< 1u, Signed > : + public gcc_ppc_operations_base +{ + typedef typename make_storage_type< 1u >::type storage_type; + typedef typename make_storage_type< 1u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + __asm__ __volatile__ + ( + "stb %1, %0\n\t" + : "+m" (storage) + : "r" (v) + ); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v; + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("sync" ::: "memory"); + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + { + __asm__ __volatile__ + ( + "lbz %0, %1\n\t" + "cmpw %0, %0\n\t" + "bne- 1f\n\t" + "1:\n\t" + "isync\n\t" + : "=&r" (v) + : "m" (storage) + : "cr0", "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lbz %0, %1\n\t" + : "=&r" (v) + : "m" (storage) + ); + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y1\n\t" + "stbcx. %2,%y1\n\t" + "bne- 1b\n\t" + : "=&b" (original), "+Z" (storage) + : "b" (v) + : "cr0" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "lbarx %0,%y2\n\t" + "cmpw %0, %3\n\t" + "bne- 1f\n\t" + "stbcx. %4,%y2\n\t" + "bne- 1f\n\t" + "li %1, 1\n\t" + "1:\n\t" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "0: lbarx %0,%y2\n\t" + "cmpw %0, %3\n\t" + "bne- 1f\n\t" + "stbcx. %4,%y2\n\t" + "bne- 0b\n\t" + "li %1, 1\n\t" + "1:\n\t" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lbarx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "stbcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX) + +template< > +struct operations< 1u, false > : + public operations< 4u, false > +{ + typedef operations< 4u, false > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "rlwinm %1, %1, 0, 0xff\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "rlwinm %1, %1, 0, 0xff\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +template< > +struct operations< 1u, true > : + public operations< 4u, true > +{ + typedef operations< 4u, true > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "extsb %1, %1\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "extsb %1, %1\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX) + +#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX) + +template< bool Signed > +struct operations< 2u, Signed > : + public gcc_ppc_operations_base +{ + typedef typename make_storage_type< 2u >::type storage_type; + typedef typename make_storage_type< 2u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + __asm__ __volatile__ + ( + "sth %1, %0\n\t" + : "+m" (storage) + : "r" (v) + ); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v; + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("sync" ::: "memory"); + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + { + __asm__ __volatile__ + ( + "lhz %0, %1\n\t" + "cmpw %0, %0\n\t" + "bne- 1f\n\t" + "1:\n\t" + "isync\n\t" + : "=&r" (v) + : "m" (storage) + : "cr0", "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "lhz %0, %1\n\t" + : "=&r" (v) + : "m" (storage) + ); + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y1\n\t" + "sthcx. %2,%y1\n\t" + "bne- 1b\n\t" + : "=&b" (original), "+Z" (storage) + : "b" (v) + : "cr0" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "lharx %0,%y2\n\t" + "cmpw %0, %3\n\t" + "bne- 1f\n\t" + "sthcx. %4,%y2\n\t" + "bne- 1f\n\t" + "li %1, 1\n\t" + "1:\n\t" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "0: lharx %0,%y2\n\t" + "cmpw %0, %3\n\t" + "bne- 1f\n\t" + "sthcx. %4,%y2\n\t" + "bne- 0b\n\t" + "li %1, 1\n\t" + "1:\n\t" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lharx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "sthcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX) + +template< > +struct operations< 2u, false > : + public operations< 4u, false > +{ + typedef operations< 4u, false > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "rlwinm %1, %1, 0, 0xffff\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "rlwinm %1, %1, 0, 0xffff\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +template< > +struct operations< 2u, true > : + public operations< 4u, true > +{ + typedef operations< 4u, true > base_type; + typedef base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "extsh %1, %1\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "lwarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "extsh %1, %1\n\t" + "stwcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX) + +#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX) + +template< bool Signed > +struct operations< 8u, Signed > : + public gcc_ppc_operations_base +{ + typedef typename make_storage_type< 8u >::type storage_type; + typedef typename make_storage_type< 8u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + __asm__ __volatile__ + ( + "std %1, %0\n\t" + : "+m" (storage) + : "r" (v) + ); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v; + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("sync" ::: "memory"); + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + { + __asm__ __volatile__ + ( + "ld %0, %1\n\t" + "cmpd %0, %0\n\t" + "bne- 1f\n\t" + "1:\n\t" + "isync\n\t" + : "=&b" (v) + : "m" (storage) + : "cr0", "memory" + ); + } + else + { + __asm__ __volatile__ + ( + "ld %0, %1\n\t" + : "=&b" (v) + : "m" (storage) + ); + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y1\n\t" + "stdcx. %2,%y1\n\t" + "bne- 1b\n\t" + : "=&b" (original), "+Z" (storage) + : "b" (v) + : "cr0" + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "ldarx %0,%y2\n\t" + "cmpd %0, %3\n\t" + "bne- 1f\n\t" + "stdcx. %4,%y2\n\t" + "bne- 1f\n\t" + "li %1, 1\n\t" + "1:" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + int success; + fence_before(success_order); + __asm__ __volatile__ + ( + "li %1, 0\n\t" + "0: ldarx %0,%y2\n\t" + "cmpd %0, %3\n\t" + "bne- 1f\n\t" + "stdcx. %4,%y2\n\t" + "bne- 0b\n\t" + "li %1, 1\n\t" + "1:\n\t" + : "=&b" (expected), "=&b" (success), "+Z" (storage) + : "b" (expected), "b" (desired) + : "cr0" + ); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + return !!success; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "add %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "sub %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "and %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "or %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type original, result; + fence_before(order); + __asm__ __volatile__ + ( + "1:\n\t" + "ldarx %0,%y2\n\t" + "xor %1,%0,%3\n\t" + "stdcx. %1,%y2\n\t" + "bne- 1b\n\t" + : "=&b" (original), "=&b" (result), "+Z" (storage) + : "b" (v) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC + ); + fence_after(order); + return original; + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, 0, order); + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX) + + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + { +#if defined(__powerpc64__) || defined(__PPC64__) + if (order != memory_order_seq_cst) + __asm__ __volatile__ ("lwsync" ::: "memory"); + else + __asm__ __volatile__ ("sync" ::: "memory"); +#else + __asm__ __volatile__ ("sync" ::: "memory"); +#endif + } +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) +#if defined(__ibmxl__) || defined(__IBMCPP__) + __fence(); +#else + __asm__ __volatile__ ("" ::: "memory"); +#endif +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_ppc_common.hpp b/boost/atomic/detail/ops_gcc_ppc_common.hpp new file mode 100644 index 00000000..e5c9303b --- /dev/null +++ b/boost/atomic/detail/ops_gcc_ppc_common.hpp @@ -0,0 +1,70 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_ppc_common.hpp + * + * This header contains basic utilities for gcc PowerPC backend. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_COMMON_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_COMMON_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +// The implementation below uses information from this document: +// http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2010.02.19a.html + +// A note about memory_order_consume. Technically, this architecture allows to avoid +// unnecessary memory barrier after consume load since it supports data dependency ordering. +// However, some compiler optimizations may break a seemingly valid code relying on data +// dependency tracking by injecting bogus branches to aid out of order execution. +// This may happen not only in Boost.Atomic code but also in user's code, which we have no +// control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php. +// For this reason we promote memory_order_consume to memory_order_acquire. + +struct gcc_ppc_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT + { +#if defined(__powerpc64__) || defined(__PPC64__) + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("sync" ::: "memory"); + else if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __asm__ __volatile__ ("lwsync" ::: "memory"); +#else + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __asm__ __volatile__ ("sync" ::: "memory"); +#endif + } + + static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + __asm__ __volatile__ ("isync" ::: "memory"); + } +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_COMMON_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_sparc.hpp b/boost/atomic/detail/ops_gcc_sparc.hpp new file mode 100644 index 00000000..19b9b1fa --- /dev/null +++ b/boost/atomic/detail/ops_gcc_sparc.hpp @@ -0,0 +1,240 @@ +/* + * 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) + * + * Copyright (c) 2010 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_sparc.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +struct gcc_sparc_cas_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + else if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); + } + + static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + else if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); + } + + static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + } +}; + +template< bool Signed > +struct gcc_sparc_cas32 : + public gcc_sparc_cas_base +{ + typedef typename make_storage_type< 4u >::type storage_type; + typedef typename make_storage_type< 4u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + storage_type previous = expected; + __asm__ __volatile__ + ( + "cas [%1], %2, %0" + : "+r" (desired) + : "r" (&storage), "r" (previous) + : "memory" + ); + const bool success = (desired == previous); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = desired; + return success; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + __asm__ __volatile__ + ( + "swap [%1], %0" + : "+r" (v) + : "r" (&storage) + : "memory" + ); + fence_after(order); + return v; + } +}; + +template< bool Signed > +struct operations< 4u, Signed > : + public cas_based_operations< gcc_sparc_cas32< Signed > > +{ +}; + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed > +{ +}; + +template< bool Signed > +struct operations< 2u, Signed > : + public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed > +{ +}; + +template< bool Signed > +struct gcc_sparc_cas64 : + public gcc_sparc_cas_base +{ + typedef typename make_storage_type< 8u >::type storage_type; + typedef typename make_storage_type< 8u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + fence_before(success_order); + storage_type previous = expected; + __asm__ __volatile__ + ( + "casx [%1], %2, %0" + : "+r" (desired) + : "r" (&storage), "r" (previous) + : "memory" + ); + const bool success = (desired == previous); + if (success) + fence_after(success_order); + else + fence_after(failure_order); + expected = desired; + return success; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } +}; + +template< bool Signed > +struct operations< 8u, Signed > : + public cas_based_operations< cas_based_exchange< gcc_sparc_cas64< Signed > > > +{ +}; + + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + switch (order) + { + case memory_order_release: + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); + break; + case memory_order_consume: + case memory_order_acquire: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); + break; + case memory_order_acq_rel: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory"); + break; + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + break; + case memory_order_relaxed: + default: + break; + } +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __asm__ __volatile__ ("" ::: "memory"); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_sync.hpp b/boost/atomic/detail/ops_gcc_sync.hpp new file mode 100644 index 00000000..1597de85 --- /dev/null +++ b/boost/atomic/detail/ops_gcc_sync.hpp @@ -0,0 +1,240 @@ +/* + * 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) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_sync.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +struct gcc_sync_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __sync_synchronize(); + } + + static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + __sync_synchronize(); + } + + static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_acquire) | static_cast< unsigned int >(memory_order_consume))) != 0u) + __sync_synchronize(); + } +}; + +template< std::size_t Size, bool Signed > +struct gcc_sync_operations : + public gcc_sync_operations_base +{ + typedef typename make_storage_type< Size >::type storage_type; + typedef typename make_storage_type< Size >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before_store(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after_load(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return __sync_fetch_and_add(&storage, v); + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return __sync_fetch_and_sub(&storage, v); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + // GCC docs mention that not all architectures may support full exchange semantics for this intrinsic. However, GCC's implementation of + // std::atomic<> uses this intrinsic unconditionally. We do so as well. In case if some architectures actually don't support this, we can always + // add a check here and fall back to a CAS loop. + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __sync_synchronize(); + return __sync_lock_test_and_set(&storage, v); + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type expected2 = expected; + storage_type old_val = __sync_val_compare_and_swap(&storage, expected2, desired); + + if (old_val == expected2) + { + return true; + } + else + { + expected = old_val; + return false; + } + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return __sync_fetch_and_and(&storage, v); + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return __sync_fetch_and_or(&storage, v); + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return __sync_fetch_and_xor(&storage, v); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __sync_synchronize(); + return !!__sync_lock_test_and_set(&storage, 1); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + __sync_lock_release(&storage); + if (order == memory_order_seq_cst) + __sync_synchronize(); + } +}; + +#if BOOST_ATOMIC_INT8_LOCK_FREE > 0 +template< bool Signed > +struct operations< 1u, Signed > : +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) + public gcc_sync_operations< 1u, Signed > +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) + public extending_cas_based_operations< gcc_sync_operations< 2u, Signed >, 1u, Signed > +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + public extending_cas_based_operations< gcc_sync_operations< 4u, Signed >, 1u, Signed > +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) + public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 1u, Signed > +#else + public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 1u, Signed > +#endif +{ +}; +#endif + +#if BOOST_ATOMIC_INT16_LOCK_FREE > 0 +template< bool Signed > +struct operations< 2u, Signed > : +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) + public gcc_sync_operations< 2u, Signed > +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + public extending_cas_based_operations< gcc_sync_operations< 4u, Signed >, 2u, Signed > +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) + public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 2u, Signed > +#else + public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 2u, Signed > +#endif +{ +}; +#endif + +#if BOOST_ATOMIC_INT32_LOCK_FREE > 0 +template< bool Signed > +struct operations< 4u, Signed > : +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + public gcc_sync_operations< 4u, Signed > +#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) + public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 4u, Signed > +#else + public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 4u, Signed > +#endif +{ +}; +#endif + +#if BOOST_ATOMIC_INT64_LOCK_FREE > 0 +template< bool Signed > +struct operations< 8u, Signed > : +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) + public gcc_sync_operations< 8u, Signed > +#else + public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 8u, Signed > +#endif +{ +}; +#endif + +#if BOOST_ATOMIC_INT128_LOCK_FREE > 0 +template< bool Signed > +struct operations< 16u, Signed > : + public gcc_sync_operations< 16u, Signed > +{ +}; +#endif + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __sync_synchronize(); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __asm__ __volatile__ ("" ::: "memory"); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_x86.hpp b/boost/atomic/detail/ops_gcc_x86.hpp new file mode 100644 index 00000000..007d4eee --- /dev/null +++ b/boost/atomic/detail/ops_gcc_x86.hpp @@ -0,0 +1,563 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_x86.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) +#include +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +struct gcc_x86_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + __asm__ __volatile__ ("" ::: "memory"); + } + + static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + __asm__ __volatile__ ("" ::: "memory"); + } +}; + +template< std::size_t Size, bool Signed, typename Derived > +struct gcc_x86_operations : + public gcc_x86_operations_base +{ + typedef typename make_storage_type< Size >::type storage_type; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + if (order != memory_order_seq_cst) + { + fence_before(order); + storage = v; + fence_after(order); + } + else + { + Derived::exchange(storage, v, order); + } + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + return Derived::fetch_add(storage, -v, order); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!Derived::exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, (storage_type)0, order); + } +}; + +template< bool Signed > +struct operations< 1u, Signed > : + public gcc_x86_operations< 1u, Signed, operations< 1u, Signed > > +{ + typedef gcc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 1u >::aligned aligned_storage_type; + typedef typename make_storage_type< 4u >::type temp_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xaddb %0, %1" + : "+q" (v), "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "xchgb %0, %1" + : "+q" (v), "+m" (storage) + : + : "memory" + ); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgb %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "q" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgb %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (storage), "=q" (success) + : "q" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + expected = previous; + return success; + } + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + temp_storage_type new_val;\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[arg], %2\n\t"\ + op " %%al, %b2\n\t"\ + "lock; cmpxchgb %b2, %[storage]\n\t"\ + "jne 1b"\ + : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\ + : [arg] "ir" ((temp_storage_type)argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andb", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orb", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorb", v, res); + return res; + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP +}; + +template< bool Signed > +struct operations< 2u, Signed > : + public gcc_x86_operations< 2u, Signed, operations< 2u, Signed > > +{ + typedef gcc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 2u >::aligned aligned_storage_type; + typedef typename make_storage_type< 4u >::type temp_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xaddw %0, %1" + : "+q" (v), "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "xchgw %0, %1" + : "+q" (v), "+m" (storage) + : + : "memory" + ); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgw %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "q" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgw %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (storage), "=q" (success) + : "q" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + expected = previous; + return success; + } + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + temp_storage_type new_val;\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[arg], %2\n\t"\ + op " %%ax, %w2\n\t"\ + "lock; cmpxchgw %w2, %[storage]\n\t"\ + "jne 1b"\ + : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\ + : [arg] "ir" ((temp_storage_type)argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andw", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orw", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorw", v, res); + return res; + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP +}; + +template< bool Signed > +struct operations< 4u, Signed > : + public gcc_x86_operations< 4u, Signed, operations< 4u, Signed > > +{ + typedef gcc_x86_operations< 4u, Signed, operations< 4u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 4u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xaddl %0, %1" + : "+r" (v), "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "xchgl %0, %1" + : "+r" (v), "+m" (storage) + : + : "memory" + ); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgl %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "r" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (storage), "=q" (success) + : "r" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + expected = previous; + return success; + } + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + storage_type new_val;\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: mov %[arg], %[new_val]\n\t"\ + op " %%eax, %[new_val]\n\t"\ + "lock; cmpxchgl %[new_val], %[storage]\n\t"\ + "jne 1b"\ + : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\ + : [arg] "ir" (argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andl", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orl", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorl", v, res); + return res; + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP +}; + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) + +template< bool Signed > +struct operations< 8u, Signed > : + public cas_based_operations< gcc_dcas_x86< Signed > > +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; +}; + +#elif defined(__x86_64__) + +template< bool Signed > +struct operations< 8u, Signed > : + public gcc_x86_operations< 8u, Signed, operations< 8u, Signed > > +{ + typedef gcc_x86_operations< 8u, Signed, operations< 8u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + typedef typename make_storage_type< 8u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "lock; xaddq %0, %1" + : "+r" (v), "+m" (storage) + : + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "xchgq %0, %1" + : "+r" (v), "+m" (storage) + : + : "memory" + ); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + bool success; +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgq %3, %1" + : "+a" (previous), "+m" (storage), "=@ccz" (success) + : "r" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (storage), "=q" (success) + : "r" (desired) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + expected = previous; + return success; + } + +#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\ + storage_type new_val;\ + __asm__ __volatile__\ + (\ + ".align 16\n\t"\ + "1: movq %[arg], %[new_val]\n\t"\ + op " %%rax, %[new_val]\n\t"\ + "lock; cmpxchgq %[new_val], %[storage]\n\t"\ + "jne 1b"\ + : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\ + : [arg] "r" (argument)\ + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\ + ) + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("andq", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("orq", v, res); + return res; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type res = storage; + BOOST_ATOMIC_DETAIL_CAS_LOOP("xorq", v, res); + return res; + } + +#undef BOOST_ATOMIC_DETAIL_CAS_LOOP +}; + +#endif + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) + +template< bool Signed > +struct operations< 16u, Signed > : + public cas_based_operations< gcc_dcas_x86_64< Signed > > +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 16u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order == memory_order_seq_cst) + { + __asm__ __volatile__ + ( +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE) + "mfence\n" +#else + "lock; addl $0, (%%esp)\n" +#endif + ::: "memory" + ); + } + else if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_acquire) | static_cast< unsigned int >(memory_order_release))) != 0u) + { + __asm__ __volatile__ ("" ::: "memory"); + } +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __asm__ __volatile__ ("" ::: "memory"); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_gcc_x86_dcas.hpp b/boost/atomic/detail/ops_gcc_x86_dcas.hpp new file mode 100644 index 00000000..4dacc66f --- /dev/null +++ b/boost/atomic/detail/ops_gcc_x86_dcas.hpp @@ -0,0 +1,555 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2014 - 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_gcc_x86_dcas.hpp + * + * This header contains implementation of the double-width CAS primitive for x86. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +// Note: In the 32-bit PIC code guarded with BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX below we have to avoid using memory +// operand constraints because the compiler may choose to use ebx as the base register for that operand. At least, clang +// is known to do that. For this reason we have to pre-compute a pointer to storage and pass it in edi. For the same reason +// we cannot save ebx to the stack with a mov instruction, so we use esi as a scratch register and restore it afterwards. +// Alternatively, we could push/pop the register to the stack, but exchanging the registers is faster. +// The need to pass a pointer in edi is a bit wasteful because normally the memory operand would use a base pointer +// with an offset (e.g. `this` + offset). But unfortunately, there seems to be no way around it. + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) + +template< bool Signed > +struct gcc_dcas_x86 +{ + typedef typename make_storage_type< 8u >::type storage_type; + typedef typename make_storage_type< 8u >::aligned aligned_storage_type; + typedef uint32_t BOOST_ATOMIC_DETAIL_MAY_ALIAS aliasing_uint32_t; + + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + if (BOOST_LIKELY((((uint32_t)&storage) & 0x00000007) == 0u)) + { +#if defined(__SSE__) + typedef float xmm_t __attribute__((__vector_size__(16))); + xmm_t xmm_scratch; + __asm__ __volatile__ + ( +#if defined(__AVX__) + "vmovq %[value], %[xmm_scratch]\n\t" + "vmovq %[xmm_scratch], %[storage]\n\t" +#elif defined(__SSE2__) + "movq %[value], %[xmm_scratch]\n\t" + "movq %[xmm_scratch], %[storage]\n\t" +#else + "xorps %[xmm_scratch], %[xmm_scratch]\n\t" + "movlps %[value], %[xmm_scratch]\n\t" + "movlps %[xmm_scratch], %[storage]\n\t" +#endif + : [storage] "=m" (storage), [xmm_scratch] "=x" (xmm_scratch) + : [value] "m" (v) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "fildll %[value]\n\t" + "fistpll %[storage]\n\t" + : [storage] "=m" (storage) + : [value] "m" (v) + : "memory" + ); +#endif + } + else + { +#if defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) + __asm__ __volatile__ + ( + "xchgl %%ebx, %%esi\n\t" + "movl %%eax, %%ebx\n\t" + "movl (%[dest]), %%eax\n\t" + "movl 4(%[dest]), %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b (%[dest])\n\t" + "jne 1b\n\t" + "xchgl %%ebx, %%esi\n\t" + : + : "a" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) + __asm__ __volatile__ + ( + "movl %[dest_lo], %%eax\n\t" + "movl %[dest_hi], %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b %[dest_lo]\n\t" + "jne 1b\n\t" + : [dest_lo] "=m" (storage), [dest_hi] "=m" (reinterpret_cast< volatile aliasing_uint32_t* >(&storage)[1]) + : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) + } + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type value; + + if (BOOST_LIKELY((((uint32_t)&storage) & 0x00000007) == 0u)) + { +#if defined(__SSE__) + typedef float xmm_t __attribute__((__vector_size__(16))); + xmm_t xmm_scratch; + __asm__ __volatile__ + ( +#if defined(__AVX__) + "vmovq %[storage], %[xmm_scratch]\n\t" + "vmovq %[xmm_scratch], %[value]\n\t" +#elif defined(__SSE2__) + "movq %[storage], %[xmm_scratch]\n\t" + "movq %[xmm_scratch], %[value]\n\t" +#else + "xorps %[xmm_scratch], %[xmm_scratch]\n\t" + "movlps %[storage], %[xmm_scratch]\n\t" + "movlps %[xmm_scratch], %[value]\n\t" +#endif + : [value] "=m" (value), [xmm_scratch] "=x" (xmm_scratch) + : [storage] "m" (storage) + : "memory" + ); +#else + __asm__ __volatile__ + ( + "fildll %[storage]\n\t" + "fistpll %[value]\n\t" + : [value] "=m" (value) + : [storage] "m" (storage) + : "memory" + ); +#endif + } + else + { +#if defined(__clang__) + // Clang cannot allocate eax:edx register pairs but it has sync intrinsics + value = __sync_val_compare_and_swap(&storage, (storage_type)0, (storage_type)0); +#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + uint32_t value_bits[2]; + // We don't care for comparison result here; the previous value will be stored into value anyway. + // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. + __asm__ __volatile__ + ( + "movl %%ebx, %%eax\n\t" + "movl %%ecx, %%edx\n\t" + "lock; cmpxchg8b %[storage]\n\t" + : "=&a" (value_bits[0]), "=&d" (value_bits[1]) + : [storage] "m" (storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + BOOST_ATOMIC_DETAIL_MEMCPY(&value, value_bits, sizeof(value)); +#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + // We don't care for comparison result here; the previous value will be stored into value anyway. + // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. + __asm__ __volatile__ + ( + "movl %%ebx, %%eax\n\t" + "movl %%ecx, %%edx\n\t" + "lock; cmpxchg8b %[storage]\n\t" + : "=&A" (value) + : [storage] "m" (storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + } + + return value; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { +#if defined(__clang__) + + // Clang cannot allocate eax:edx register pairs but it has sync intrinsics + storage_type old_expected = expected; + expected = __sync_val_compare_and_swap(&storage, old_expected, desired); + return expected == old_expected; + +#elif defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) + + bool success; + +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "xchgl %%ebx, %%esi\n\t" + "lock; cmpxchg8b (%[dest])\n\t" + "xchgl %%ebx, %%esi\n\t" + : "+A" (expected), [success] "=@ccz" (success) + : "S" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), [dest] "D" (&storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "xchgl %%ebx, %%esi\n\t" + "lock; cmpxchg8b (%[dest])\n\t" + "xchgl %%ebx, %%esi\n\t" + "sete %[success]\n\t" + : "+A" (expected), [success] "=qm" (success) + : "S" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), [dest] "D" (&storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + + return success; + +#else // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) + + bool success; + +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchg8b %[dest]\n\t" + : "+A" (expected), [dest] "+m" (storage), [success] "=@ccz" (success) + : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchg8b %[dest]\n\t" + "sete %[success]\n\t" + : "+A" (expected), [dest] "+m" (storage), [success] "=qm" (success) + : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + + return success; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) +#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + uint32_t old_bits[2]; + __asm__ __volatile__ + ( + "xchgl %%ebx, %%esi\n\t" + "movl (%[dest]), %%eax\n\t" + "movl 4(%[dest]), %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b (%[dest])\n\t" + "jne 1b\n\t" + "xchgl %%ebx, %%esi\n\t" + : "=a" (old_bits[0]), "=d" (old_bits[1]) + : "S" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + storage_type old_value; + BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value)); + return old_value; + +#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + storage_type old_value; + __asm__ __volatile__ + ( + "xchgl %%ebx, %%esi\n\t" + "movl (%[dest]), %%eax\n\t" + "movl 4(%[dest]), %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b (%[dest])\n\t" + "jne 1b\n\t" + "xchgl %%ebx, %%esi\n\t" + : "=A" (old_value) + : "S" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + return old_value; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) +#else // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) +#if defined(__MINGW32__) && ((__GNUC__+0) * 100 + (__GNUC_MINOR__+0)) < 407 + + // MinGW gcc up to 4.6 has problems with allocating registers in the asm blocks below + uint32_t old_bits[2]; + __asm__ __volatile__ + ( + "movl (%[dest]), %%eax\n\t" + "movl 4(%[dest]), %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b (%[dest])\n\t" + "jne 1b\n\t" + : "=&a" (old_bits[0]), "=&d" (old_bits[1]) + : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "DS" (&storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + storage_type old_value; + BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value)); + return old_value; + +#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + uint32_t old_bits[2]; + __asm__ __volatile__ + ( + "movl %[dest_lo], %%eax\n\t" + "movl %[dest_hi], %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b %[dest_lo]\n\t" + "jne 1b\n\t" + : "=&a" (old_bits[0]), "=&d" (old_bits[1]), [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint32_t* >(&storage)[1]) + : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + storage_type old_value; + BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value)); + return old_value; + +#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + storage_type old_value; + __asm__ __volatile__ + ( + "movl %[dest_lo], %%eax\n\t" + "movl %[dest_hi], %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b %[dest_lo]\n\t" + "jne 1b\n\t" + : "=&A" (old_value), [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint32_t* >(&storage)[1]) + : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + return old_value; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) +#endif // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX) + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) + +template< bool Signed > +struct gcc_dcas_x86_64 +{ + typedef typename make_storage_type< 16u >::type storage_type; + typedef typename make_storage_type< 16u >::aligned aligned_storage_type; + typedef uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS aliasing_uint64_t; + + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + __asm__ __volatile__ + ( + "movq %[dest_lo], %%rax\n\t" + "movq %[dest_hi], %%rdx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg16b %[dest_lo]\n\t" + "jne 1b\n\t" + : [dest_lo] "=m" (storage), [dest_hi] "=m" (reinterpret_cast< volatile aliasing_uint64_t* >(&storage)[1]) + : "b" (reinterpret_cast< const aliasing_uint64_t* >(&v)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&v)[1]) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory" + ); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT + { +#if defined(__clang__) + + // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics + storage_type value = storage_type(); + return __sync_val_compare_and_swap(&storage, value, value); + +#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + // Some compilers can't allocate rax:rdx register pair either and also don't support 128-bit __sync_val_compare_and_swap + uint64_t value_bits[2]; + + // We don't care for comparison result here; the previous value will be stored into value anyway. + // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b. + __asm__ __volatile__ + ( + "movq %%rbx, %%rax\n\t" + "movq %%rcx, %%rdx\n\t" + "lock; cmpxchg16b %[storage]\n\t" + : "=&a" (value_bits[0]), "=&d" (value_bits[1]) + : [storage] "m" (storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + storage_type value; + BOOST_ATOMIC_DETAIL_MEMCPY(&value, value_bits, sizeof(value)); + return value; + +#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + storage_type value; + + // We don't care for comparison result here; the previous value will be stored into value anyway. + // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b. + __asm__ __volatile__ + ( + "movq %%rbx, %%rax\n\t" + "movq %%rcx, %%rdx\n\t" + "lock; cmpxchg16b %[storage]\n\t" + : "=&A" (value) + : [storage] "m" (storage) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + return value; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { +#if defined(__clang__) + + // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics + storage_type old_expected = expected; + expected = __sync_val_compare_and_swap(&storage, old_expected, desired); + return expected == old_expected; + +#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + // Some compilers can't allocate rax:rdx register pair either but also don't support 128-bit __sync_val_compare_and_swap + bool success; + __asm__ __volatile__ + ( + "lock; cmpxchg16b %[dest]\n\t" + "sete %[success]\n\t" + : [dest] "+m" (storage), "+a" (reinterpret_cast< aliasing_uint64_t* >(&expected)[0]), "+d" (reinterpret_cast< aliasing_uint64_t* >(&expected)[1]), [success] "=q" (success) + : "b" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[1]) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + return success; + +#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + + bool success; + +#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchg16b %[dest]\n\t" + : "+A" (expected), [dest] "+m" (storage), "=@ccz" (success) + : "b" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[1]) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + __asm__ __volatile__ + ( + "lock; cmpxchg16b %[dest]\n\t" + "sete %[success]\n\t" + : "+A" (expected), [dest] "+m" (storage), [success] "=qm" (success) + : "b" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[1]) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); +#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS) + + return success; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + uint64_t old_bits[2]; + __asm__ __volatile__ + ( + "movq %[dest_lo], %%rax\n\t" + "movq %[dest_hi], %%rdx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg16b %[dest_lo]\n\t" + "jne 1b\n\t" + : [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint64_t* >(&storage)[1]), "=&a" (old_bits[0]), "=&d" (old_bits[1]) + : "b" (reinterpret_cast< const aliasing_uint64_t* >(&v)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&v)[1]) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + storage_type old_value; + BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value)); + return old_value; +#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + storage_type old_value; + __asm__ __volatile__ + ( + "movq %[dest_lo], %%rax\n\t" + "movq %[dest_hi], %%rdx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg16b %[dest_lo]\n\t" + "jne 1b\n\t" + : "=&A" (old_value), [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint64_t* >(&storage)[1]) + : "b" (reinterpret_cast< const aliasing_uint64_t* >(&v)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&v)[1]) + : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory" + ); + + return old_value; +#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS) + } +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_linux_arm.hpp b/boost/atomic/detail/ops_linux_arm.hpp new file mode 100644 index 00000000..16af1732 --- /dev/null +++ b/boost/atomic/detail/ops_linux_arm.hpp @@ -0,0 +1,180 @@ +/* + * 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) + * + * Copyright (c) 2009, 2011 Helge Bahmann + * Copyright (c) 2009 Phil Endecott + * Copyright (c) 2013 Tim Blechmann + * Linux-specific code by Phil Endecott + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_linux_arm.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +// Different ARM processors have different atomic instructions. In particular, +// architecture versions before v6 (which are still in widespread use, e.g. the +// Intel/Marvell XScale chips like the one in the NSLU2) have only atomic swap. +// On Linux the kernel provides some support that lets us abstract away from +// these differences: it provides emulated CAS and barrier functions at special +// addresses that are guaranteed not to be interrupted by the kernel. Using +// this facility is slightly slower than inline assembler would be, but much +// faster than a system call. +// +// While this emulated CAS is "strong" in the sense that it does not fail +// "spuriously" (i.e.: it never fails to perform the exchange when the value +// found equals the value expected), it does not return the found value on +// failure. To satisfy the atomic API, compare_exchange_{weak|strong} must +// return the found value on failure, and we have to manually load this value +// after the emulated CAS reports failure. This in turn introduces a race +// between the CAS failing (due to the "wrong" value being found) and subsequently +// loading (which might turn up the "right" value). From an application's +// point of view this looks like "spurious failure", and therefore the +// emulated CAS is only good enough to provide compare_exchange_weak +// semantics. + +struct linux_arm_cas_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + hardware_full_fence(); + } + + static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT + { + if (order == memory_order_seq_cst) + hardware_full_fence(); + } + + static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT + { + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + hardware_full_fence(); + } + + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT + { + typedef void (*kernel_dmb_t)(void); + ((kernel_dmb_t)0xffff0fa0)(); + } +}; + +template< bool Signed > +struct linux_arm_cas : + public linux_arm_cas_base +{ + typedef typename make_storage_type< 4u >::type storage_type; + typedef typename make_storage_type< 4u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + fence_before_store(order); + storage = v; + fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after_load(order); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + while (true) + { + storage_type tmp = expected; + if (compare_exchange_weak(storage, tmp, desired, success_order, failure_order)) + return true; + if (tmp != expected) + { + expected = tmp; + return false; + } + } + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + typedef storage_type (*kernel_cmpxchg32_t)(storage_type oldval, storage_type newval, volatile storage_type* ptr); + + if (((kernel_cmpxchg32_t)0xffff0fc0)(expected, desired, &storage) == 0) + { + return true; + } + else + { + expected = storage; + return false; + } + } +}; + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 1u, Signed > +{ +}; + +template< bool Signed > +struct operations< 2u, Signed > : + public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 2u, Signed > +{ +}; + +template< bool Signed > +struct operations< 4u, Signed > : + public cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > > +{ +}; + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + linux_arm_cas_base::hardware_full_fence(); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + __asm__ __volatile__ ("" ::: "memory"); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_msvc_arm.hpp b/boost/atomic/detail/ops_msvc_arm.hpp new file mode 100644 index 00000000..608c6fdd --- /dev/null +++ b/boost/atomic/detail/ops_msvc_arm.hpp @@ -0,0 +1,824 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_msvc_arm.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#define BOOST_ATOMIC_DETAIL_ARM_LOAD8(p) __iso_volatile_load8((const volatile __int8*)(p)) +#define BOOST_ATOMIC_DETAIL_ARM_LOAD16(p) __iso_volatile_load16((const volatile __int16*)(p)) +#define BOOST_ATOMIC_DETAIL_ARM_LOAD32(p) __iso_volatile_load32((const volatile __int32*)(p)) +#define BOOST_ATOMIC_DETAIL_ARM_LOAD64(p) __iso_volatile_load64((const volatile __int64*)(p)) +#define BOOST_ATOMIC_DETAIL_ARM_STORE8(p, v) __iso_volatile_store8((volatile __int8*)(p), (__int8)(v)) +#define BOOST_ATOMIC_DETAIL_ARM_STORE16(p, v) __iso_volatile_store16((volatile __int16*)(p), (__int16)(v)) +#define BOOST_ATOMIC_DETAIL_ARM_STORE32(p, v) __iso_volatile_store32((volatile __int32*)(p), (__int32)(v)) +#define BOOST_ATOMIC_DETAIL_ARM_STORE64(p, v) __iso_volatile_store64((volatile __int64*)(p), (__int64)(v)) + +namespace boost { +namespace atomics { +namespace detail { + +// A note about memory_order_consume. Technically, this architecture allows to avoid +// unnecessary memory barrier after consume load since it supports data dependency ordering. +// However, some compiler optimizations may break a seemingly valid code relying on data +// dependency tracking by injecting bogus branches to aid out of order execution. +// This may happen not only in Boost.Atomic code but also in user's code, which we have no +// control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php. +// For this reason we promote memory_order_consume to memory_order_acquire. + +struct msvc_arm_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT + { + __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later + } + + static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u) + hardware_full_fence(); + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } + + static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + if (order == memory_order_seq_cst) + hardware_full_fence(); + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } + + static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u) + hardware_full_fence(); + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } + + static BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order cas_common_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + // Combine order flags together and promote memory_order_consume to memory_order_acquire + return static_cast< memory_order >(((static_cast< unsigned int >(failure_order) | static_cast< unsigned int >(success_order)) & ~static_cast< unsigned int >(memory_order_consume)) + | (((static_cast< unsigned int >(failure_order) | static_cast< unsigned int >(success_order)) & static_cast< unsigned int >(memory_order_consume)) << 1u)); + } +}; + +template< std::size_t Size, bool Signed, typename Derived > +struct msvc_arm_operations : + public msvc_arm_operations_base +{ + typedef typename make_storage_type< Size >::type storage_type; + typedef typename make_storage_type< Size >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + typedef typename boost::atomics::detail::make_signed< storage_type >::type signed_storage_type; + return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!Derived::exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + Derived::store(storage, (storage_type)0, order); + } +}; + +template< bool Signed > +struct operations< 1u, Signed > : + public msvc_arm_operations< 1u, Signed, operations< 1u, Signed > > +{ + typedef msvc_arm_operations< 1u, Signed, operations< 1u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before_store(order); + BOOST_ATOMIC_DETAIL_ARM_STORE8(&storage, v); + base_type::fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD8(&storage); + base_type::fence_after_load(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + storage_type previous = expected, old_val; + + switch (cas_common_order(success_order, failure_order)) + { + case memory_order_relaxed: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELAXED(&storage, desired, previous)); + break; + case memory_order_consume: + case memory_order_acquire: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_ACQUIRE(&storage, desired, previous)); + break; + case memory_order_release: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELEASE(&storage, desired, previous)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&storage, desired, previous)); + break; + } + expected = old_val; + + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8(&storage, v)); + break; + } + return v; + } +}; + +template< bool Signed > +struct operations< 2u, Signed > : + public msvc_arm_operations< 2u, Signed, operations< 2u, Signed > > +{ + typedef msvc_arm_operations< 2u, Signed, operations< 2u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before_store(order); + BOOST_ATOMIC_DETAIL_ARM_STORE16(&storage, v); + base_type::fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD16(&storage); + base_type::fence_after_load(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + storage_type previous = expected, old_val; + + switch (cas_common_order(success_order, failure_order)) + { + case memory_order_relaxed: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELAXED(&storage, desired, previous)); + break; + case memory_order_consume: + case memory_order_acquire: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_ACQUIRE(&storage, desired, previous)); + break; + case memory_order_release: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELEASE(&storage, desired, previous)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&storage, desired, previous)); + break; + } + expected = old_val; + + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16(&storage, v)); + break; + } + return v; + } +}; + +template< bool Signed > +struct operations< 4u, Signed > : + public msvc_arm_operations< 4u, Signed, operations< 4u, Signed > > +{ + typedef msvc_arm_operations< 4u, Signed, operations< 4u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before_store(order); + BOOST_ATOMIC_DETAIL_ARM_STORE32(&storage, v); + base_type::fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD32(&storage); + base_type::fence_after_load(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + storage_type previous = expected, old_val; + + switch (cas_common_order(success_order, failure_order)) + { + case memory_order_relaxed: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELAXED(&storage, desired, previous)); + break; + case memory_order_consume: + case memory_order_acquire: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_ACQUIRE(&storage, desired, previous)); + break; + case memory_order_release: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELEASE(&storage, desired, previous)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous)); + break; + } + expected = old_val; + + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v)); + break; + } + return v; + } +}; + +template< bool Signed > +struct operations< 8u, Signed > : + public msvc_arm_operations< 8u, Signed, operations< 8u, Signed > > +{ + typedef msvc_arm_operations< 8u, Signed, operations< 8u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before_store(order); + BOOST_ATOMIC_DETAIL_ARM_STORE64(&storage, v); + base_type::fence_after_store(order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD64(&storage); + base_type::fence_after_load(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + storage_type previous = expected, old_val; + + switch (cas_common_order(success_order, failure_order)) + { + case memory_order_relaxed: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELAXED(&storage, desired, previous)); + break; + case memory_order_consume: + case memory_order_acquire: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_ACQUIRE(&storage, desired, previous)); + break; + case memory_order_release: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELEASE(&storage, desired, previous)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(&storage, desired, previous)); + break; + } + expected = old_val; + + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64(&storage, v)); + break; + } + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + switch (order) + { + case memory_order_relaxed: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELAXED(&storage, v)); + break; + case memory_order_consume: + case memory_order_acquire: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_ACQUIRE(&storage, v)); + break; + case memory_order_release: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELEASE(&storage, v)); + break; + case memory_order_acq_rel: + case memory_order_seq_cst: + default: + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64(&storage, v)); + break; + } + return v; + } +}; + + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + if (order != memory_order_relaxed) + msvc_arm_operations_base::hardware_full_fence(); + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#undef BOOST_ATOMIC_DETAIL_ARM_LOAD8 +#undef BOOST_ATOMIC_DETAIL_ARM_LOAD16 +#undef BOOST_ATOMIC_DETAIL_ARM_LOAD32 +#undef BOOST_ATOMIC_DETAIL_ARM_LOAD64 +#undef BOOST_ATOMIC_DETAIL_ARM_STORE8 +#undef BOOST_ATOMIC_DETAIL_ARM_STORE16 +#undef BOOST_ATOMIC_DETAIL_ARM_STORE32 +#undef BOOST_ATOMIC_DETAIL_ARM_STORE64 + +#endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_msvc_common.hpp b/boost/atomic/detail/ops_msvc_common.hpp new file mode 100644 index 00000000..53628f36 --- /dev/null +++ b/boost/atomic/detail/ops_msvc_common.hpp @@ -0,0 +1,38 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_msvc_common.hpp + * + * This header contains common tools for MSVC implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +// Define compiler barriers +#if defined(__INTEL_COMPILER) +#define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() __memory_barrier() +#elif defined(_MSC_VER) && !defined(_WIN32_WCE) +extern "C" void _ReadWriteBarrier(void); +#pragma intrinsic(_ReadWriteBarrier) +#define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() _ReadWriteBarrier() +#endif + +#ifndef BOOST_ATOMIC_DETAIL_COMPILER_BARRIER +#define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() +#endif + +#endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_msvc_x86.hpp b/boost/atomic/detail/ops_msvc_x86.hpp new file mode 100644 index 00000000..70b0ea99 --- /dev/null +++ b/boost/atomic/detail/ops_msvc_x86.hpp @@ -0,0 +1,908 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_msvc_x86.hpp + * + * This header contains implementation of the \c operations template. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) +#include +#include +#endif +#include +#if !defined(_M_IX86) && !(defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8) && defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16)) +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +// frame pointer register 'ebx' modified by inline assembly code. See the note below. +#pragma warning(disable: 4731) +#endif + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE) +extern "C" void _mm_mfence(void); +#if defined(BOOST_MSVC) +#pragma intrinsic(_mm_mfence) +#endif +#endif + +namespace boost { +namespace atomics { +namespace detail { + +/* + * Implementation note for asm blocks. + * + * http://msdn.microsoft.com/en-us/data/k1a8ss06%28v=vs.105%29 + * + * Some SSE types require eight-byte stack alignment, forcing the compiler to emit dynamic stack-alignment code. + * To be able to access both the local variables and the function parameters after the alignment, the compiler + * maintains two frame pointers. If the compiler performs frame pointer omission (FPO), it will use EBP and ESP. + * If the compiler does not perform FPO, it will use EBX and EBP. To ensure code runs correctly, do not modify EBX + * in asm code if the function requires dynamic stack alignment as it could modify the frame pointer. + * Either move the eight-byte aligned types out of the function, or avoid using EBX. + * + * Since we have no way of knowing that the compiler uses FPO, we have to always save and restore ebx + * whenever we have to clobber it. Additionally, we disable warning C4731 above so that the compiler + * doesn't spam about ebx use. + */ + +struct msvc_x86_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE) + _mm_mfence(); +#else + long tmp; + BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&tmp, 0); +#endif + } + + static BOOST_FORCEINLINE void fence_before(memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } + + static BOOST_FORCEINLINE void fence_after(memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } + + static BOOST_FORCEINLINE void fence_after_load(memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + // On x86 and x86_64 there is no need for a hardware barrier, + // even if seq_cst memory order is requested, because all + // seq_cst writes are implemented with lock-prefixed operations + // or xchg which has implied lock prefix. Therefore normal loads + // are already ordered with seq_cst stores on these architectures. + } +}; + +template< std::size_t Size, bool Signed, typename Derived > +struct msvc_x86_operations : + public msvc_x86_operations_base +{ + typedef typename make_storage_type< Size >::type storage_type; + typedef typename make_storage_type< Size >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + if (order != memory_order_seq_cst) + { + fence_before(order); + storage = v; + fence_after(order); + } + else + { + Derived::exchange(storage, v, order); + } + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + storage_type v = storage; + fence_after_load(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + typedef typename boost::atomics::detail::make_signed< storage_type >::type signed_storage_type; + return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!Derived::exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, (storage_type)0, order); + } +}; + +template< bool Signed > +struct operations< 4u, Signed > : + public msvc_x86_operations< 4u, Signed, operations< 4u, Signed > > +{ + typedef msvc_x86_operations< 4u, Signed, operations< 4u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v)); + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous)); + expected = old_val; + return (previous == old_val); + } + +#if defined(BOOST_ATOMIC_INTERLOCKED_AND) + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v)); + } +#else + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type res = storage; + while (!compare_exchange_strong(storage, res, res & v, order, memory_order_relaxed)) {} + return res; + } +#endif + +#if defined(BOOST_ATOMIC_INTERLOCKED_OR) + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v)); + } +#else + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type res = storage; + while (!compare_exchange_strong(storage, res, res | v, order, memory_order_relaxed)) {} + return res; + } +#endif + +#if defined(BOOST_ATOMIC_INTERLOCKED_XOR) + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v)); + } +#else + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type res = storage; + while (!compare_exchange_strong(storage, res, res ^ v, order, memory_order_relaxed)) {} + return res; + } +#endif +}; + +#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8) + +template< bool Signed > +struct operations< 1u, Signed > : + public msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > +{ + typedef msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&storage, v)); + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&storage, desired, previous)); + expected = old_val; + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8(&storage, v)); + } +}; + +#elif defined(_M_IX86) + +template< bool Signed > +struct operations< 1u, Signed > : + public msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > +{ + typedef msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock xadd byte ptr [edx], al + mov v, al + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + xchg byte ptr [edx], al + mov v, al + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order) BOOST_NOEXCEPT + { + base_type::fence_before(success_order); + bool success; + __asm + { + mov esi, expected + mov edi, storage + movzx eax, byte ptr [esi] + movzx edx, desired + lock cmpxchg byte ptr [edi], dl + mov byte ptr [esi], al + sete success + }; + // The success and failure fences are equivalent anyway + base_type::fence_after(success_order); + return success; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, byte ptr [edi] + align 16 + again: + mov dl, al + and dl, cl + lock cmpxchg byte ptr [edi], dl + jne again + mov v, al + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, byte ptr [edi] + align 16 + again: + mov dl, al + or dl, cl + lock cmpxchg byte ptr [edi], dl + jne again + mov v, al + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, byte ptr [edi] + align 16 + again: + mov dl, al + xor dl, cl + lock cmpxchg byte ptr [edi], dl + jne again + mov v, al + }; + base_type::fence_after(order); + return v; + } +}; + +#else + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed > +{ +}; + +#endif + +#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16) + +template< bool Signed > +struct operations< 2u, Signed > : + public msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > +{ + typedef msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&storage, v)); + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&storage, desired, previous)); + expected = old_val; + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16(&storage, v)); + } +}; + +#elif defined(_M_IX86) + +template< bool Signed > +struct operations< 2u, Signed > : + public msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > +{ + typedef msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + lock xadd word ptr [edx], ax + mov v, ax + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edx, storage + movzx eax, v + xchg word ptr [edx], ax + mov v, ax + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order) BOOST_NOEXCEPT + { + base_type::fence_before(success_order); + bool success; + __asm + { + mov esi, expected + mov edi, storage + movzx eax, word ptr [esi] + movzx edx, desired + lock cmpxchg word ptr [edi], dx + mov word ptr [esi], ax + sete success + }; + // The success and failure fences are equivalent anyway + base_type::fence_after(success_order); + return success; + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, word ptr [edi] + align 16 + again: + mov dx, ax + and dx, cx + lock cmpxchg word ptr [edi], dx + jne again + mov v, ax + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, word ptr [edi] + align 16 + again: + mov dx, ax + or dx, cx + lock cmpxchg word ptr [edi], dx + jne again + mov v, ax + }; + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + __asm + { + mov edi, storage + movzx ecx, v + xor edx, edx + movzx eax, word ptr [edi] + align 16 + again: + mov dx, ax + xor dx, cx + lock cmpxchg word ptr [edi], dx + jne again + mov v, ax + }; + base_type::fence_after(order); + return v; + } +}; + +#else + +template< bool Signed > +struct operations< 2u, Signed > : + public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed > +{ +}; + +#endif + + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) + +template< bool Signed > +struct msvc_dcas_x86 +{ + typedef typename make_storage_type< 8u >::type storage_type; + typedef typename make_storage_type< 8u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + // Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, 8.1.1. Guaranteed Atomic Operations: + // + // The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically: + // * Reading or writing a quadword aligned on a 64-bit boundary + // + // Luckily, the memory is almost always 8-byte aligned in our case because atomic<> uses 64 bit native types for storage and dynamic memory allocations + // have at least 8 byte alignment. The only unfortunate case is when atomic is placed on the stack and it is not 8-byte aligned (like on 32 bit Windows). + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + storage_type volatile* p = &storage; + if (((uint32_t)p & 0x00000007) == 0) + { +#if defined(_M_IX86_FP) && _M_IX86_FP >= 2 +#if defined(__AVX__) + __asm + { + mov edx, p + vmovq xmm4, v + vmovq qword ptr [edx], xmm4 + }; +#else + __asm + { + mov edx, p + movq xmm4, v + movq qword ptr [edx], xmm4 + }; +#endif +#else + __asm + { + mov edx, p + fild v + fistp qword ptr [edx] + }; +#endif + } + else + { + uint32_t backup; + __asm + { + mov backup, ebx + mov edi, p + mov ebx, dword ptr [v] + mov ecx, dword ptr [v + 4] + mov eax, dword ptr [edi] + mov edx, dword ptr [edi + 4] + align 16 + again: + lock cmpxchg8b qword ptr [edi] + jne again + mov ebx, backup + }; + } + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + storage_type const volatile* p = &storage; + storage_type value; + + if (((uint32_t)p & 0x00000007) == 0) + { +#if defined(_M_IX86_FP) && _M_IX86_FP >= 2 +#if defined(__AVX__) + __asm + { + mov edx, p + vmovq xmm4, qword ptr [edx] + vmovq value, xmm4 + }; +#else + __asm + { + mov edx, p + movq xmm4, qword ptr [edx] + movq value, xmm4 + }; +#endif +#else + __asm + { + mov edx, p + fild qword ptr [edx] + fistp value + }; +#endif + } + else + { + // We don't care for comparison result here; the previous value will be stored into value anyway. + // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b. + __asm + { + mov edi, p + mov eax, ebx + mov edx, ecx + lock cmpxchg8b qword ptr [edi] + mov dword ptr [value], eax + mov dword ptr [value + 4], edx + }; + } + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + return value; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + // MSVC-11 in 32-bit mode sometimes generates messed up code without compiler barriers, + // even though the _InterlockedCompareExchange64 intrinsic already provides one. + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + storage_type volatile* p = &storage; +#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64) + const storage_type old_val = (storage_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(p, desired, expected); + const bool result = (old_val == expected); + expected = old_val; +#else + bool result; + uint32_t backup; + __asm + { + mov backup, ebx + mov edi, p + mov esi, expected + mov ebx, dword ptr [desired] + mov ecx, dword ptr [desired + 4] + mov eax, dword ptr [esi] + mov edx, dword ptr [esi + 4] + lock cmpxchg8b qword ptr [edi] + mov dword ptr [esi], eax + mov dword ptr [esi + 4], edx + mov ebx, backup + sete result + }; +#endif + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + return result; + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + storage_type volatile* p = &storage; + uint32_t backup; + __asm + { + mov backup, ebx + mov edi, p + mov ebx, dword ptr [v] + mov ecx, dword ptr [v + 4] + mov eax, dword ptr [edi] + mov edx, dword ptr [edi + 4] + align 16 + again: + lock cmpxchg8b qword ptr [edi] + jne again + mov ebx, backup + mov dword ptr [v], eax + mov dword ptr [v + 4], edx + }; + + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + + return v; + } +}; + +template< bool Signed > +struct operations< 8u, Signed > : + public cas_based_operations< msvc_dcas_x86< Signed > > +{ +}; + +#elif defined(_M_AMD64) + +template< bool Signed > +struct operations< 8u, Signed > : + public msvc_x86_operations< 8u, Signed, operations< 8u, Signed > > +{ + typedef msvc_x86_operations< 8u, Signed, operations< 8u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(&storage, v)); + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(&storage, desired, previous)); + expected = old_val; + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64(&storage, v)); + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64(&storage, v)); + } +}; + +#endif + +#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) + +template< bool Signed > +struct msvc_dcas_x86_64 +{ + typedef typename make_storage_type< 16u >::type storage_type; + typedef typename make_storage_type< 16u >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 16u; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT + { + storage_type value = const_cast< storage_type& >(storage); + while (!BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, v, &value)) {} + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT + { + storage_type value = storage_type(); + BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, value, &value); + return value; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT + { + return !!BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, desired, &expected); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } +}; + +template< bool Signed > +struct operations< 16u, Signed > : + public cas_based_operations< cas_based_exchange< msvc_dcas_x86_64< Signed > > > +{ +}; + +#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + if (order == memory_order_seq_cst) + msvc_x86_operations_base::hardware_full_fence(); + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_ diff --git a/boost/atomic/detail/ops_windows.hpp b/boost/atomic/detail/ops_windows.hpp new file mode 100644 index 00000000..d4ce6d95 --- /dev/null +++ b/boost/atomic/detail/ops_windows.hpp @@ -0,0 +1,218 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/ops_windows.hpp + * + * This header contains implementation of the \c operations template. + * + * This implementation is the most basic version for Windows. It should + * work for any non-MSVC-like compilers as long as there are Interlocked WinAPI + * functions available. This version is also used for WinCE. + * + * Notably, this implementation is not as efficient as other + * versions based on compiler intrinsics. + */ + +#ifndef BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +struct windows_operations_base +{ + static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false; + static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true; + + static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT + { + long tmp; + BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&tmp, 0); + } + + static BOOST_FORCEINLINE void fence_before(memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } + + static BOOST_FORCEINLINE void fence_after(memory_order) BOOST_NOEXCEPT + { + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + } +}; + +template< std::size_t Size, bool Signed, typename Derived > +struct windows_operations : + public windows_operations_base +{ + typedef typename make_storage_type< Size >::type storage_type; + typedef typename make_storage_type< Size >::aligned aligned_storage_type; + + static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size; + static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed; + + static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + Derived::exchange(storage, v, order); + } + + static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return Derived::fetch_add(const_cast< storage_type volatile& >(storage), (storage_type)0, order); + } + + static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + typedef typename boost::atomics::detail::make_signed< storage_type >::type signed_storage_type; + return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order); + } + + static BOOST_FORCEINLINE bool compare_exchange_weak( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order); + } + + static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + return !!Derived::exchange(storage, (storage_type)1, order); + } + + static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT + { + store(storage, (storage_type)0, order); + } +}; + +template< bool Signed > +struct operations< 4u, Signed > : + public windows_operations< 4u, Signed, operations< 4u, Signed > > +{ + typedef windows_operations< 4u, Signed, operations< 4u, Signed > > base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v)); + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + base_type::fence_before(order); + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v)); + base_type::fence_after(order); + return v; + } + + static BOOST_FORCEINLINE bool compare_exchange_strong( + storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT + { + storage_type previous = expected; + base_type::fence_before(success_order); + storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous)); + expected = old_val; + // The success and failure fences are the same anyway + base_type::fence_after(success_order); + return (previous == old_val); + } + + static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_INTERLOCKED_AND) + base_type::fence_before(order); + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v)); + base_type::fence_after(order); + return v; +#else + storage_type res = storage; + while (!compare_exchange_strong(storage, res, res & v, order, memory_order_relaxed)) {} + return res; +#endif + } + + static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_INTERLOCKED_OR) + base_type::fence_before(order); + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v)); + base_type::fence_after(order); + return v; +#else + storage_type res = storage; + while (!compare_exchange_strong(storage, res, res | v, order, memory_order_relaxed)) {} + return res; +#endif + } + + static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { +#if defined(BOOST_ATOMIC_INTERLOCKED_XOR) + base_type::fence_before(order); + v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v)); + base_type::fence_after(order); + return v; +#else + storage_type res = storage; + while (!compare_exchange_strong(storage, res, res ^ v, order, memory_order_relaxed)) {} + return res; +#endif + } +}; + +template< bool Signed > +struct operations< 1u, Signed > : + public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed > +{ +}; + +template< bool Signed > +struct operations< 2u, Signed > : + public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed > +{ +}; + +BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT +{ + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); + if (order == memory_order_seq_cst) + windows_operations_base::hardware_full_fence(); + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); +} + +BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT +{ + if (order != memory_order_relaxed) + BOOST_ATOMIC_DETAIL_COMPILER_BARRIER(); +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/pause.hpp b/boost/atomic/detail/pause.hpp new file mode 100644 index 00000000..37aa5ca8 --- /dev/null +++ b/boost/atomic/detail/pause.hpp @@ -0,0 +1,43 @@ +/* + * 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) + * + * (C) Copyright 2013 Tim Blechmann + * (C) Copyright 2013 Andrey Semashev + */ + +#ifndef BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86)) +extern "C" void _mm_pause(void); +#if defined(BOOST_MSVC) +#pragma intrinsic(_mm_pause) +#endif +#endif + +namespace boost { +namespace atomics { +namespace detail { + +BOOST_FORCEINLINE void pause() BOOST_NOEXCEPT +{ +#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86)) + _mm_pause(); +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + __asm__ __volatile__("pause;"); +#endif +} + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_ diff --git a/boost/atomic/detail/platform.hpp b/boost/atomic/detail/platform.hpp new file mode 100644 index 00000000..df4cc305 --- /dev/null +++ b/boost/atomic/detail/platform.hpp @@ -0,0 +1,163 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/platform.hpp + * + * This header defines macros for the target platform detection + */ + +#ifndef BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__GNUC__) && defined(__arm__) + +// Newer gcc versions define __ARM_ARCH. Older ones don't, so we have to deduce ARM arch version from a bunch of version-specific macros. +#if defined(__ARM_ARCH) +#define BOOST_ATOMIC_DETAIL_ARM_ARCH __ARM_ARCH +#elif defined(__ARM_ARCH_8A__) +#define BOOST_ATOMIC_DETAIL_ARM_ARCH 8 +#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) ||\ + defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) ||\ + defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__) +#define BOOST_ATOMIC_DETAIL_ARM_ARCH 7 +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) ||\ + defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) ||\ + defined(__ARM_ARCH_6ZK__) +#define BOOST_ATOMIC_DETAIL_ARM_ARCH 6 +#else +// We are not interested in older versions - they don't support atomic ops +#define BOOST_ATOMIC_DETAIL_ARM_ARCH 0 +#endif + +#endif // defined(__GNUC__) && defined(__arm__) + +#if !defined(BOOST_ATOMIC_FORCE_FALLBACK) + +// Determine the target platform. +// The target platform describes the compiler and target architecture. It can be used by more generic backends, such as the ones +// based on compiler intrinsics, to implement specialized operations in a non-generic way. + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_x86 +#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND gcc_x86 + +#elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__PPC__)) + +#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_ppc +#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND gcc_ppc + +#elif defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH+0) >= 6 + +#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_arm +#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND gcc_arm + +#elif (defined(__GNUC__) || defined(__SUNPRO_CC)) && (defined(__sparcv8plus) || defined(__sparc_v9__)) + +#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_sparc + +#elif defined(__GNUC__) && defined(__alpha__) + +#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_alpha + +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + +#define BOOST_ATOMIC_DETAIL_PLATFORM msvc_x86 + +#elif defined(_MSC_VER) && _MSC_VER >= 1700 && (defined(_M_ARM) || defined(_M_ARM64)) + +#define BOOST_ATOMIC_DETAIL_PLATFORM msvc_arm + +#endif + +// Compiler-based backends + +// IBM XL C++ Compiler has to be checked before GCC/Clang as it pretends to be one but does not support __atomic* intrinsics. +// It does support GCC inline assembler though. +#if !(defined(__ibmxl__) || defined(__IBMCPP__)) &&\ + ((defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407)) ||\ + (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302))) &&\ + (\ + (__GCC_ATOMIC_BOOL_LOCK_FREE + 0) == 2 ||\ + (__GCC_ATOMIC_CHAR_LOCK_FREE + 0) == 2 ||\ + (__GCC_ATOMIC_SHORT_LOCK_FREE + 0) == 2 ||\ + (__GCC_ATOMIC_INT_LOCK_FREE + 0) == 2 ||\ + (__GCC_ATOMIC_LONG_LOCK_FREE + 0) == 2 ||\ + (__GCC_ATOMIC_LLONG_LOCK_FREE + 0) == 2\ + ) + +#define BOOST_ATOMIC_DETAIL_BACKEND gcc_atomic + +#elif defined(BOOST_ATOMIC_DETAIL_PLATFORM) + +#define BOOST_ATOMIC_DETAIL_BACKEND BOOST_ATOMIC_DETAIL_PLATFORM + +#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 401) &&\ + (\ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) ||\ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) ||\ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) ||\ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)\ + ) + +#define BOOST_ATOMIC_DETAIL_BACKEND gcc_sync + +#endif + +// OS-based backends + +#if !defined(BOOST_ATOMIC_DETAIL_BACKEND) + +#if defined(__linux__) && defined(__arm__) + +#define BOOST_ATOMIC_DETAIL_BACKEND linux_arm + +#elif defined(BOOST_WINDOWS) || defined(_WIN32_CE) + +#define BOOST_ATOMIC_DETAIL_BACKEND windows + +#endif + +#endif // !defined(BOOST_ATOMIC_DETAIL_BACKEND) + +#endif // !defined(BOOST_ATOMIC_FORCE_FALLBACK) + +#if !defined(BOOST_ATOMIC_DETAIL_BACKEND) +#define BOOST_ATOMIC_DETAIL_BACKEND emulated +#define BOOST_ATOMIC_EMULATED +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_FP_BACKEND) +#define BOOST_ATOMIC_DETAIL_FP_BACKEND generic +#define BOOST_ATOMIC_DETAIL_FP_BACKEND_GENERIC +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_BACKEND) +#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND generic +#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_GENERIC +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND) +#define BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND generic +#define BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_GENERIC +#endif + +#define BOOST_ATOMIC_DETAIL_BACKEND_HEADER(prefix) +#define BOOST_ATOMIC_DETAIL_FP_BACKEND_HEADER(prefix) +#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_HEADER(prefix) +#define BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_HEADER(prefix) + +#endif // BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_ diff --git a/boost/atomic/detail/storage_type.hpp b/boost/atomic/detail/storage_type.hpp new file mode 100644 index 00000000..5d824d3a --- /dev/null +++ b/boost/atomic/detail/storage_type.hpp @@ -0,0 +1,207 @@ +/* + * 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) + * + * Copyright (c) 2009 Helge Bahmann + * Copyright (c) 2012 Tim Blechmann + * Copyright (c) 2013 - 2014 Andrey Semashev + */ +/*! + * \file atomic/detail/storage_type.hpp + * + * This header defines underlying types used as storage + */ + +#ifndef BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ + +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename T > +BOOST_FORCEINLINE void non_atomic_load(T const volatile& from, T& to) BOOST_NOEXCEPT +{ + to = from; +} + +template< std::size_t Size > +struct BOOST_ATOMIC_DETAIL_MAY_ALIAS buffer_storage +{ + BOOST_ALIGNMENT(16) unsigned char data[Size]; + + BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT + { + return (data[0] == 0u && BOOST_ATOMIC_DETAIL_MEMCMP(data, data + 1, Size - 1) == 0); + } + + BOOST_FORCEINLINE bool operator== (buffer_storage const& that) const BOOST_NOEXCEPT + { + return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) == 0; + } + + BOOST_FORCEINLINE bool operator!= (buffer_storage const& that) const BOOST_NOEXCEPT + { + return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) != 0; + } +}; + +template< std::size_t Size > +BOOST_FORCEINLINE void non_atomic_load(buffer_storage< Size > const volatile& from, buffer_storage< Size >& to) BOOST_NOEXCEPT +{ + BOOST_ATOMIC_DETAIL_MEMCPY(to.data, const_cast< unsigned char const* >(from.data), Size); +} + +template< std::size_t Size > +struct make_storage_type +{ + typedef buffer_storage< Size > type; + + struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned + { + type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} + }; +}; + +template< > +struct make_storage_type< 1u > +{ + typedef boost::uint8_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type; + + struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned + { + type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; +}; + +template< > +struct make_storage_type< 2u > +{ + typedef boost::uint16_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type; + + struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned + { + BOOST_ALIGNMENT(2) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; +}; + +template< > +struct make_storage_type< 4u > +{ + typedef boost::uint32_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type; + + struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned + { + BOOST_ALIGNMENT(4) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; +}; + +template< > +struct make_storage_type< 8u > +{ + typedef boost::uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type; + + struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned + { + BOOST_ALIGNMENT(8) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; +}; + +#if defined(BOOST_HAS_INT128) + +template< > +struct make_storage_type< 16u > +{ + typedef boost::uint128_type BOOST_ATOMIC_DETAIL_MAY_ALIAS type; + + struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned + { + BOOST_ALIGNMENT(16) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type v) BOOST_NOEXCEPT : value(v) {} + }; +}; + +#elif !defined(BOOST_NO_ALIGNMENT) + +struct BOOST_ATOMIC_DETAIL_MAY_ALIAS storage128_t +{ + typedef boost::uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS element_type; + + element_type data[2]; + + BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT + { + return (data[0] | data[1]) == 0u; + } +}; + +BOOST_FORCEINLINE bool operator== (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT +{ + return ((left.data[0] ^ right.data[0]) | (left.data[1] ^ right.data[1])) == 0u; +} +BOOST_FORCEINLINE bool operator!= (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT +{ + return !(left == right); +} + +BOOST_FORCEINLINE void non_atomic_load(storage128_t const volatile& from, storage128_t& to) BOOST_NOEXCEPT +{ + to.data[0] = from.data[0]; + to.data[1] = from.data[1]; +} + +template< > +struct make_storage_type< 16u > +{ + typedef storage128_t type; + + struct BOOST_ATOMIC_DETAIL_MAY_ALIAS aligned + { + BOOST_ALIGNMENT(16) type value; + + BOOST_DEFAULTED_FUNCTION(aligned(), {}) + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit aligned(type const& v) BOOST_NOEXCEPT : value(v) {} + }; +}; + +#endif + +template< typename T > +struct storage_size_of +{ + static BOOST_CONSTEXPR_OR_CONST std::size_t size = sizeof(T); + static BOOST_CONSTEXPR_OR_CONST std::size_t value = (size == 3u ? 4u : (size >= 5u && size <= 7u ? 8u : (size >= 9u && size <= 15u ? 16u : size))); +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_STORAGE_TYPE_HPP_INCLUDED_ diff --git a/boost/atomic/detail/string_ops.hpp b/boost/atomic/detail/string_ops.hpp new file mode 100644 index 00000000..ce145b98 --- /dev/null +++ b/boost/atomic/detail/string_ops.hpp @@ -0,0 +1,61 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/string_ops.hpp + * + * This header defines string operations for Boost.Atomic + */ + +#ifndef BOOST_ATOMIC_DETAIL_STRING_OPS_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_STRING_OPS_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined(__has_builtin) +#if __has_builtin(__builtin_memcpy) +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY +#endif +#if __has_builtin(__builtin_memcmp) +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP +#endif +#if __has_builtin(__builtin_memset) +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET +#endif +#elif defined(BOOST_GCC) +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP +#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET +#endif + +#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) +#define BOOST_ATOMIC_DETAIL_MEMCPY __builtin_memcpy +#else +#define BOOST_ATOMIC_DETAIL_MEMCPY std::memcpy +#endif + +#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) +#define BOOST_ATOMIC_DETAIL_MEMCMP __builtin_memcmp +#else +#define BOOST_ATOMIC_DETAIL_MEMCMP std::memcmp +#endif + +#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET) +#define BOOST_ATOMIC_DETAIL_MEMSET __builtin_memset +#else +#define BOOST_ATOMIC_DETAIL_MEMSET std::memset +#endif + +#if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET) +#include +#endif + +#endif // BOOST_ATOMIC_DETAIL_STRING_OPS_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/conditional.hpp b/boost/atomic/detail/type_traits/conditional.hpp new file mode 100644 index 00000000..6b9e8967 --- /dev/null +++ b/boost/atomic/detail/type_traits/conditional.hpp @@ -0,0 +1,42 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/conditional.hpp + * + * This header defines \c conditional type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_CONDITIONAL_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_CONDITIONAL_HPP_INCLUDED_ + +#include +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +using std::conditional; +#else +using boost::conditional; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_CONDITIONAL_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/integral_constant.hpp b/boost/atomic/detail/type_traits/integral_constant.hpp new file mode 100644 index 00000000..eac86491 --- /dev/null +++ b/boost/atomic/detail/type_traits/integral_constant.hpp @@ -0,0 +1,46 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/integral_constant.hpp + * + * This header defines \c integral_constant wrapper + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP_INCLUDED_ + +#include +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +using std::integral_constant; +using std::true_type; +using std::false_type; +#else +using boost::integral_constant; +using boost::true_type; +using boost::false_type; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/is_floating_point.hpp b/boost/atomic/detail/type_traits/is_floating_point.hpp new file mode 100644 index 00000000..c425112b --- /dev/null +++ b/boost/atomic/detail/type_traits/is_floating_point.hpp @@ -0,0 +1,42 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/is_floating_point.hpp + * + * This header defines \c is_floating_point type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FLOATING_POINT_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FLOATING_POINT_HPP_INCLUDED_ + +#include +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +using std::is_floating_point; +#else +using boost::is_floating_point; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FLOATING_POINT_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/is_function.hpp b/boost/atomic/detail/type_traits/is_function.hpp new file mode 100644 index 00000000..e7205356 --- /dev/null +++ b/boost/atomic/detail/type_traits/is_function.hpp @@ -0,0 +1,42 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/is_function.hpp + * + * This header defines \c is_function type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FUNCTION_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FUNCTION_HPP_INCLUDED_ + +#include +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) +using std::is_function; +#else +using boost::is_function; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FUNCTION_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/is_iec559.hpp b/boost/atomic/detail/type_traits/is_iec559.hpp new file mode 100644 index 00000000..299c4f0f --- /dev/null +++ b/boost/atomic/detail/type_traits/is_iec559.hpp @@ -0,0 +1,47 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/is_iec559.hpp + * + * This header defines \c is_iec559 type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_IEC559_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_IEC559_HPP_INCLUDED_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename T > +struct is_iec559 +{ + static BOOST_CONSTEXPR_OR_CONST bool value = !!std::numeric_limits< T >::is_iec559; +}; + +#if defined(BOOST_HAS_FLOAT128) +// libstdc++ does not specialize numeric_limits for __float128 +template< > +struct is_iec559< boost::float128_type > +{ + static BOOST_CONSTEXPR_OR_CONST bool value = true; +}; +#endif // defined(BOOST_HAS_FLOAT128) + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_IEC559_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/is_integral.hpp b/boost/atomic/detail/type_traits/is_integral.hpp new file mode 100644 index 00000000..ef3e2e34 --- /dev/null +++ b/boost/atomic/detail/type_traits/is_integral.hpp @@ -0,0 +1,43 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/is_integral.hpp + * + * This header defines \c is_integral type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_INTEGRAL_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_INTEGRAL_HPP_INCLUDED_ + +#include +// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +using std::is_integral; +#else +using boost::is_integral; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_INTEGRAL_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/is_signed.hpp b/boost/atomic/detail/type_traits/is_signed.hpp new file mode 100644 index 00000000..2dc1df72 --- /dev/null +++ b/boost/atomic/detail/type_traits/is_signed.hpp @@ -0,0 +1,43 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/is_signed.hpp + * + * This header defines \c is_signed type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_SIGNED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_SIGNED_HPP_INCLUDED_ + +#include +// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +using std::is_signed; +#else +using boost::is_signed; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_SIGNED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp b/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp new file mode 100644 index 00000000..5f88b88e --- /dev/null +++ b/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp @@ -0,0 +1,46 @@ +/* + * 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) + * + * Copyright (c) 2018 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/is_trivially_default_constructible.hpp + * + * This header defines \c is_trivially_default_constructible type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_ + +#include +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) +using std::is_trivially_default_constructible; +#elif !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template< typename T > +using is_trivially_default_constructible = boost::has_trivial_constructor< T >; +#else +template< typename T > +struct is_trivially_default_constructible : public boost::has_trivial_constructor< T > {}; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/make_signed.hpp b/boost/atomic/detail/type_traits/make_signed.hpp new file mode 100644 index 00000000..82f61b33 --- /dev/null +++ b/boost/atomic/detail/type_traits/make_signed.hpp @@ -0,0 +1,43 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/make_signed.hpp + * + * This header defines \c make_signed type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_SIGNED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_SIGNED_HPP_INCLUDED_ + +#include +// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +using std::make_signed; +#else +using boost::make_signed; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_SIGNED_HPP_INCLUDED_ diff --git a/boost/atomic/detail/type_traits/make_unsigned.hpp b/boost/atomic/detail/type_traits/make_unsigned.hpp new file mode 100644 index 00000000..573a1616 --- /dev/null +++ b/boost/atomic/detail/type_traits/make_unsigned.hpp @@ -0,0 +1,43 @@ +/* + * 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) + * + * Copyright (c) 2017 Andrey Semashev + */ +/*! + * \file atomic/detail/type_traits/make_unsigned.hpp + * + * This header defines \c make_unsigned type trait + */ + +#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_UNSIGNED_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_UNSIGNED_HPP_INCLUDED_ + +#include +// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that. +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +#include +#else +#include +#endif + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128) +using std::make_unsigned; +#else +using boost::make_unsigned; +#endif + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_UNSIGNED_HPP_INCLUDED_ diff --git a/boost/atomic/fences.hpp b/boost/atomic/fences.hpp new file mode 100644 index 00000000..31e30405 --- /dev/null +++ b/boost/atomic/fences.hpp @@ -0,0 +1,67 @@ +/* + * 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) + * + * Copyright (c) 2011 Helge Bahmann + * Copyright (c) 2013 Tim Blechmann + * Copyright (c) 2014 Andrey Semashev + */ +/*! + * \file atomic/fences.hpp + * + * This header contains definition of \c atomic_thread_fence and \c atomic_signal_fence functions. + */ + +#ifndef BOOST_ATOMIC_FENCES_HPP_INCLUDED_ +#define BOOST_ATOMIC_FENCES_HPP_INCLUDED_ + +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +/* + * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE, + * see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp. + */ + +namespace boost { + +namespace atomics { + +#if BOOST_ATOMIC_THREAD_FENCE > 0 +BOOST_FORCEINLINE void atomic_thread_fence(memory_order order) BOOST_NOEXCEPT +{ + detail::thread_fence(order); +} +#else +BOOST_FORCEINLINE void atomic_thread_fence(memory_order) BOOST_NOEXCEPT +{ + detail::lockpool::thread_fence(); +} +#endif + +#if BOOST_ATOMIC_SIGNAL_FENCE > 0 +BOOST_FORCEINLINE void atomic_signal_fence(memory_order order) BOOST_NOEXCEPT +{ + detail::signal_fence(order); +} +#else +BOOST_FORCEINLINE void atomic_signal_fence(memory_order) BOOST_NOEXCEPT +{ + detail::lockpool::signal_fence(); +} +#endif + +} // namespace atomics + +using atomics::atomic_thread_fence; +using atomics::atomic_signal_fence; + +} // namespace boost + +#endif // BOOST_ATOMIC_FENCES_HPP_INCLUDED_ diff --git a/boost/bind.hpp b/boost/bind.hpp new file mode 100644 index 00000000..450120c7 --- /dev/null +++ b/boost/bind.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_BIND_HPP_INCLUDED +#define BOOST_BIND_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind.hpp - binds function objects to arguments +// +// Copyright (c) 2009, 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 +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include + +#ifndef BOOST_BIND_NO_PLACEHOLDERS + +#if defined(BOOST_CLANG) +# pragma clang diagnostic push +# if __has_warning("-Wheader-hygiene") +# pragma clang diagnostic ignored "-Wheader-hygiene" +# endif +#endif + +using namespace boost::placeholders; + +#if defined(BOOST_CLANG) +# pragma clang diagnostic pop +#endif + +#endif // #ifndef BOOST_BIND_NO_PLACEHOLDERS + +#endif // #ifndef BOOST_BIND_HPP_INCLUDED diff --git a/boost/bind/arg.hpp b/boost/bind/arg.hpp new file mode 100644 index 00000000..cb52e668 --- /dev/null +++ b/boost/bind/arg.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_BIND_ARG_HPP_INCLUDED +#define BOOST_BIND_ARG_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/arg.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// 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/bind/bind.html for documentation. +// + +#include +#include + +namespace boost +{ + +template struct _arg_eq +{ +}; + +template<> struct _arg_eq +{ + typedef void type; +}; + +template< int I > struct arg +{ + BOOST_CONSTEXPR arg() + { + } + + template< class T > BOOST_CONSTEXPR arg( T const & /* t */, typename _arg_eq< I == is_placeholder::value >::type * = 0 ) + { + } +}; + +template< int I > BOOST_CONSTEXPR bool operator==( arg const &, arg const & ) +{ + return true; +} + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< int I > struct is_placeholder< arg > +{ + enum _vt { value = I }; +}; + +template< int I > struct is_placeholder< arg (*) () > +{ + enum _vt { value = I }; +}; + +#endif + +} // namespace boost + +#endif // #ifndef BOOST_BIND_ARG_HPP_INCLUDED diff --git a/boost/bind/bind.hpp b/boost/bind/bind.hpp new file mode 100644 index 00000000..4cedc5e9 --- /dev/null +++ b/boost/bind/bind.hpp @@ -0,0 +1,2365 @@ +#ifndef BOOST_BIND_BIND_HPP_INCLUDED +#define BOOST_BIND_BIND_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind.hpp - binds function objects to arguments +// +// Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2001 David Abrahams +// Copyright (c) 2005 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) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) +#include // std::forward +#endif + +// Borland-specific bug, visit_each() silently fails to produce code + +#if defined(__BORLANDC__) +# define BOOST_BIND_VISIT_EACH boost::visit_each +#else +# define BOOST_BIND_VISIT_EACH visit_each +#endif + +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace boost +{ + +template class weak_ptr; + +namespace _bi // implementation details +{ + +// result_traits + +template struct result_traits +{ + typedef R type; +}; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +struct unspecified {}; + +template struct result_traits +{ + typedef typename F::result_type type; +}; + +template struct result_traits< unspecified, reference_wrapper > +{ + typedef typename F::result_type type; +}; + +#endif + +// ref_compare + +template bool ref_compare( T const & a, T const & b, long ) +{ + return a == b; +} + +template bool ref_compare( arg const &, arg const &, int ) +{ + return true; +} + +template bool ref_compare( arg (*) (), arg (*) (), int ) +{ + return true; +} + +template bool ref_compare( reference_wrapper const & a, reference_wrapper const & b, int ) +{ + return a.get_pointer() == b.get_pointer(); +} + +// bind_t forward declaration for listN + +template class bind_t; + +template bool ref_compare( bind_t const & a, bind_t const & b, int ) +{ + return a.compare( b ); +} + +// value + +template class value +{ +public: + + value(T const & t): t_(t) {} + + T & get() { return t_; } + T const & get() const { return t_; } + + bool operator==(value const & rhs) const + { + return t_ == rhs.t_; + } + +private: + + T t_; +}; + +// ref_compare for weak_ptr + +template bool ref_compare( value< weak_ptr > const & a, value< weak_ptr > const & b, int ) +{ + return !(a.get() < b.get()) && !(b.get() < a.get()); +} + +// type + +template class type {}; + +// unwrap + +template struct unwrapper +{ + static inline F & unwrap( F & f, long ) + { + return f; + } + + template static inline F2 & unwrap( reference_wrapper rf, int ) + { + return rf.get(); + } + + template static inline _mfi::dm unwrap( R T::* pm, int ) + { + return _mfi::dm( pm ); + } +}; + +// listN + +class list0 +{ +public: + + list0() {} + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A &, long) + { + return unwrapper::unwrap(f, 0)(); + } + + template R operator()(type, F const & f, A &, long) const + { + return unwrapper::unwrap(f, 0)(); + } + + template void operator()(type, F & f, A &, int) + { + unwrapper::unwrap(f, 0)(); + } + + template void operator()(type, F const & f, A &, int) const + { + unwrapper::unwrap(f, 0)(); + } + + template void accept(V &) const + { + } + + bool operator==(list0 const &) const + { + return true; + } +}; + +#ifdef BOOST_MSVC +// MSVC is bright enough to realise that the parameter rhs +// in operator==may be unused for some template argument types: +#pragma warning(push) +#pragma warning(disable:4100) +#endif + +template< class A1 > class list1: private storage1< A1 > +{ +private: + + typedef storage1< A1 > base_type; + +public: + + explicit list1( A1 a1 ): base_type( a1 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list1 const & rhs) const + { + return ref_compare(base_type::a1_, rhs.a1_, 0); + } +}; + +struct logical_and; +struct logical_or; + +template< class A1, class A2 > class list2: private storage2< A1, A2 > +{ +private: + + typedef storage2< A1, A2 > base_type; + +public: + + list2( A1 a1, A2 a2 ): base_type( a1, a2 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template bool operator()( type, logical_and & /*f*/, A & a, int ) + { + return a[ base_type::a1_ ] && a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_and const & /*f*/, A & a, int ) const + { + return a[ base_type::a1_ ] && a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_or & /*f*/, A & a, int ) + { + return a[ base_type::a1_ ] || a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_or const & /*f*/, A & a, int ) const + { + return a[ base_type::a1_ ] || a[ base_type::a2_ ]; + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list2 const & rhs) const + { + return ref_compare(base_type::a1_, rhs.a1_, 0) && ref_compare(base_type::a2_, rhs.a2_, 0); + } +}; + +template< class A1, class A2, class A3 > class list3: private storage3< A1, A2, A3 > +{ +private: + + typedef storage3< A1, A2, A3 > base_type; + +public: + + list3( A1 a1, A2 a2, A3 a3 ): base_type( a1, a2, a3 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list3 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4 > class list4: private storage4< A1, A2, A3, A4 > +{ +private: + + typedef storage4< A1, A2, A3, A4 > base_type; + +public: + + list4( A1 a1, A2 a2, A3 a3, A4 a4 ): base_type( a1, a2, a3, a4 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list4 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5 > class list5: private storage5< A1, A2, A3, A4, A5 > +{ +private: + + typedef storage5< A1, A2, A3, A4, A5 > base_type; + +public: + + list5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): base_type( a1, a2, a3, a4, a5 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list5 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ); + } +}; + +template class list6: private storage6< A1, A2, A3, A4, A5, A6 > +{ +private: + + typedef storage6< A1, A2, A3, A4, A5, A6 > base_type; + +public: + + list6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): base_type( a1, a2, a3, a4, a5, a6 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list6 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ); + } +}; + +template class list7: private storage7< A1, A2, A3, A4, A5, A6, A7 > +{ +private: + + typedef storage7< A1, A2, A3, A4, A5, A6, A7 > base_type; + +public: + + list7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): base_type( a1, a2, a3, a4, a5, a6, a7 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list7 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class list8: private storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ +private: + + typedef storage8< A1, A2, A3, A4, A5, A6, A7, A8 > base_type; + +public: + + list8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + A8 operator[] (boost::arg<8>) const { return base_type::a8_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list8 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ) && + ref_compare( base_type::a8_, rhs.a8_, 0 ); + } +}; + +template class list9: private storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > +{ +private: + + typedef storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > base_type; + +public: + + list9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8, a9 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + A8 operator[] (boost::arg<8>) const { return base_type::a8_; } + A9 operator[] (boost::arg<9>) const { return base_type::a9_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; } + A9 operator[] (boost::arg<9> (*) ()) const { return base_type::a9_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list9 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ) && + ref_compare( base_type::a8_, rhs.a8_, 0 ) && + ref_compare( base_type::a9_, rhs.a9_, 0 ); + } +}; + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// bind_t + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template< class A1 > class rrlist1 +{ +private: + + A1 & a1_; // not A1&& because of msvc-10.0 + +public: + + explicit rrlist1( A1 & a1 ): a1_( a1 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } // not static_cast because of g++ 4.9 + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist1 a( a1_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist1 a( a1_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2 > class rrlist2 +{ +private: + + A1 & a1_; + A2 & a2_; + +public: + + rrlist2( A1 & a1, A2 & a2 ): a1_( a1 ), a2_( a2 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist2 a( a1_, a2_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist2 a( a1_, a2_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3 > class rrlist3 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + +public: + + rrlist3( A1 & a1, A2 & a2, A3 & a3 ): a1_( a1 ), a2_( a2 ), a3_( a3 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist3 a( a1_, a2_, a3_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist3 a( a1_, a2_, a3_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4 > class rrlist4 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + +public: + + rrlist4( A1 & a1, A2 & a2, A3 & a3, A4 & a4 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist4 a( a1_, a2_, a3_, a4_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist4 a( a1_, a2_, a3_, a4_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5 > class rrlist5 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + +public: + + rrlist5( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist5 a( a1_, a2_, a3_, a4_, a5_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist5 a( a1_, a2_, a3_, a4_, a5_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6 > class rrlist6 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + +public: + + rrlist6( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist6 a( a1_, a2_, a3_, a4_, a5_, a6_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist6 a( a1_, a2_, a3_, a4_, a5_, a6_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7 > class rrlist7 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + +public: + + rrlist7( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist7 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist7 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class rrlist8 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + A8 & a8_; + +public: + + rrlist8( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8>) const { return std::forward( a8_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward( a8_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist8 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist8 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > class rrlist9 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + A8 & a8_; + A9 & a9_; + +public: + + rrlist9( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ), a9_( a9 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8>) const { return std::forward( a8_ ); } + A9 && operator[] (boost::arg<9>) const { return std::forward( a9_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward( a8_ ); } + A9 && operator[] (boost::arg<9> (*) ()) const { return std::forward( a9_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist9 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist9 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_ ); + return b.eval( a ); + } +}; + +template class bind_t +{ +private: + + F f_; + L l_; + +public: + + typedef typename result_traits::type result_type; + typedef bind_t this_type; + + bind_t( F f, L const & l ): f_( f ), l_( l ) {} + + // + + result_type operator()() + { + list0 a; + return l_( type(), f_, a, 0 ); + } + + result_type operator()() const + { + list0 a; + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1 ) + { + rrlist1< A1 > a( a1 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1 ) const + { + rrlist1< A1 > a( a1 ); + return l_(type(), f_, a, 0); + } + + template result_type operator()( A1 && a1, A2 && a2 ) + { + rrlist2< A1, A2 > a( a1, a2 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2 ) const + { + rrlist2< A1, A2 > a( a1, a2 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3 ) + { + rrlist3< A1, A2, A3 > a( a1, a2, a3 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3 ) const + { + rrlist3< A1, A2, A3 > a( a1, a2, a3 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) + { + rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) const + { + rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) + { + rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) const + { + rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) + { + rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) const + { + rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) + { + rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) const + { + rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) + { + rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) const + { + rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) + { + rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) const + { + rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + return l_( type(), f_, a, 0 ); + } + + // + + template result_type eval( A & a ) + { + return l_( type(), f_, a, 0 ); + } + + template result_type eval( A & a ) const + { + return l_( type(), f_, a, 0 ); + } + + template void accept( V & v ) const + { +#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ ) + using boost::visit_each; +#endif + + BOOST_BIND_VISIT_EACH( v, f_, 0 ); + l_.accept( v ); + } + + bool compare( this_type const & rhs ) const + { + return ref_compare( f_, rhs.f_, 0 ) && l_ == rhs.l_; + } +}; + +#elif !defined( BOOST_NO_VOID_RETURNS ) + +template class bind_t +{ +public: + + typedef bind_t this_type; + + bind_t(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN return +#include +#undef BOOST_BIND_RETURN + +}; + +#else // no void returns + +template struct bind_t_generator +{ + +template class implementation +{ +public: + + typedef implementation this_type; + + implementation(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN return +#include +#undef BOOST_BIND_RETURN + +}; + +}; + +template<> struct bind_t_generator +{ + +template class implementation +{ +private: + + typedef void R; + +public: + + typedef implementation this_type; + + implementation(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN +#include +#undef BOOST_BIND_RETURN + +}; + +}; + +template class bind_t: public bind_t_generator::BOOST_NESTED_TEMPLATE implementation +{ +public: + + bind_t(F f, L const & l): bind_t_generator::BOOST_NESTED_TEMPLATE implementation(f, l) {} + +}; + +#endif + +// function_equal + +#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// put overloads in _bi, rely on ADL + +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template bool function_equal( bind_t const & a, bind_t const & b ) +{ + return a.compare(b); +} + +# else + +template bool function_equal_impl( bind_t const & a, bind_t const & b, int ) +{ + return a.compare(b); +} + +# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +#else // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// put overloads in boost + +} // namespace _bi + +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template bool function_equal( _bi::bind_t const & a, _bi::bind_t const & b ) +{ + return a.compare(b); +} + +# else + +template bool function_equal_impl( _bi::bind_t const & a, _bi::bind_t const & b, int ) +{ + return a.compare(b); +} + +# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +namespace _bi +{ + +#endif // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// add_value + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || (__SUNPRO_CC >= 0x530) + +#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x582) ) + +template struct add_value +{ + typedef _bi::value type; +}; + +#else + +template< class T, int I > struct add_value_2 +{ + typedef boost::arg type; +}; + +template< class T > struct add_value_2< T, 0 > +{ + typedef _bi::value< T > type; +}; + +template struct add_value +{ + typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type; +}; + +#endif + +template struct add_value< value > +{ + typedef _bi::value type; +}; + +template struct add_value< reference_wrapper > +{ + typedef reference_wrapper type; +}; + +template struct add_value< arg > +{ + typedef boost::arg type; +}; + +template struct add_value< arg (*) () > +{ + typedef boost::arg (*type) (); +}; + +template struct add_value< bind_t > +{ + typedef bind_t type; +}; + +#else + +template struct _avt_0; + +template<> struct _avt_0<1> +{ + template struct inner + { + typedef T type; + }; +}; + +template<> struct _avt_0<2> +{ + template struct inner + { + typedef value type; + }; +}; + +typedef char (&_avt_r1) [1]; +typedef char (&_avt_r2) [2]; + +template _avt_r1 _avt_f(value); +template _avt_r1 _avt_f(reference_wrapper); +template _avt_r1 _avt_f(arg); +template _avt_r1 _avt_f(arg (*) ()); +template _avt_r1 _avt_f(bind_t); + +_avt_r2 _avt_f(...); + +template struct add_value +{ + static T t(); + typedef typename _avt_0::template inner::type type; +}; + +#endif + +// list_av_N + +template struct list_av_1 +{ + typedef typename add_value::type B1; + typedef list1 type; +}; + +template struct list_av_2 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef list2 type; +}; + +template struct list_av_3 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef list3 type; +}; + +template struct list_av_4 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef list4 type; +}; + +template struct list_av_5 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef list5 type; +}; + +template struct list_av_6 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef list6 type; +}; + +template struct list_av_7 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef list7 type; +}; + +template struct list_av_8 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef typename add_value::type B8; + typedef list8 type; +}; + +template struct list_av_9 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef typename add_value::type B8; + typedef typename add_value::type B9; + typedef list9 type; +}; + +// operator! + +struct logical_not +{ + template bool operator()(V const & v) const { return !v; } +}; + +template + bind_t< bool, logical_not, list1< bind_t > > + operator! (bind_t const & f) +{ + typedef list1< bind_t > list_type; + return bind_t ( logical_not(), list_type(f) ); +} + +// relational operators + +#define BOOST_BIND_OPERATOR( op, name ) \ +\ +struct name \ +{ \ + template bool operator()(V const & v, W const & w) const { return v op w; } \ +}; \ + \ +template \ + bind_t< bool, name, list2< bind_t, typename add_value::type > > \ + operator op (bind_t const & f, A2 a2) \ +{ \ + typedef typename add_value::type B2; \ + typedef list2< bind_t, B2> list_type; \ + return bind_t ( name(), list_type(f, a2) ); \ +} + +BOOST_BIND_OPERATOR( ==, equal ) +BOOST_BIND_OPERATOR( !=, not_equal ) + +BOOST_BIND_OPERATOR( <, less ) +BOOST_BIND_OPERATOR( <=, less_equal ) + +BOOST_BIND_OPERATOR( >, greater ) +BOOST_BIND_OPERATOR( >=, greater_equal ) + +BOOST_BIND_OPERATOR( &&, logical_and ) +BOOST_BIND_OPERATOR( ||, logical_or ) + +#undef BOOST_BIND_OPERATOR + +#if defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) + +// resolve ambiguity with rel_ops + +#define BOOST_BIND_OPERATOR( op, name ) \ +\ +template \ + bind_t< bool, name, list2< bind_t, bind_t > > \ + operator op (bind_t const & f, bind_t const & g) \ +{ \ + typedef list2< bind_t, bind_t > list_type; \ + return bind_t ( name(), list_type(f, g) ); \ +} + +BOOST_BIND_OPERATOR( !=, not_equal ) +BOOST_BIND_OPERATOR( <=, less_equal ) +BOOST_BIND_OPERATOR( >, greater ) +BOOST_BIND_OPERATOR( >=, greater_equal ) + +#endif + +// visit_each, ADL + +#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ ) \ + && !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + +template void visit_each( V & v, value const & t, int ) +{ + using boost::visit_each; + BOOST_BIND_VISIT_EACH( v, t.get(), 0 ); +} + +template void visit_each( V & v, bind_t const & t, int ) +{ + t.accept( v ); +} + +#endif + +} // namespace _bi + +// visit_each, no ADL + +#if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) || defined( __BORLANDC__ ) \ + || (defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + +template void visit_each( V & v, _bi::value const & t, int ) +{ + BOOST_BIND_VISIT_EACH( v, t.get(), 0 ); +} + +template void visit_each( V & v, _bi::bind_t const & t, int ) +{ + t.accept( v ); +} + +#endif + +// is_bind_expression + +template< class T > struct is_bind_expression +{ + enum _vt { value = 0 }; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class R, class F, class L > struct is_bind_expression< _bi::bind_t< R, F, L > > +{ + enum _vt { value = 1 }; +}; + +#endif + +// bind + +#ifndef BOOST_BIND +#define BOOST_BIND bind +#endif + +// generic function objects + +template + _bi::bind_t + BOOST_BIND(F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +// generic function objects, alternative syntax + +template + _bi::bind_t + BOOST_BIND(boost::type, F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +// adaptable function objects + +template + _bi::bind_t<_bi::unspecified, F, _bi::list0> + BOOST_BIND(F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type()); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_1::type> + BOOST_BIND(F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_2::type> + BOOST_BIND(F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1, a2)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_3::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_4::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_5::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_6::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_7::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_8::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_9::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +#endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +// function pointers + +#define BOOST_BIND_CC +#define BOOST_BIND_ST +#define BOOST_BIND_NOEXCEPT + +#include + +# if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) +# undef BOOST_BIND_NOEXCEPT +# define BOOST_BIND_NOEXCEPT noexcept +# include +# endif + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST +#undef BOOST_BIND_NOEXCEPT + +#ifdef BOOST_BIND_ENABLE_STDCALL + +#define BOOST_BIND_CC __stdcall +#define BOOST_BIND_ST +#define BOOST_BIND_NOEXCEPT + +#include + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST +#undef BOOST_BIND_NOEXCEPT + +#endif + +#ifdef BOOST_BIND_ENABLE_FASTCALL + +#define BOOST_BIND_CC __fastcall +#define BOOST_BIND_ST +#define BOOST_BIND_NOEXCEPT + +#include + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST +#undef BOOST_BIND_NOEXCEPT + +#endif + +#ifdef BOOST_BIND_ENABLE_PASCAL + +#define BOOST_BIND_ST pascal +#define BOOST_BIND_CC +#define BOOST_BIND_NOEXCEPT + +#include + +#undef BOOST_BIND_ST +#undef BOOST_BIND_CC +#undef BOOST_BIND_NOEXCEPT + +#endif + +// member function pointers + +#define BOOST_BIND_MF_NAME(X) X +#define BOOST_BIND_MF_CC +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +# if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) +# undef BOOST_BIND_MF_NOEXCEPT +# define BOOST_BIND_MF_NOEXCEPT noexcept +# include +# endif + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#ifdef BOOST_MEM_FN_ENABLE_CDECL + +#define BOOST_BIND_MF_NAME(X) X##_cdecl +#define BOOST_BIND_MF_CC __cdecl +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_BIND_MF_NAME(X) X##_stdcall +#define BOOST_BIND_MF_CC __stdcall +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_BIND_MF_NAME(X) X##_fastcall +#define BOOST_BIND_MF_CC __fastcall +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#endif + +// data member pointers + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + || ( defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x620 ) ) ) + +template +_bi::bind_t< R, _mfi::dm, typename _bi::list_av_1::type > + BOOST_BIND(R T::*f, A1 a1) +{ + typedef _mfi::dm F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t( F(f), list_type(a1) ); +} + +#else + +namespace _bi +{ + +template< class Pm, int I > struct add_cref; + +template< class M, class T > struct add_cref< M T::*, 0 > +{ + typedef M type; +}; + +template< class M, class T > struct add_cref< M T::*, 1 > +{ +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4180) +#endif + typedef M const & type; +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +}; + +template< class R, class T > struct add_cref< R (T::*) (), 1 > +{ + typedef void type; +}; + +#if !defined(__IBMCPP__) || __IBMCPP_FUNC_CV_TMPL_ARG_DEDUCTION + +template< class R, class T > struct add_cref< R (T::*) () const, 1 > +{ + typedef void type; +}; + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + +template< class R, class T > struct add_cref< R (T::*) () const noexcept, 1 > +{ + typedef void type; +}; + +#endif // __cpp_noexcept_function_type + +#endif // __IBMCPP__ + +template struct isref +{ + enum value_type { value = 0 }; +}; + +template struct isref< R& > +{ + enum value_type { value = 1 }; +}; + +template struct isref< R* > +{ + enum value_type { value = 1 }; +}; + +template struct dm_result +{ + typedef typename add_cref< Pm, 1 >::type type; +}; + +template struct dm_result< Pm, bind_t > +{ + typedef typename bind_t::result_type result_type; + typedef typename add_cref< Pm, isref< result_type >::value >::type type; +}; + +} // namespace _bi + +template< class A1, class M, class T > + +_bi::bind_t< + typename _bi::dm_result< M T::*, A1 >::type, + _mfi::dm, + typename _bi::list_av_1::type +> + +BOOST_BIND( M T::*f, A1 a1 ) +{ + typedef typename _bi::dm_result< M T::*, A1 >::type result_type; + typedef _mfi::dm F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t< result_type, F, list_type >( F( f ), list_type( a1 ) ); +} + +#endif + +} // namespace boost + +#ifndef BOOST_BIND_NO_PLACEHOLDERS + +# include + +#endif + +#ifdef BOOST_MSVC +# pragma warning(default: 4512) // assignment operator could not be generated +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_BIND_BIND_HPP_INCLUDED diff --git a/boost/bind/bind_cc.hpp b/boost/bind/bind_cc.hpp new file mode 100644 index 00000000..278aa9a2 --- /dev/null +++ b/boost/bind/bind_cc.hpp @@ -0,0 +1,117 @@ +// +// bind/bind_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// 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/bind/bind.html for documentation. +// + +template + _bi::bind_t + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) () BOOST_BIND_NOEXCEPT) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) () BOOST_BIND_NOEXCEPT; + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1) BOOST_BIND_NOEXCEPT, A1 a1) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8, B9) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8, B9) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/boost/bind/bind_mf2_cc.hpp b/boost/bind/bind_mf2_cc.hpp new file mode 100644 index 00000000..66476bc1 --- /dev/null +++ b/boost/bind/bind_mf2_cc.hpp @@ -0,0 +1,228 @@ +// +// bind/bind_mf2_cc.hpp - member functions, type<> syntax +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2008 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 +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +// 0 + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (), A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) () const, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +// 1 + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +// 2 + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +// 3 + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +// 4 + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +// 5 + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +// 6 + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +// 7 + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +// 8 + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/boost/bind/bind_mf_cc.hpp b/boost/bind/bind_mf_cc.hpp new file mode 100644 index 00000000..bbfd3719 --- /dev/null +++ b/boost/bind/bind_mf_cc.hpp @@ -0,0 +1,441 @@ +// +// bind/bind_mf_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// 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/bind/bind.html for documentation. +// + +// 0 + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_1::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_1::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +// 1 + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_2::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_2::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +// 2 + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_3::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_3::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +// 3 + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_4::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_4::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +// 4 + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_5::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_5::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +// 5 + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_6::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_6::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +// 6 + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_7::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_7::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +// 7 + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_8::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_8::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +// 8 + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_9::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_9::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/boost/bind/bind_template.hpp b/boost/bind/bind_template.hpp new file mode 100644 index 00000000..411d20c7 --- /dev/null +++ b/boost/bind/bind_template.hpp @@ -0,0 +1,345 @@ +// +// bind/bind_template.hpp +// +// Do not include this header directly. +// +// Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd. +// +// 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/bind/bind.html for documentation. +// + + typedef typename result_traits::type result_type; + + result_type operator()() + { + list0 a; + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + result_type operator()() const + { + list0 a; + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1) + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1) const + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1) + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1) const + { + list1 a(a1); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + + template result_type operator()(A1 & a1, A2 const & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 const & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + + template result_type operator()(A1 const & a1, A2 const & a2) + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2) const + { + list2 a(a1, a2); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3) + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3) const + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) const + { + list3 a(a1, a2, a3); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) const + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) const + { + list4 a(a1, a2, a3, a4); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) const + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) const + { + list5 a(a1, a2, a3, a4, a5); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) const + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) const + { + list6 a(a1, a2, a3, a4, a5, a6); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) const + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) const + { + list7 a(a1, a2, a3, a4, a5, a6, a7); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) const + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) const + { + list8 a(a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) const + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) const + { + list9 a(a1, a2, a3, a4, a5, a6, a7, a8, a9); + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + +#endif + + template result_type eval(A & a) + { + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template result_type eval(A & a) const + { + BOOST_BIND_RETURN l_(type(), f_, a, 0); + } + + template void accept(V & v) const + { +#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ ) + + using boost::visit_each; + +#endif + BOOST_BIND_VISIT_EACH(v, f_, 0); + l_.accept(v); + } + + bool compare(this_type const & rhs) const + { + return ref_compare(f_, rhs.f_, 0) && l_ == rhs.l_; + } + +private: + + F f_; + L l_; diff --git a/boost/bind/mem_fn.hpp b/boost/bind/mem_fn.hpp new file mode 100644 index 00000000..956e7d88 --- /dev/null +++ b/boost/bind/mem_fn.hpp @@ -0,0 +1,389 @@ +#ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED +#define BOOST_BIND_MEM_FN_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// mem_fn.hpp - a generalization of std::mem_fun[_ref] +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2001 David Abrahams +// Copyright (c) 2003-2005 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) +// +// See http://www.boost.org/libs/bind/mem_fn.html for documentation. +// + +#include +#include +#include + +namespace boost +{ + +#if defined(BOOST_NO_VOID_RETURNS) + +#define BOOST_MEM_FN_CLASS_F , class F +#define BOOST_MEM_FN_TYPEDEF(X) + +namespace _mfi // mem_fun_impl +{ + +template struct mf +{ + +#define BOOST_MEM_FN_RETURN return + +#define BOOST_MEM_FN_NAME(X) inner_##X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#ifdef BOOST_MEM_FN_ENABLE_CDECL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#undef BOOST_MEM_FN_RETURN + +}; // struct mf + +template<> struct mf +{ + +#define BOOST_MEM_FN_RETURN + +#define BOOST_MEM_FN_NAME(X) inner_##X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#ifdef BOOST_MEM_FN_ENABLE_CDECL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#undef BOOST_MEM_FN_RETURN + +}; // struct mf + +#undef BOOST_MEM_FN_CLASS_F +#undef BOOST_MEM_FN_TYPEDEF_F + +#define BOOST_MEM_FN_NAME(X) X +#define BOOST_MEM_FN_NAME2(X) inner_##X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#ifdef BOOST_MEM_FN_ENABLE_CDECL + +#define BOOST_MEM_FN_NAME(X) X##_cdecl +#define BOOST_MEM_FN_NAME2(X) inner_##X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_MEM_FN_NAME(X) X##_stdcall +#define BOOST_MEM_FN_NAME2(X) inner_##X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_MEM_FN_NAME(X) X##_fastcall +#define BOOST_MEM_FN_NAME2(X) inner_##X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#endif + +} // namespace _mfi + +#else // #ifdef BOOST_NO_VOID_RETURNS + +#define BOOST_MEM_FN_CLASS_F +#define BOOST_MEM_FN_TYPEDEF(X) typedef X; + +namespace _mfi +{ + +#define BOOST_MEM_FN_RETURN return + +#define BOOST_MEM_FN_NAME(X) X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#ifdef BOOST_MEM_FN_ENABLE_CDECL + +#define BOOST_MEM_FN_NAME(X) X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_MEM_FN_NAME(X) X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_MEM_FN_NAME(X) X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#undef BOOST_MEM_FN_RETURN + +} // namespace _mfi + +#undef BOOST_MEM_FN_CLASS_F +#undef BOOST_MEM_FN_TYPEDEF + +#endif // #ifdef BOOST_NO_VOID_RETURNS + +#define BOOST_MEM_FN_NAME(X) X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC + +#ifdef BOOST_MEM_FN_ENABLE_CDECL + +#define BOOST_MEM_FN_NAME(X) X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_MEM_FN_NAME(X) X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_MEM_FN_NAME(X) X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC + +#endif + +// data member support + +namespace _mfi +{ + +template class dm +{ +public: + + typedef R const & result_type; + typedef T const * argument_type; + +private: + + typedef R (T::*F); + F f_; + + template R const & call(U & u, T const *) const + { + return (u.*f_); + } + + template R const & call(U & u, void const *) const + { + return (get_pointer(u)->*f_); + } + +public: + + explicit dm(F f): f_(f) {} + + R & operator()(T * p) const + { + return (p->*f_); + } + + R const & operator()(T const * p) const + { + return (p->*f_); + } + + template R const & operator()(U const & u) const + { + return call(u, &u); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__MWERKS__, < 0x3200) + + R & operator()(T & t) const + { + return (t.*f_); + } + + R const & operator()(T const & t) const + { + return (t.*f_); + } + +#endif + + bool operator==(dm const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(dm const & rhs) const + { + return f_ != rhs.f_; + } +}; + +} // namespace _mfi + +template _mfi::dm mem_fn(R T::*f) +{ + return _mfi::dm(f); +} + +} // namespace boost + +#endif // #ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED diff --git a/boost/bind/mem_fn_cc.hpp b/boost/bind/mem_fn_cc.hpp new file mode 100644 index 00000000..8b6ea0ba --- /dev/null +++ b/boost/bind/mem_fn_cc.hpp @@ -0,0 +1,103 @@ +// +// bind/mem_fn_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// 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/bind/mem_fn.html for documentation. +// + +template _mfi::BOOST_MEM_FN_NAME(mf0) mem_fn(R (BOOST_MEM_FN_CC T::*f) ()) +{ + return _mfi::BOOST_MEM_FN_NAME(mf0)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf0) mem_fn(R (BOOST_MEM_FN_CC T::*f) () const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf0)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf1) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf1)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf1) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf1)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf2) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf2)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf2) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf2)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf3) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf3)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf3) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf3)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf4) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf4)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf4) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf4)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf5) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf5)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf5) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf5)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf6) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf6)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf6) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf6)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf7) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf7)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf7) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf7)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf8) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8)) +{ + return _mfi::BOOST_MEM_FN_NAME(mf8)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf8) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8) const) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf8)(f); +} diff --git a/boost/bind/mem_fn_template.hpp b/boost/bind/mem_fn_template.hpp new file mode 100644 index 00000000..b26d585d --- /dev/null +++ b/boost/bind/mem_fn_template.hpp @@ -0,0 +1,1047 @@ +// +// bind/mem_fn_template.hpp +// +// Do not include this header directly +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// 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/bind/mem_fn.html for documentation. +// + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +# define BOOST_MEM_FN_ENABLE_CONST_OVERLOADS +#endif + +// mf0 + +template class BOOST_MEM_FN_NAME(mf0) +{ +public: + + typedef R result_type; + typedef T * argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) ()) + F f_; + + template R call(U & u, T const *) const + { + BOOST_MEM_FN_RETURN (u.*f_)(); + } + + template R call(U & u, void const *) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf0)(F f): f_(f) {} + + R operator()(T * p) const + { + BOOST_MEM_FN_RETURN (p->*f_)(); + } + + template R operator()(U & u) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p); + } + +#endif + + R operator()(T & t) const + { + BOOST_MEM_FN_RETURN (t.*f_)(); + } + + bool operator==(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf0 + +template class BOOST_MEM_FN_NAME(cmf0) +{ +public: + + typedef R result_type; + typedef T const * argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) () const) + F f_; + + template R call(U & u, T const *) const + { + BOOST_MEM_FN_RETURN (u.*f_)(); + } + + template R call(U & u, void const *) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf0)(F f): f_(f) {} + + template R operator()(U const & u) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p); + } + + R operator()(T const & t) const + { + BOOST_MEM_FN_RETURN (t.*f_)(); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf1 + +template class BOOST_MEM_FN_NAME(mf1) +{ +public: + + typedef R result_type; + typedef T * first_argument_type; + typedef A1 second_argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1)) + F f_; + + template R call(U & u, T const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1); + } + + template R call(U & u, void const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf1)(F f): f_(f) {} + + R operator()(T * p, A1 a1) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1); + } + + template R operator()(U & u, A1 a1) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1); + } + +#endif + + R operator()(T & t, A1 a1) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1); + } + + bool operator==(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf1 + +template class BOOST_MEM_FN_NAME(cmf1) +{ +public: + + typedef R result_type; + typedef T const * first_argument_type; + typedef A1 second_argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1) const) + F f_; + + template R call(U & u, T const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1); + } + + template R call(U & u, void const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf1)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1); + } + + R operator()(T const & t, A1 a1) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf2 + +template class BOOST_MEM_FN_NAME(mf2) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf2)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2); + } + + template R operator()(U & u, A1 a1, A2 a2) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); + } + + bool operator==(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf2 + +template class BOOST_MEM_FN_NAME(cmf2) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf2)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2); + } + + R operator()(T const & t, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf3 + +template class BOOST_MEM_FN_NAME(mf3) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf3)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); + } + + bool operator==(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf3 + +template class BOOST_MEM_FN_NAME(cmf3) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf3)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf4 + +template class BOOST_MEM_FN_NAME(mf4) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf4)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); + } + + bool operator==(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf4 + +template class BOOST_MEM_FN_NAME(cmf4) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf4)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf5 + +template class BOOST_MEM_FN_NAME(mf5) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf5)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); + } + + bool operator==(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf5 + +template class BOOST_MEM_FN_NAME(cmf5) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf5)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf6 + +template class BOOST_MEM_FN_NAME(mf6) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf6)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); + } + + bool operator==(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf6 + +template class BOOST_MEM_FN_NAME(cmf6) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf6)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf7 + +template class BOOST_MEM_FN_NAME(mf7) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf7)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + bool operator==(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf7 + +template class BOOST_MEM_FN_NAME(cmf7) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf7)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf8 + +template class BOOST_MEM_FN_NAME(mf8) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf8)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + bool operator==(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf8 + +template class BOOST_MEM_FN_NAME(cmf8) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf8)(F f): f_(f) {} + + R operator()(T const * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +#undef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS diff --git a/boost/bind/mem_fn_vw.hpp b/boost/bind/mem_fn_vw.hpp new file mode 100644 index 00000000..f3fc58db --- /dev/null +++ b/boost/bind/mem_fn_vw.hpp @@ -0,0 +1,130 @@ +// +// bind/mem_fn_vw.hpp - void return helper wrappers +// +// Do not include this header directly +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// 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/bind/mem_fn.html for documentation. +// + +template struct BOOST_MEM_FN_NAME(mf0): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf0) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (); + explicit BOOST_MEM_FN_NAME(mf0)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf0)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf0): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf0) +{ + typedef R (BOOST_MEM_FN_CC T::*F) () const; + explicit BOOST_MEM_FN_NAME(cmf0)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf0)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf1): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf1) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1); + explicit BOOST_MEM_FN_NAME(mf1)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf1)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf1): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf1) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1) const; + explicit BOOST_MEM_FN_NAME(cmf1)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf1)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf2): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf2) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2); + explicit BOOST_MEM_FN_NAME(mf2)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf2)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf2): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf2) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2) const; + explicit BOOST_MEM_FN_NAME(cmf2)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf2)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf3): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf3) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3); + explicit BOOST_MEM_FN_NAME(mf3)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf3)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf3): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf3) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3) const; + explicit BOOST_MEM_FN_NAME(cmf3)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf3)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf4): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf4) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4); + explicit BOOST_MEM_FN_NAME(mf4)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf4)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf4): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf4) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4) const; + explicit BOOST_MEM_FN_NAME(cmf4)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf4)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf5): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf5) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5); + explicit BOOST_MEM_FN_NAME(mf5)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf5)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf5): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf5) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5) const; + explicit BOOST_MEM_FN_NAME(cmf5)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf5)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf6): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf6) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6); + explicit BOOST_MEM_FN_NAME(mf6)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf6)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf6): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf6) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6) const; + explicit BOOST_MEM_FN_NAME(cmf6)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf6)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf7): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf7) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7); + explicit BOOST_MEM_FN_NAME(mf7)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf7)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf7): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf7) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7) const; + explicit BOOST_MEM_FN_NAME(cmf7)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf7)(f) {} +}; + + +template struct BOOST_MEM_FN_NAME(mf8): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf8) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8); + explicit BOOST_MEM_FN_NAME(mf8)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(mf8)(f) {} +}; + +template struct BOOST_MEM_FN_NAME(cmf8): public mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf8) +{ + typedef R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8) const; + explicit BOOST_MEM_FN_NAME(cmf8)(F f): mf::BOOST_NESTED_TEMPLATE BOOST_MEM_FN_NAME2(cmf8)(f) {} +}; + diff --git a/boost/bind/placeholders.hpp b/boost/bind/placeholders.hpp new file mode 100644 index 00000000..b819ef4c --- /dev/null +++ b/boost/bind/placeholders.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED +#define BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/placeholders.hpp - _N definitions +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// 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 +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +namespace boost +{ + +namespace placeholders +{ + +#if defined(__BORLANDC__) || defined(__GNUC__) && (__GNUC__ < 4) + +inline boost::arg<1> _1() { return boost::arg<1>(); } +inline boost::arg<2> _2() { return boost::arg<2>(); } +inline boost::arg<3> _3() { return boost::arg<3>(); } +inline boost::arg<4> _4() { return boost::arg<4>(); } +inline boost::arg<5> _5() { return boost::arg<5>(); } +inline boost::arg<6> _6() { return boost::arg<6>(); } +inline boost::arg<7> _7() { return boost::arg<7>(); } +inline boost::arg<8> _8() { return boost::arg<8>(); } +inline boost::arg<9> _9() { return boost::arg<9>(); } + +#else + +BOOST_STATIC_CONSTEXPR boost::arg<1> _1; +BOOST_STATIC_CONSTEXPR boost::arg<2> _2; +BOOST_STATIC_CONSTEXPR boost::arg<3> _3; +BOOST_STATIC_CONSTEXPR boost::arg<4> _4; +BOOST_STATIC_CONSTEXPR boost::arg<5> _5; +BOOST_STATIC_CONSTEXPR boost::arg<6> _6; +BOOST_STATIC_CONSTEXPR boost::arg<7> _7; +BOOST_STATIC_CONSTEXPR boost::arg<8> _8; +BOOST_STATIC_CONSTEXPR boost::arg<9> _9; + +#endif + +} // namespace placeholders + +} // namespace boost + +#endif // #ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED diff --git a/boost/bind/storage.hpp b/boost/bind/storage.hpp new file mode 100644 index 00000000..be490b0f --- /dev/null +++ b/boost/bind/storage.hpp @@ -0,0 +1,475 @@ +#ifndef BOOST_BIND_STORAGE_HPP_INCLUDED +#define BOOST_BIND_STORAGE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/storage.hpp +// +// boost/bind.hpp support header, optimized storage +// +// Copyright (c) 2006 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 +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace boost +{ + +namespace _bi +{ + +// 1 + +template struct storage1 +{ + explicit storage1( A1 a1 ): a1_( a1 ) {} + + template void accept(V & v) const + { + BOOST_BIND_VISIT_EACH(v, a1_, 0); + } + + A1 a1_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( __BORLANDC__ ) + +template struct storage1< boost::arg > +{ + explicit storage1( boost::arg ) {} + + template void accept(V &) const { } + + static boost::arg a1_() { return boost::arg(); } +}; + +template struct storage1< boost::arg (*) () > +{ + explicit storage1( boost::arg (*) () ) {} + + template void accept(V &) const { } + + static boost::arg a1_() { return boost::arg(); } +}; + +#endif + +// 2 + +template struct storage2: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, A2 a2 ): storage1( a1 ), a2_( a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a2_, 0); + } + + A2 a2_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage2< A1, boost::arg >: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, boost::arg ): storage1( a1 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a2_() { return boost::arg(); } +}; + +template struct storage2< A1, boost::arg (*) () >: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, boost::arg (*) () ): storage1( a1 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a2_() { return boost::arg(); } +}; + +#endif + +// 3 + +template struct storage3: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, A3 a3 ): storage2( a1, a2 ), a3_( a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a3_, 0); + } + + A3 a3_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage3< A1, A2, boost::arg >: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, boost::arg ): storage2( a1, a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a3_() { return boost::arg(); } +}; + +template struct storage3< A1, A2, boost::arg (*) () >: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, boost::arg (*) () ): storage2( a1, a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a3_() { return boost::arg(); } +}; + +#endif + +// 4 + +template struct storage4: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, A4 a4 ): storage3( a1, a2, a3 ), a4_( a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a4_, 0); + } + + A4 a4_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage4< A1, A2, A3, boost::arg >: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, boost::arg ): storage3( a1, a2, a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a4_() { return boost::arg(); } +}; + +template struct storage4< A1, A2, A3, boost::arg (*) () >: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, boost::arg (*) () ): storage3( a1, a2, a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a4_() { return boost::arg(); } +}; + +#endif + +// 5 + +template struct storage5: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): storage4( a1, a2, a3, a4 ), a5_( a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a5_, 0); + } + + A5 a5_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage5< A1, A2, A3, A4, boost::arg >: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg ): storage4( a1, a2, a3, a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a5_() { return boost::arg(); } +}; + +template struct storage5< A1, A2, A3, A4, boost::arg (*) () >: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg (*) () ): storage4( a1, a2, a3, a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a5_() { return boost::arg(); } +}; + +#endif + +// 6 + +template struct storage6: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): storage5( a1, a2, a3, a4, a5 ), a6_( a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a6_, 0); + } + + A6 a6_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage6< A1, A2, A3, A4, A5, boost::arg >: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg ): storage5( a1, a2, a3, a4, a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a6_() { return boost::arg(); } +}; + +template struct storage6< A1, A2, A3, A4, A5, boost::arg (*) () >: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg (*) () ): storage5( a1, a2, a3, a4, a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a6_() { return boost::arg(); } +}; + +#endif + +// 7 + +template struct storage7: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): storage6( a1, a2, a3, a4, a5, a6 ), a7_( a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a7_, 0); + } + + A7 a7_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage7< A1, A2, A3, A4, A5, A6, boost::arg >: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg ): storage6( a1, a2, a3, a4, a5, a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a7_() { return boost::arg(); } +}; + +template struct storage7< A1, A2, A3, A4, A5, A6, boost::arg (*) () >: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg (*) () ): storage6( a1, a2, a3, a4, a5, a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a7_() { return boost::arg(); } +}; + +#endif + +// 8 + +template struct storage8: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): storage7( a1, a2, a3, a4, a5, a6, a7 ), a8_( a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a8_, 0); + } + + A8 a8_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg >: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg ): storage7( a1, a2, a3, a4, a5, a6, a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a8_() { return boost::arg(); } +}; + +template struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg (*) () >: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg (*) () ): storage7( a1, a2, a3, a4, a5, a6, a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a8_() { return boost::arg(); } +}; + +#endif + +// 9 + +template struct storage9: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ), a9_( a9 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a9_, 0); + } + + A9 a9_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a9_() { return boost::arg(); } +}; + +template struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg (*) () >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg (*) () ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a9_() { return boost::arg(); } +}; + +#endif + +} // namespace _bi + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(default: 4512) // assignment operator could not be generated +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_BIND_STORAGE_HPP_INCLUDED diff --git a/boost/call_traits.hpp b/boost/call_traits.hpp new file mode 100644 index 00000000..2c1328e9 --- /dev/null +++ b/boost/call_traits.hpp @@ -0,0 +1,20 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & 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/utility for most recent version including documentation. + +// See boost/detail/call_traits.hpp +// for full copyright notices. + +#ifndef BOOST_CALL_TRAITS_HPP +#define BOOST_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#include + +#endif // BOOST_CALL_TRAITS_HPP diff --git a/boost/cerrno.hpp b/boost/cerrno.hpp new file mode 100644 index 00000000..57278f5c --- /dev/null +++ b/boost/cerrno.hpp @@ -0,0 +1,331 @@ +// Boost cerrno.hpp header -------------------------------------------------// + +// Copyright Beman Dawes 2005. +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/system + +#ifndef BOOST_SYSTEM_CERRNO_HPP +#define BOOST_SYSTEM_CERRNO_HPP + +#include + +// supply errno values likely to be missing, particularly on Windows + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 9901 +#endif + +#ifndef EADDRINUSE +#define EADDRINUSE 9902 +#endif + +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL 9903 +#endif + +#ifndef EISCONN +#define EISCONN 9904 +#endif + +#ifndef EBADMSG +#define EBADMSG 9905 +#endif + +#ifndef ECONNABORTED +#define ECONNABORTED 9906 +#endif + +#ifndef EALREADY +#define EALREADY 9907 +#endif + +#ifndef ECONNREFUSED +#define ECONNREFUSED 9908 +#endif + +#ifndef ECONNRESET +#define ECONNRESET 9909 +#endif + +#ifndef EDESTADDRREQ +#define EDESTADDRREQ 9910 +#endif + +#ifndef EHOSTUNREACH +#define EHOSTUNREACH 9911 +#endif + +#ifndef EIDRM +#define EIDRM 9912 +#endif + +#ifndef EMSGSIZE +#define EMSGSIZE 9913 +#endif + +#ifndef ENETDOWN +#define ENETDOWN 9914 +#endif + +#ifndef ENETRESET +#define ENETRESET 9915 +#endif + +#ifndef ENETUNREACH +#define ENETUNREACH 9916 +#endif + +#ifndef ENOBUFS +#define ENOBUFS 9917 +#endif + +#ifndef ENOLINK +#define ENOLINK 9918 +#endif + +#ifndef ENODATA +#define ENODATA 9919 +#endif + +#ifndef ENOMSG +#define ENOMSG 9920 +#endif + +#ifndef ENOPROTOOPT +#define ENOPROTOOPT 9921 +#endif + +#ifndef ENOSR +#define ENOSR 9922 +#endif + +#ifndef ENOTSOCK +#define ENOTSOCK 9923 +#endif + +#ifndef ENOSTR +#define ENOSTR 9924 +#endif + +#ifndef ENOTCONN +#define ENOTCONN 9925 +#endif + +#ifndef ENOTSUP +#define ENOTSUP 9926 +#endif + +#ifndef ECANCELED +#define ECANCELED 9927 +#endif + +#ifndef EINPROGRESS +#define EINPROGRESS 9928 +#endif + +#ifndef EOPNOTSUPP +#define EOPNOTSUPP 9929 +#endif + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 9930 +#endif + +#ifndef EOWNERDEAD +#define EOWNERDEAD 9931 +#endif + +#ifndef EPROTO +#define EPROTO 9932 +#endif + +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT 9933 +#endif + +#ifndef ENOTRECOVERABLE +#define ENOTRECOVERABLE 9934 +#endif + +#ifndef ETIME +#define ETIME 9935 +#endif + +#ifndef ETXTBSY +#define ETXTBSY 9936 +#endif + +#ifndef ETIMEDOUT +#define ETIMEDOUT 9938 +#endif + +#ifndef ELOOP +#define ELOOP 9939 +#endif + +#ifndef EOVERFLOW +#define EOVERFLOW 9940 +#endif + +#ifndef EPROTOTYPE +#define EPROTOTYPE 9941 +#endif + +#ifndef ENOSYS +#define ENOSYS 9942 +#endif + +#ifndef EINVAL +#define EINVAL 9943 +#endif + +#ifndef ERANGE +#define ERANGE 9944 +#endif + +#ifndef EILSEQ +#define EILSEQ 9945 +#endif + +// Windows Mobile doesn't appear to define these: + +#ifndef E2BIG +#define E2BIG 9946 +#endif + +#ifndef EDOM +#define EDOM 9947 +#endif + +#ifndef EFAULT +#define EFAULT 9948 +#endif + +#ifndef EBADF +#define EBADF 9949 +#endif + +#ifndef EPIPE +#define EPIPE 9950 +#endif + +#ifndef EXDEV +#define EXDEV 9951 +#endif + +#ifndef EBUSY +#define EBUSY 9952 +#endif + +#ifndef ENOTEMPTY +#define ENOTEMPTY 9953 +#endif + +#ifndef ENOEXEC +#define ENOEXEC 9954 +#endif + +#ifndef EEXIST +#define EEXIST 9955 +#endif + +#ifndef EFBIG +#define EFBIG 9956 +#endif + +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 9957 +#endif + +#ifndef ENOTTY +#define ENOTTY 9958 +#endif + +#ifndef EINTR +#define EINTR 9959 +#endif + +#ifndef ESPIPE +#define ESPIPE 9960 +#endif + +#ifndef EIO +#define EIO 9961 +#endif + +#ifndef EISDIR +#define EISDIR 9962 +#endif + +#ifndef ECHILD +#define ECHILD 9963 +#endif + +#ifndef ENOLCK +#define ENOLCK 9964 +#endif + +#ifndef ENOSPC +#define ENOSPC 9965 +#endif + +#ifndef ENXIO +#define ENXIO 9966 +#endif + +#ifndef ENODEV +#define ENODEV 9967 +#endif + +#ifndef ENOENT +#define ENOENT 9968 +#endif + +#ifndef ESRCH +#define ESRCH 9969 +#endif + +#ifndef ENOTDIR +#define ENOTDIR 9970 +#endif + +#ifndef ENOMEM +#define ENOMEM 9971 +#endif + +#ifndef EPERM +#define EPERM 9972 +#endif + +#ifndef EACCES +#define EACCES 9973 +#endif + +#ifndef EROFS +#define EROFS 9974 +#endif + +#ifndef EDEADLK +#define EDEADLK 9975 +#endif + +#ifndef EAGAIN +#define EAGAIN 9976 +#endif + +#ifndef ENFILE +#define ENFILE 9977 +#endif + +#ifndef EMFILE +#define EMFILE 9978 +#endif + +#ifndef EMLINK +#define EMLINK 9979 +#endif + +#endif // include guard diff --git a/boost/checked_delete.hpp b/boost/checked_delete.hpp new file mode 100644 index 00000000..fb71c789 --- /dev/null +++ b/boost/checked_delete.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014 Glen Fernandes + * + * 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_CHECKED_DELETE_HPP +#define BOOST_CHECKED_DELETE_HPP + +// The header file at this path is deprecated; +// use boost/core/checked_delete.hpp instead. + +#include + +#endif diff --git a/boost/chrono.hpp b/boost/chrono.hpp new file mode 100644 index 00000000..a3a35229 --- /dev/null +++ b/boost/chrono.hpp @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Vicente J. Botet Escriba 2010. +// 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/stm for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CHRONO_HPP +#define BOOST_CHRONO_HPP + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + +#endif // BOOST_CHRONO_HPP diff --git a/boost/chrono/ceil.hpp b/boost/chrono/ceil.hpp new file mode 100644 index 00000000..7fbf9ddc --- /dev/null +++ b/boost/chrono/ceil.hpp @@ -0,0 +1,36 @@ +// boost/chrono/round.hpp ------------------------------------------------------------// + +// (C) Copyright Howard Hinnant +// Copyright 2011 Vicente J. Botet Escriba + +// 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/chrono for documentation. + +#ifndef BOOST_CHRONO_CEIL_HPP +#define BOOST_CHRONO_CEIL_HPP + +#include + +namespace boost +{ + namespace chrono + { + + /** + * rounds up + */ + template + To ceil(const duration& d) + { + To t = duration_cast(d); + if (t < d) + ++t; + return t; + } + + } // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/chrono.hpp b/boost/chrono/chrono.hpp new file mode 100644 index 00000000..ebc29d8d --- /dev/null +++ b/boost/chrono/chrono.hpp @@ -0,0 +1,15 @@ +// chrono.hpp --------------------------------------------------------------// + +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_CHRONO_HPP +#define BOOST_CHRONO_CHRONO_HPP + +#include +#include +#include + +#endif // BOOST_CHRONO_CHRONO_HPP diff --git a/boost/chrono/chrono_io.hpp b/boost/chrono/chrono_io.hpp new file mode 100644 index 00000000..ebd18a3d --- /dev/null +++ b/boost/chrono/chrono_io.hpp @@ -0,0 +1,34 @@ + +// chrono_io +// +// (C) Copyright Howard Hinnant +// (C) Copyright 2010-2011 Vicente J. Botet Escriba +// 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 code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o under lvm/libc++ to Boost + +#ifndef BOOST_CHRONO_CHRONO_IO_HPP +#define BOOST_CHRONO_CHRONO_IO_HPP + +#include + +//#if BOOST_CHRONO_VERSION == 2 +//#include +//#include +//#elif BOOST_CHRONO_VERSION == 1 +//#include +//#endif + +#if defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 +#include +#include +#else +#include +#endif + +#include + +#endif // BOOST_CHRONO_CHRONO_IO_HPP diff --git a/boost/chrono/clock_string.hpp b/boost/chrono/clock_string.hpp new file mode 100644 index 00000000..af025f27 --- /dev/null +++ b/boost/chrono/clock_string.hpp @@ -0,0 +1,25 @@ +// +// (C) Copyright 2010-2011 Vicente J. Botet Escriba +// 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_CHRONO_CLOCK_STRING_HPP +#define BOOST_CHRONO_CLOCK_STRING_HPP + +#include + +namespace boost +{ + namespace chrono + { + + template + struct clock_string; + + } // chrono + +} // boost + +#endif // BOOST_CHRONO_CLOCK_STRING_HPP diff --git a/boost/chrono/config.hpp b/boost/chrono/config.hpp new file mode 100644 index 00000000..1045ba3a --- /dev/null +++ b/boost/chrono/config.hpp @@ -0,0 +1,216 @@ +// boost/chrono/config.hpp -------------------------------------------------// + +// Copyright Beman Dawes 2003, 2006, 2008 +// Copyright 2009-2011 Vicente J. Botet Escriba +// 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) + +// See http://www.boost.org/libs/chrono for documentation. + +#ifndef BOOST_CHRONO_CONFIG_HPP +#define BOOST_CHRONO_CONFIG_HPP + +#include +#include + +#if !defined BOOST_CHRONO_VERSION +#define BOOST_CHRONO_VERSION 1 +#else +#if BOOST_CHRONO_VERSION!=1 && BOOST_CHRONO_VERSION!=2 +#error "BOOST_CHRONO_VERSION must be 1 or 2" +#endif +#endif + +#if defined(BOOST_CHRONO_SOURCE) && !defined(BOOST_USE_WINDOWS_H) +#define BOOST_USE_WINDOWS_H +#endif + +#if ! defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT \ + && ! defined BOOST_CHRONO_DONT_PROVIDE_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT + +# define BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT + +#endif + +// BOOST_CHRONO_POSIX_API, BOOST_CHRONO_MAC_API, or BOOST_CHRONO_WINDOWS_API +// can be defined by the user to specify which API should be used + +#if defined(BOOST_CHRONO_WINDOWS_API) +# warning Boost.Chrono will use the Windows API +#elif defined(BOOST_CHRONO_MAC_API) +# warning Boost.Chrono will use the Mac API +#elif defined(BOOST_CHRONO_POSIX_API) +# warning Boost.Chrono will use the POSIX API +#endif + +# if defined( BOOST_CHRONO_WINDOWS_API ) && defined( BOOST_CHRONO_POSIX_API ) +# error both BOOST_CHRONO_WINDOWS_API and BOOST_CHRONO_POSIX_API are defined +# elif defined( BOOST_CHRONO_WINDOWS_API ) && defined( BOOST_CHRONO_MAC_API ) +# error both BOOST_CHRONO_WINDOWS_API and BOOST_CHRONO_MAC_API are defined +# elif defined( BOOST_CHRONO_MAC_API ) && defined( BOOST_CHRONO_POSIX_API ) +# error both BOOST_CHRONO_MAC_API and BOOST_CHRONO_POSIX_API are defined +# elif !defined( BOOST_CHRONO_WINDOWS_API ) && !defined( BOOST_CHRONO_MAC_API ) && !defined( BOOST_CHRONO_POSIX_API ) +# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) +# define BOOST_CHRONO_WINDOWS_API +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +# define BOOST_CHRONO_MAC_API +# else +# define BOOST_CHRONO_POSIX_API +# endif +# endif + +# if defined( BOOST_CHRONO_WINDOWS_API ) +# ifndef UNDER_CE +# define BOOST_CHRONO_HAS_PROCESS_CLOCKS +# endif +# define BOOST_CHRONO_HAS_CLOCK_STEADY +# if BOOST_PLAT_WINDOWS_DESKTOP +# define BOOST_CHRONO_HAS_THREAD_CLOCK +# endif +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif + +# if defined( BOOST_CHRONO_MAC_API ) +# define BOOST_CHRONO_HAS_PROCESS_CLOCKS +# define BOOST_CHRONO_HAS_CLOCK_STEADY +# define BOOST_CHRONO_HAS_THREAD_CLOCK +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif + +# if defined( BOOST_CHRONO_POSIX_API ) +# define BOOST_CHRONO_HAS_PROCESS_CLOCKS +# include //to check for CLOCK_REALTIME and CLOCK_MONOTONIC and _POSIX_THREAD_CPUTIME +# if defined(CLOCK_MONOTONIC) +# define BOOST_CHRONO_HAS_CLOCK_STEADY +# endif +# if defined(_POSIX_THREAD_CPUTIME) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_CHRONO_HAS_THREAD_CLOCK +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif +# if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_CHRONO_HAS_THREAD_CLOCK +# define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true +# endif +# if defined(sun) || defined(__sun) +# undef BOOST_CHRONO_HAS_THREAD_CLOCK +# undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY +# endif +# if (defined(__HP_aCC) || defined(__GNUC__)) && defined(__hpux) +# undef BOOST_CHRONO_HAS_THREAD_CLOCK +# undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY +# endif +# if defined(__VXWORKS__) +# undef BOOST_CHRONO_HAS_PROCESS_CLOCKS +# endif +# endif + +#if defined(BOOST_CHRONO_THREAD_DISABLED) && defined(BOOST_CHRONO_HAS_THREAD_CLOCK) +#undef BOOST_CHRONO_HAS_THREAD_CLOCK +#undef BOOST_CHRONO_THREAD_CLOCK_IS_STEADY +#endif + +// unicode support ------------------------------// + +#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) || defined(BOOST_NO_CXX11_CHAR16_T) || defined(BOOST_NO_CXX11_CHAR32_T) +//~ #define BOOST_CHRONO_HAS_UNICODE_SUPPORT +#else +#define BOOST_CHRONO_HAS_UNICODE_SUPPORT 1 +#endif + +#ifndef BOOST_CHRONO_LIB_CONSTEXPR +#if defined( BOOST_NO_CXX11_NUMERIC_LIMITS ) +#define BOOST_CHRONO_LIB_CONSTEXPR +#elif defined(_LIBCPP_VERSION) && !defined(_LIBCPP_CONSTEXPR) + #define BOOST_CHRONO_LIB_CONSTEXPR +#else + #define BOOST_CHRONO_LIB_CONSTEXPR BOOST_CONSTEXPR +#endif +#endif + +#if defined( BOOST_NO_CXX11_NUMERIC_LIMITS ) +# define BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW throw() +#else +#ifdef BOOST_NO_CXX11_NOEXCEPT +# define BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW throw() +#else +# define BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW noexcept +#endif +#endif + +#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING \ + && defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +#error "BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING && BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING defined" +#endif + +#if defined BOOST_CHRONO_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 \ + && defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 +#error "BOOST_CHRONO_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 && BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 defined" +#endif + +#if ! defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING \ + && ! defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +#define BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING +#endif + +#if (BOOST_CHRONO_VERSION == 2) +#if ! defined BOOST_CHRONO_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 \ + && ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 +#define BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 +#endif +#endif + +#ifdef BOOST_CHRONO_HEADER_ONLY +#define BOOST_CHRONO_INLINE inline +#define BOOST_CHRONO_STATIC inline +#define BOOST_CHRONO_DECL + +#else +#define BOOST_CHRONO_INLINE +#define BOOST_CHRONO_STATIC static + +// enable dynamic linking on Windows ---------------------------------------// + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_CHRONO_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CHRONO_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_CHRONO_SOURCE +# define BOOST_CHRONO_DECL BOOST_SYMBOL_EXPORT +#else +# define BOOST_CHRONO_DECL BOOST_SYMBOL_IMPORT +#endif // BOOST_CHRONO_SOURCE +#endif // DYN_LINK +// +// if BOOST_CHRONO_DECL isn't defined yet define it now: +#ifndef BOOST_CHRONO_DECL +#define BOOST_CHRONO_DECL +#endif + + + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_CHRONO_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_CHRONO_NO_LIB) +// +// Set the name of our library; this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_chrono +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CHRONO_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled +#endif // BOOST_CHRONO_HEADER_ONLY +#endif // BOOST_CHRONO_CONFIG_HPP + diff --git a/boost/chrono/detail/inlined/chrono.hpp b/boost/chrono/detail/inlined/chrono.hpp new file mode 100644 index 00000000..3bad546d --- /dev/null +++ b/boost/chrono/detail/inlined/chrono.hpp @@ -0,0 +1,46 @@ +// chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_INLINED_CHRONO_HPP +#define BOOST_CHRONO_DETAIL_INLINED_CHRONO_HPP + +#include +#include +#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING +#include +#endif +#include +#include + +//----------------------------------------------------------------------------// +// // +// Platform-specific Implementations // +// // +//----------------------------------------------------------------------------// + +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#if defined(BOOST_CHRONO_WINDOWS_API) +#include + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_MAC_API) +#include + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_POSIX_API) +#include + +#endif // POSIX + +#endif diff --git a/boost/chrono/detail/inlined/mac/chrono.hpp b/boost/chrono/detail/inlined/mac/chrono.hpp new file mode 100644 index 00000000..0bd3400a --- /dev/null +++ b/boost/chrono/detail/inlined/mac/chrono.hpp @@ -0,0 +1,242 @@ +// mac/chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// + +#include //for gettimeofday and timeval +#include // mach_absolute_time, mach_timebase_info_data_t +#include + +namespace boost +{ +namespace chrono +{ + +// system_clock + +// gettimeofday is the most precise "system time" available on this platform. +// It returns the number of microseconds since New Years 1970 in a struct called timeval +// which has a field for seconds and a field for microseconds. +// Fill in the timeval and then convert that to the time_point +system_clock::time_point +system_clock::now() BOOST_NOEXCEPT +{ + timeval tv; + gettimeofday(&tv, 0); + return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +system_clock::time_point +system_clock::now(system::error_code & ec) +{ + timeval tv; + gettimeofday(&tv, 0); + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); +} +#endif +// Take advantage of the fact that on this platform time_t is nothing but +// an integral count of seconds since New Years 1970 (same epoch as timeval). +// Just get the duration out of the time_point and truncate it to seconds. +time_t +system_clock::to_time_t(const time_point& t) BOOST_NOEXCEPT +{ + return time_t(duration_cast(t.time_since_epoch()).count()); +} + +// Just turn the time_t into a count of seconds and construct a time_point with it. +system_clock::time_point +system_clock::from_time_t(time_t t) BOOST_NOEXCEPT +{ + return system_clock::time_point(seconds(t)); +} + +namespace chrono_detail +{ + +// steady_clock + +// Note, in this implementation steady_clock and high_resolution_clock +// are the same clock. They are both based on mach_absolute_time(). +// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of +// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom +// are run time constants supplied by the OS. This clock has no relationship +// to the Gregorian calendar. It's main use is as a high resolution timer. + +// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize +// for that case as an optimization. +BOOST_CHRONO_STATIC +steady_clock::rep +steady_simplified() +{ + return mach_absolute_time(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +BOOST_CHRONO_STATIC +steady_clock::rep +steady_simplified_ec(system::error_code & ec) +{ + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return mach_absolute_time(); +} +#endif + +BOOST_CHRONO_STATIC +double +compute_steady_factor(kern_return_t& err) +{ + mach_timebase_info_data_t MachInfo; + err = mach_timebase_info(&MachInfo); + if ( err != 0 ) { + return 0; + } + return static_cast(MachInfo.numer) / MachInfo.denom; +} + +BOOST_CHRONO_STATIC +steady_clock::rep +steady_full() +{ + kern_return_t err; + const double factor = chrono_detail::compute_steady_factor(err); + if (err != 0) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + return static_cast(mach_absolute_time() * factor); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +BOOST_CHRONO_STATIC +steady_clock::rep +steady_full_ec(system::error_code & ec) +{ + kern_return_t err; + const double factor = chrono_detail::compute_steady_factor(err); + if (err != 0) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + err, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return steady_clock::rep(); + } + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return static_cast(mach_absolute_time() * factor); +} +#endif + +typedef steady_clock::rep (*FP)(); +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +typedef steady_clock::rep (*FP_ec)(system::error_code &); +#endif + +BOOST_CHRONO_STATIC +FP +init_steady_clock(kern_return_t & err) +{ + mach_timebase_info_data_t MachInfo; + err = mach_timebase_info(&MachInfo); + if ( err != 0 ) + { + return 0; + } + + if (MachInfo.numer == MachInfo.denom) + { + return &chrono_detail::steady_simplified; + } + return &chrono_detail::steady_full; +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +BOOST_CHRONO_STATIC +FP_ec +init_steady_clock_ec(kern_return_t & err) +{ + mach_timebase_info_data_t MachInfo; + err = mach_timebase_info(&MachInfo); + if ( err != 0 ) + { + return 0; + } + + if (MachInfo.numer == MachInfo.denom) + { + return &chrono_detail::steady_simplified_ec; + } + return &chrono_detail::steady_full_ec; +} +#endif +} + +steady_clock::time_point +steady_clock::now() BOOST_NOEXCEPT +{ + kern_return_t err; + chrono_detail::FP fp = chrono_detail::init_steady_clock(err); + if ( err != 0 ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + return time_point(duration(fp())); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +steady_clock::time_point +steady_clock::now(system::error_code & ec) +{ + kern_return_t err; + chrono_detail::FP_ec fp = chrono_detail::init_steady_clock_ec(err); + if ( err != 0 ) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + err, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( err, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration(fp(ec))); +} +#endif +} // namespace chrono +} // namespace boost diff --git a/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp new file mode 100644 index 00000000..6e55b0f2 --- /dev/null +++ b/boost/chrono/detail/inlined/mac/process_cpu_clocks.hpp @@ -0,0 +1,356 @@ +// boost process_cpu_clocks.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include +#include +#include + +#include //for gettimeofday and timeval +#include //for times +# include + +namespace boost +{ + namespace chrono + { + namespace chrono_detail + { + + inline long tick_factor() // multiplier to convert ticks + // to nanoseconds; -1 if unknown + { + long factor = 0; + if (!factor) + { + if ((factor = ::sysconf(_SC_CLK_TCK)) <= 0) + factor = -1; + else + { + BOOST_ASSERT(factor <= 1000000000l); // doesn't handle large ticks + factor = 1000000000l / factor; // compute factor + if (!factor) + factor = -1; + } + } + return factor; + } + } + + + process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT + { +#if 1 + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + return time_point(nanoseconds(c * factor)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +#else + clock_t c = ::clock(); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + return time_point(nanoseconds(c * factor)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +#endif + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_real_cpu_clock::time_point process_real_cpu_clock::now(system::error_code & ec) + { + +#if 1 + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(nanoseconds(c * factor)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } +#else + clock_t c = ::clock(); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(nanoseconds(c * factor)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } +#endif + + } +#endif + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_user_cpu_clock::time_point process_user_cpu_clock::now(system::error_code & ec) + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_user_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime) * factor)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_user_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } + } +#endif + + process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime) + * factor)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); + } + process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime) + * factor)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_system_cpu_clock::time_point process_system_cpu_clock::now(system::error_code & ec) + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_system_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime) * factor)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_system_cpu_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } + } +#endif + + process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT + { + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + time_point::rep + r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime + + tm.tms_cstime) * factor); + return time_point(duration(r)); + } else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + process_cpu_clock::time_point process_cpu_clock::now(system::error_code & ec) + { + + tms tm; + clock_t c = ::times(&tm); + if (c == clock_t(-1)) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } else + { + long factor = chrono_detail::tick_factor(); + if (factor != -1) + { + time_point::rep + r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime + + tm.tms_cstime) * factor); + return time_point(duration(r)); + } else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_clock")); + } else + { + ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY); + return time_point(); + } + } + } + + } +#endif + + } +} diff --git a/boost/chrono/detail/inlined/mac/thread_clock.hpp b/boost/chrono/detail/inlined/mac/thread_clock.hpp new file mode 100644 index 00000000..690458f4 --- /dev/null +++ b/boost/chrono/detail/inlined/mac/thread_clock.hpp @@ -0,0 +1,92 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright Vicente J. Botet Escriba 2009-2011 +// Copyright Christopher Brown 2013 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include +#include +#include +#include + +# include +# include + +namespace boost { namespace chrono { + + thread_clock::time_point thread_clock::now( ) BOOST_NOEXCEPT + { + // get the thread port (borrowing pthread's reference) + mach_port_t port = pthread_mach_thread_np(pthread_self()); + + // get the thread info + thread_basic_info_data_t info; + mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; + if ( thread_info(port, THREAD_BASIC_INFO, (thread_info_t)&info, &count) != KERN_SUCCESS ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + + // convert to nanoseconds + duration user = duration( + static_cast( info.user_time.seconds ) * 1000000000 + + static_cast(info.user_time.microseconds ) * 1000); + + duration system = duration( + static_cast( info.system_time.seconds ) * 1000000000 + + static_cast( info.system_time.microseconds ) * 1000); + + return time_point( user + system ); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + thread_clock::time_point thread_clock::now( system::error_code & ec ) + { + // get the thread port (borrowing pthread's reference) + mach_port_t port = pthread_mach_thread_np(pthread_self()); + + // get the thread info + thread_basic_info_data_t info; + mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; + if ( thread_info(port, THREAD_BASIC_INFO, (thread_info_t)&info, &count) != KERN_SUCCESS ) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + EINVAL, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::thread_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + + // convert to nanoseconds + duration user = duration( + static_cast( info.user_time.seconds ) * 1000000000 + + static_cast(info.user_time.microseconds ) * 1000); + + duration system = duration( + static_cast( info.system_time.seconds ) * 1000000000 + + static_cast( info.system_time.microseconds ) * 1000); + + return time_point( user + system ); + } +#endif +} } diff --git a/boost/chrono/detail/inlined/posix/chrono.hpp b/boost/chrono/detail/inlined/posix/chrono.hpp new file mode 100644 index 00000000..c4c8a6ad --- /dev/null +++ b/boost/chrono/detail/inlined/posix/chrono.hpp @@ -0,0 +1,121 @@ +// posix/chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// + +#include // for clock_gettime +#include + +namespace boost +{ +namespace chrono +{ + + system_clock::time_point system_clock::now() BOOST_NOEXCEPT + { + timespec ts; + if ( ::clock_gettime( CLOCK_REALTIME, &ts ) ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + + return time_point(duration( + static_cast( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + system_clock::time_point system_clock::now(system::error_code & ec) + { + timespec ts; + if ( ::clock_gettime( CLOCK_REALTIME, &ts ) ) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::system_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + static_cast( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } +#endif + + std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT + { + return static_cast( t.time_since_epoch().count() / 1000000000 ); + } + + system_clock::time_point system_clock::from_time_t(std::time_t t) BOOST_NOEXCEPT + { + return time_point(duration(static_cast(t) * 1000000000)); + } + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + + steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT + { + timespec ts; + if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) ) + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + + return time_point(duration( + static_cast( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + steady_clock::time_point steady_clock::now(system::error_code & ec) + { + timespec ts; + if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) ) + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + static_cast( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + } +#endif +#endif + +} // namespace chrono +} // namespace boost + + diff --git a/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp new file mode 100644 index 00000000..feecc867 --- /dev/null +++ b/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp @@ -0,0 +1,354 @@ +// boost process_cpu_clocks.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright Vicente J. Botet Escriba 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include +#include +#include + +#include +#include +#include // for clock_gettime + + +namespace boost { namespace chrono { +namespace chrono_detail +{ + inline nanoseconds::rep tick_factor() // multiplier to convert ticks + // to nanoseconds; -1 if unknown + { + long factor = 0; + if ( !factor ) + { + if ( (factor = ::sysconf( _SC_CLK_TCK )) <= 0 ) + factor = -1; + else + { + BOOST_ASSERT( factor <= 1000000000l ); // doesn't handle large ticks + factor = 1000000000l / factor; // compute factor + if ( !factor ) factor = -1; + } + } + return factor; + } +} + +process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + return time_point( + nanoseconds(c*chrono_detail::tick_factor())); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_real_cpu_clock::time_point process_real_cpu_clock::now( + system::error_code & ec) +{ + + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_real_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point( + nanoseconds(c*chrono_detail::tick_factor())); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_real_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } +} +#endif + +process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + return time_point( + nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor())); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_user_cpu_clock::time_point process_user_cpu_clock::now( + system::error_code & ec) +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_user_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point( + nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor())); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_user_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } +} +#endif + +process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + return time_point( + nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor())); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + } +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_system_cpu_clock::time_point process_system_cpu_clock::now( + system::error_code & ec) +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_system_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point( + nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor())); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_system_cpu_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } +} +#endif + +process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + else + { + nanoseconds::rep factor = chrono_detail::tick_factor(); + if ( factor != -1 ) + { + time_point::rep r( + c*factor, + (tm.tms_utime + tm.tms_cutime)*factor, + (tm.tms_stime + tm.tms_cstime)*factor); + return time_point(duration(r)); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + } + return time_point(); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_cpu_clock::time_point process_cpu_clock::now( + system::error_code & ec ) +{ + tms tm; + clock_t c = ::times( &tm ); + if ( c == clock_t(-1) ) // error + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + else + { + if ( chrono_detail::tick_factor() != -1 ) + { + time_point::rep r( + c*chrono_detail::tick_factor(), + (tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(), + (tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()); + return time_point(duration(r)); + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + } + +} +#endif + +} } diff --git a/boost/chrono/detail/inlined/posix/thread_clock.hpp b/boost/chrono/detail/inlined/posix/thread_clock.hpp new file mode 100644 index 00000000..a42b3c8a --- /dev/null +++ b/boost/chrono/detail/inlined/posix/thread_clock.hpp @@ -0,0 +1,92 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright Vicente J. Botet Escriba 2009-2011 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// + +#include +#include +#include +#include + +#if !defined(__VXWORKS__) +# include +#endif +# include +# include + +namespace boost { namespace chrono { + + thread_clock::time_point thread_clock::now( ) BOOST_NOEXCEPT + { + struct timespec ts; +#if defined CLOCK_THREAD_CPUTIME_ID + // get the timespec associated to the thread clock + if ( ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) ) +#else + // get the current thread + pthread_t pth=pthread_self(); + // get the clock_id associated to the current thread + clockid_t clock_id; + pthread_getcpuclockid(pth, &clock_id); + // get the timespec associated to the thread clock + if ( ::clock_gettime( clock_id, &ts ) ) +#endif + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + + // transform to nanoseconds + return time_point(duration( + static_cast( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + thread_clock::time_point thread_clock::now( system::error_code & ec ) + { + struct timespec ts; +#if defined CLOCK_THREAD_CPUTIME_ID + // get the timespec associated to the thread clock + if ( ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) ) +#else + // get the current thread + pthread_t pth=pthread_self(); + // get the clock_id associated to the current thread + clockid_t clock_id; + pthread_getcpuclockid(pth, &clock_id); + // get the timespec associated to the thread clock + if ( ::clock_gettime( clock_id, &ts ) ) +#endif + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::thread_clock" )); + } + else + { + ec.assign( errno, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + // transform to nanoseconds + return time_point(duration( + static_cast( ts.tv_sec ) * 1000000000 + ts.tv_nsec)); + + } +#endif +} } diff --git a/boost/chrono/detail/inlined/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/process_cpu_clocks.hpp new file mode 100644 index 00000000..fad60361 --- /dev/null +++ b/boost/chrono/detail/inlined/process_cpu_clocks.hpp @@ -0,0 +1,46 @@ +// boost process_cpu_clocks.cpp -----------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_PROCESS_CPU_CLOCKS_HPP +#define BOOST_CHRONO_DETAIL_INLINED_PROCESS_CPU_CLOCKS_HPP + + +#include +#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS) + +#include +#include +#include +#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING +#include +#endif +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#if defined(BOOST_CHRONO_WINDOWS_API) +#include + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_MAC_API) +#include + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_POSIX_API) +#include + +#endif // POSIX + +#endif + +#endif diff --git a/boost/chrono/detail/inlined/thread_clock.hpp b/boost/chrono/detail/inlined/thread_clock.hpp new file mode 100644 index 00000000..e4f8317e --- /dev/null +++ b/boost/chrono/detail/inlined/thread_clock.hpp @@ -0,0 +1,46 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_THREAD_CLOCK_HPP +#define BOOST_CHRONO_DETAIL_INLINED_THREAD_CLOCK_HPP + +#include +#include +#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK) +#include +#include +#if defined BOOST_CHRONO_PROVIDE_HYBRID_ERROR_HANDLING +#include +#endif +#include +#include + +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#if defined(BOOST_CHRONO_WINDOWS_API) +#include + +//----------------------------------------------------------------------------// +// Mac // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_MAC_API) +#include + +//----------------------------------------------------------------------------// +// POSIX // +//----------------------------------------------------------------------------// +#elif defined(BOOST_CHRONO_POSIX_API) +#include + +#endif // POSIX + +#endif +#endif diff --git a/boost/chrono/detail/inlined/win/chrono.hpp b/boost/chrono/detail/inlined/win/chrono.hpp new file mode 100644 index 00000000..e61f11e7 --- /dev/null +++ b/boost/chrono/detail/inlined/win/chrono.hpp @@ -0,0 +1,150 @@ +// win/chrono.cpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2008 +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//----------------------------------------------------------------------------// +// Windows // +//----------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP +#define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP + +#include +#include +#include +#include + +namespace boost +{ +namespace chrono +{ +namespace chrono_detail +{ + + BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT + { + boost::detail::winapi::LARGE_INTEGER_ freq; + if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) ) + return 0.0L; + return double(1000000000.0L / freq.QuadPart); + } + +} + + steady_clock::time_point steady_clock::now() BOOST_NOEXCEPT + { + double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); + + boost::detail::winapi::LARGE_INTEGER_ pcount; + if ( nanosecs_per_tic <= 0.0L ) + { + BOOST_ASSERT(0 && "Boost::Chrono - get_nanosecs_per_tic Internal Error"); + return steady_clock::time_point(); + } + unsigned times=0; + while ( ! boost::detail::winapi::QueryPerformanceCounter( &pcount ) ) + { + if ( ++times > 3 ) + { + BOOST_ASSERT(0 && "Boost::Chrono - QueryPerformanceCounter Internal Error"); + return steady_clock::time_point(); + } + } + + return steady_clock::time_point(steady_clock::duration( + static_cast((nanosecs_per_tic) * pcount.QuadPart))); + } + + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + steady_clock::time_point steady_clock::now( system::error_code & ec ) + { + double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); + + boost::detail::winapi::LARGE_INTEGER_ pcount; + if ( (nanosecs_per_tic <= 0.0L) + || (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) ) + { + boost::detail::winapi::DWORD_ cause = + ((nanosecs_per_tic <= 0.0L) + ? ERROR_NOT_SUPPORTED + : boost::detail::winapi::GetLastError()); + if (BOOST_CHRONO_IS_THROWS(ec)) { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::steady_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return steady_clock::time_point(duration(0)); + } + } + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + static_cast(nanosecs_per_tic * pcount.QuadPart))); + } +#endif + + BOOST_CHRONO_INLINE + system_clock::time_point system_clock::now() BOOST_NOEXCEPT + { + boost::detail::winapi::FILETIME_ ft; + boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails + return system_clock::time_point( + system_clock::duration( + ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime) + - 116444736000000000LL + //- (134775LL*864000000000LL) + ) + ); + } + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + BOOST_CHRONO_INLINE + system_clock::time_point system_clock::now( system::error_code & ec ) + { + boost::detail::winapi::FILETIME_ ft; + boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return system_clock::time_point( + system_clock::duration( + ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime) + - 116444736000000000LL + //- (134775LL*864000000000LL) + )); + } +#endif + + BOOST_CHRONO_INLINE + std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT + { + __int64 temp = t.time_since_epoch().count(); + temp /= 10000000; + return static_cast( temp ); + } + + BOOST_CHRONO_INLINE + system_clock::time_point system_clock::from_time_t(std::time_t t) BOOST_NOEXCEPT + { + __int64 temp = t; + temp *= 10000000; + return time_point(duration(temp)); + } + +} // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp b/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp new file mode 100644 index 00000000..7169f802 --- /dev/null +++ b/boost/chrono/detail/inlined/win/process_cpu_clocks.hpp @@ -0,0 +1,281 @@ +// boost process_timer.cpp -----------------------------------------------------------// + +// Copyright Beman Dawes 1994, 2006, 2008 +// Copyright 2009-2010 Vicente J. Botet Escriba +// Copyright (c) Microsoft Corporation 2014 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_PROCESS_CLOCK_HPP +#define BOOST_CHRONO_DETAIL_INLINED_WIN_PROCESS_CLOCK_HPP + +#include +#include +#include +#include +#include + +#include +#include +#if BOOST_PLAT_WINDOWS_DESKTOP +#include +#endif + +namespace boost +{ +namespace chrono +{ + +process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT +{ + clock_t c = ::clock(); + if ( c == clock_t(-1) ) // error + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + } + typedef ratio_divide >::type R; + return time_point( + duration(static_cast(c)*R::num/R::den) + ); +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_real_cpu_clock::time_point process_real_cpu_clock::now( + system::error_code & ec) +{ + clock_t c = ::clock(); + if ( c == clock_t(-1) ) // error + { + boost::throw_exception( + system::system_error( + errno, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_real_cpu_clock" )); + } + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + typedef ratio_divide >::type R; + return time_point( + duration(static_cast(c)*R::num/R::den) + ); +} +#endif + +#if BOOST_PLAT_WINDOWS_DESKTOP +process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetProcessTimes( + boost::detail::winapi::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + return time_point(duration( + ((static_cast(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 + )); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_user_cpu_clock::time_point process_user_cpu_clock::now( + system::error_code & ec) +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetProcessTimes( + boost::detail::winapi::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + ((static_cast(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 + )); + } + else + { + boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError(); + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_user_cpu_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + +} +#endif + +process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetProcessTimes( + boost::detail::winapi::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + return time_point(duration( + ((static_cast(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 + )); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_system_cpu_clock::time_point process_system_cpu_clock::now( + system::error_code & ec) +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetProcessTimes( + boost::detail::winapi::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(duration( + ((static_cast(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 + )); + } + else + { + boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError(); + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_system_cpu_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + +} +#endif + +process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetProcessTimes( + boost::detail::winapi::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + time_point::rep r(process_real_cpu_clock::now().time_since_epoch().count() + , + ((static_cast(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime + ) * 100, + ((static_cast(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime + ) * 100 + ); + return time_point(duration(r)); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +process_cpu_clock::time_point process_cpu_clock::now( + system::error_code & ec ) +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetProcessTimes( + boost::detail::winapi::GetCurrentProcess(), &creation, &exit, + &system_time, &user_time ) ) + { + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + time_point::rep r(process_real_cpu_clock::now().time_since_epoch().count() + , + ((static_cast(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime + ) * 100, + ((static_cast(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime + ) * 100 + ); + return time_point(duration(r)); + } + else + { + boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError(); + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + cause, + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::process_cpu_clock" )); + } + else + { + ec.assign( cause, BOOST_CHRONO_SYSTEM_CATEGORY ); + return time_point(); + } + } + +} +#endif +#endif +} // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/detail/inlined/win/thread_clock.hpp b/boost/chrono/detail/inlined/win/thread_clock.hpp new file mode 100644 index 00000000..037ccbee --- /dev/null +++ b/boost/chrono/detail/inlined/win/thread_clock.hpp @@ -0,0 +1,103 @@ +// boost thread_clock.cpp -----------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/chrono for documentation. + +//--------------------------------------------------------------------------------------// +#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_THREAD_CLOCK_HPP +#define BOOST_CHRONO_DETAIL_INLINED_WIN_THREAD_CLOCK_HPP + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost +{ +namespace chrono +{ + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING +thread_clock::time_point thread_clock::now( system::error_code & ec ) +{ + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetThreadTimes( + boost::detail::winapi::GetCurrentThread (), &creation, &exit, + &system_time, &user_time ) ) + { + duration user = duration( + ((static_cast(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 ); + + duration system = duration( + ((static_cast(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 ); + + if (!BOOST_CHRONO_IS_THROWS(ec)) + { + ec.clear(); + } + return time_point(system+user); + + } + else + { + if (BOOST_CHRONO_IS_THROWS(ec)) + { + boost::throw_exception( + system::system_error( + boost::detail::winapi::GetLastError(), + BOOST_CHRONO_SYSTEM_CATEGORY, + "chrono::thread_clock" )); + } + else + { + ec.assign( boost::detail::winapi::GetLastError(), BOOST_CHRONO_SYSTEM_CATEGORY ); + return thread_clock::time_point(duration(0)); + } + } +} +#endif + +thread_clock::time_point thread_clock::now() BOOST_NOEXCEPT +{ + + // note that Windows uses 100 nanosecond ticks for FILETIME + boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time; + + if ( boost::detail::winapi::GetThreadTimes( + boost::detail::winapi::GetCurrentThread (), &creation, &exit, + &system_time, &user_time ) ) + { + duration user = duration( + ((static_cast(user_time.dwHighDateTime) << 32) + | user_time.dwLowDateTime) * 100 ); + + duration system = duration( + ((static_cast(system_time.dwHighDateTime) << 32) + | system_time.dwLowDateTime) * 100 ); + + return time_point(system+user); + } + else + { + BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); + return time_point(); + } + +} + +} // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/detail/is_evenly_divisible_by.hpp b/boost/chrono/detail/is_evenly_divisible_by.hpp new file mode 100644 index 00000000..960a208a --- /dev/null +++ b/boost/chrono/detail/is_evenly_divisible_by.hpp @@ -0,0 +1,31 @@ +// is_evenly_divisible_by.hpp --------------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_IS_EVENLY_DIVISIBLE_BY_HPP +#define BOOST_CHRONO_DETAIL_IS_EVENLY_DIVISIBLE_BY_HPP + +#include + +#include +#include + +namespace boost { +namespace chrono { +namespace chrono_detail { + +// template +// struct is_evenly_divisible_by : public boost::mpl::bool_ < ratio_divide::type::den == 1 > +// {}; + template + struct is_evenly_divisible_by : public boost::ratio_detail::is_evenly_divisible_by + {}; + +} // namespace chrono_detail +} // namespace detail +} // namespace chrono + +#endif // BOOST_CHRONO_DETAIL_IS_EVENLY_DIVISIBLE_BY_HPP diff --git a/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp b/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp new file mode 100644 index 00000000..94936c8b --- /dev/null +++ b/boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp @@ -0,0 +1,54 @@ +// is_evenly_divisible_by.hpp --------------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_NO_WARNING_SIGNED_UNSIGNED_CMP_HPP +#define BOOST_CHRONO_DETAIL_NO_WARNING_SIGNED_UNSIGNED_CMP_HPP + +// +// We simply cannot include this header on gcc without getting copious warnings of the kind: +// +//../../../boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp:37: warning: comparison between signed and unsigned integer expressions +// +// And yet there is no other reasonable implementation, so we declare this a system header +// to suppress these warnings. +// + +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#elif defined __SUNPRO_CC +#pragma disable_warn +#elif defined _MSC_VER +#pragma warning(push, 1) +#endif + +namespace boost { +namespace chrono { +namespace detail { + + template + bool lt(T t, U u) + { + return t < u; + } + + template + bool gt(T t, U u) + { + return t > u; + } + +} // namespace detail +} // namespace detail +} // namespace chrono + +#if defined __SUNPRO_CC +#pragma enable_warn +#elif defined _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_CHRONO_DETAIL_NO_WARNING_SIGNED_UNSIGNED_CMP_HPP diff --git a/boost/chrono/detail/scan_keyword.hpp b/boost/chrono/detail/scan_keyword.hpp new file mode 100644 index 00000000..aa4e2e87 --- /dev/null +++ b/boost/chrono/detail/scan_keyword.hpp @@ -0,0 +1,163 @@ +// scan_keyword.hpp --------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Adaptation to Boost of the libcxx + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP +#define BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP + +#include + +#include +#include +#include +#include +#include + +namespace boost { + using movelib::unique_ptr; + +namespace chrono { +namespace chrono_detail { + +inline void free_aux(void* ptr) { free(ptr); } + +// scan_keyword +// Scans [b, e) until a match is found in the basic_strings range +// [kb, ke) or until it can be shown that there is no match in [kb, ke). +// b will be incremented (visibly), consuming CharT until a match is found +// or proved to not exist. A keyword may be "", in which will match anything. +// If one keyword is a prefix of another, and the next CharT in the input +// might match another keyword, the algorithm will attempt to find the longest +// matching keyword. If the longer matching keyword ends up not matching, then +// no keyword match is found. If no keyword match is found, ke is returned +// and failbit is set in err. +// Else an iterator pointing to the matching keyword is found. If more than +// one keyword matches, an iterator to the first matching keyword is returned. +// If on exit b == e, eofbit is set in err. +// Examples: +// Keywords: "a", "abb" +// If the input is "a", the first keyword matches and eofbit is set. +// If the input is "abc", no match is found and "ab" are consumed. + +template +ForwardIterator +scan_keyword(InputIterator& b, InputIterator e, + ForwardIterator kb, ForwardIterator ke, + std::ios_base::iostate& err + ) +{ + typedef typename std::iterator_traits::value_type CharT; + size_t nkw = std::distance(kb, ke); + const unsigned char doesnt_match = '\0'; + const unsigned char might_match = '\1'; + const unsigned char does_match = '\2'; + unsigned char statbuf[100]; + unsigned char* status = statbuf; + // Change free by free_aux to avoid + // Error: Could not find a match for boost::interprocess::unique_ptr::unique_ptr(int, extern "C" void(void*)) + unique_ptr stat_hold(0, free_aux); + if (nkw > sizeof(statbuf)) + { + status = (unsigned char*)malloc(nkw); + if (status == 0) + throw_exception(std::bad_alloc()); + stat_hold.reset(status); + } + size_t n_might_match = nkw; // At this point, any keyword might match + size_t n_does_match = 0; // but none of them definitely do + // Initialize all statuses to might_match, except for "" keywords are does_match + unsigned char* st = status; + for (ForwardIterator ky = kb; ky != ke; ++ky, ++st) + { + if (!ky->empty()) + *st = might_match; + else + { + *st = does_match; + --n_might_match; + ++n_does_match; + } + } + // While there might be a match, test keywords against the next CharT + for (size_t indx = 0; b != e && n_might_match > 0; ++indx) + { + // Peek at the next CharT but don't consume it + CharT c = *b; + bool consume = false; + // For each keyword which might match, see if the indx character is c + // If a match if found, consume c + // If a match is found, and that is the last character in the keyword, + // then that keyword matches. + // If the keyword doesn't match this character, then change the keyword + // to doesn't match + st = status; + for (ForwardIterator ky = kb; ky != ke; ++ky, ++st) + { + if (*st == might_match) + { + CharT kc = (*ky)[indx]; + if (c == kc) + { + consume = true; + if (ky->size() == indx+1) + { + *st = does_match; + --n_might_match; + ++n_does_match; + } + } + else + { + *st = doesnt_match; + --n_might_match; + } + } + } + // consume if we matched a character + if (consume) + { + ++b; + // If we consumed a character and there might be a matched keyword that + // was marked matched on a previous iteration, then such keywords + // which are now marked as not matching. + if (n_might_match + n_does_match > 1) + { + st = status; + for (ForwardIterator ky = kb; ky != ke; ++ky, ++st) + { + if (*st == does_match && ky->size() != indx+1) + { + *st = doesnt_match; + --n_does_match; + } + } + } + } + } + // We've exited the loop because we hit eof and/or we have no more "might matches". + if (b == e) + err |= std::ios_base::eofbit; + // Return the first matching result + for (st = status; kb != ke; ++kb, ++st) + if (*st == does_match) + break; + if (kb == ke) + err |= std::ios_base::failbit; + return kb; +} +} +} +} +#endif // BOOST_CHRONO_DETAIL_SCAN_KEYWORD_HPP diff --git a/boost/chrono/detail/static_assert.hpp b/boost/chrono/detail/static_assert.hpp new file mode 100644 index 00000000..86151947 --- /dev/null +++ b/boost/chrono/detail/static_assert.hpp @@ -0,0 +1,30 @@ +// static_assert.hpp --------------------------------------------------------------// + +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + + +#ifndef BOOST_CHRONO_DETAIL_STATIC_ASSERT_HPP +#define BOOST_CHRONO_DETAIL_STATIC_ASSERT_HPP + +#include + +#ifndef BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) static_assert(CND,MSG) +#elif defined(BOOST_CHRONO_USES_STATIC_ASSERT) +#include +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) BOOST_STATIC_ASSERT(CND) +#elif defined(BOOST_CHRONO_USES_MPL_ASSERT) +#include +#include +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) \ + BOOST_MPL_ASSERT_MSG(boost::mpl::bool_< (CND) >::type::value, MSG, TYPES) +#else +//~ #elif defined(BOOST_CHRONO_USES_ARRAY_ASSERT) +#define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) static char BOOST_JOIN(boost_chrono_test_,__LINE__)[(CND)?1:-1] +//~ #define BOOST_CHRONO_STATIC_ASSERT(CND, MSG, TYPES) +#endif + +#endif // BOOST_CHRONO_DETAIL_STATIC_ASSERT_HPP diff --git a/boost/chrono/detail/system.hpp b/boost/chrono/detail/system.hpp new file mode 100644 index 00000000..ebe27aba --- /dev/null +++ b/boost/chrono/detail/system.hpp @@ -0,0 +1,19 @@ +// Copyright 2009-2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CHRONO_DETAIL_SYSTEM_HPP +#define BOOST_CHRONO_DETAIL_SYSTEM_HPP + +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + +#include + +#define BOOST_CHRONO_SYSTEM_CATEGORY boost::system::system_category() + +#define BOOST_CHRONO_THROWS boost::throws() +#define BOOST_CHRONO_IS_THROWS(EC) (&EC==&boost::throws()) + +#endif +#endif diff --git a/boost/chrono/duration.hpp b/boost/chrono/duration.hpp new file mode 100644 index 00000000..0a09674f --- /dev/null +++ b/boost/chrono/duration.hpp @@ -0,0 +1,798 @@ +// duration.hpp --------------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* + +This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. +Many thanks to Howard for making his code available under the Boost license. +The original code was modified to conform to Boost conventions and to section +20.9 Time utilities [time] of the C++ committee's working paper N2798. +See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. + +time2_demo contained this comment: + + Much thanks to Andrei Alexandrescu, + Walter Brown, + Peter Dimov, + Jeff Garland, + Terry Golubiewski, + Daniel Krugler, + Anthony Williams. +*/ + + +#ifndef BOOST_CHRONO_DURATION_HPP +#define BOOST_CHRONO_DURATION_HPP + +#include +#include + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || !defined(BOOST_CHRONO_USES_MPL_ASSERT) +#define BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION "A duration representation can not be a duration" +#define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO "Second template parameter of duration must be a boost::ratio" +#define BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE "duration period must be positive" +#define BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION "Second template parameter of time_point must be a boost::chrono::duration" +#endif + +#ifndef BOOST_CHRONO_HEADER_ONLY +// this must occur after all of the includes and before any code appears: +#include // must be the last #include +#endif + +//----------------------------------------------------------------------------// +// // +// 20.9 Time utilities [time] // +// synopsis // +// // +//----------------------------------------------------------------------------// + +namespace boost { +namespace chrono { + + template > + class duration; + + namespace detail + { + template + struct is_duration + : boost::false_type {}; + + template + struct is_duration > + : boost::true_type {}; + + template ::value> + struct duration_divide_result + { + }; + + template ::type>::value)) + && ((boost::is_convertible::type>::value)) + ) + > + struct duration_divide_imp + { + }; + + template + struct duration_divide_imp, Rep2, true> + { + typedef duration::type, Period> type; + }; + + template + struct duration_divide_result, Rep2, false> + : duration_divide_imp, Rep2> + { + }; + +/// + template ::value> + struct duration_divide_result2 + { + }; + + template ::type>::value)) + && ((boost::is_convertible::type>::value)) + ) + > + struct duration_divide_imp2 + { + }; + + template + struct duration_divide_imp2, true> + { + //typedef typename common_type::type type; + typedef double type; + }; + + template + struct duration_divide_result2, false> + : duration_divide_imp2 > + { + }; + +/// + template ::value> + struct duration_modulo_result + { + }; + + template ::type>::value + //&& + boost::is_convertible::type>::value + ) + > + struct duration_modulo_imp + { + }; + + template + struct duration_modulo_imp, Rep2, true> + { + typedef duration::type, Period> type; + }; + + template + struct duration_modulo_result, Rep2, false> + : duration_modulo_imp, Rep2> + { + }; + +} // namespace detail +} // namespace chrono + + +// common_type trait specializations + +template +struct common_type, + chrono::duration >; + + +namespace chrono { + + // customization traits + template struct treat_as_floating_point; + template struct duration_values; + + // convenience typedefs + typedef duration nanoseconds; // at least 64 bits needed + typedef duration microseconds; // at least 55 bits needed + typedef duration milliseconds; // at least 45 bits needed + typedef duration seconds; // at least 35 bits needed + typedef duration > minutes; // at least 29 bits needed + typedef duration > hours; // at least 23 bits needed + +//----------------------------------------------------------------------------// +// duration helpers // +//----------------------------------------------------------------------------// + +namespace detail +{ + + // duration_cast + + // duration_cast is the heart of this whole prototype. It can convert any + // duration to any other. It is also (implicitly) used in converting + // time_points. The conversion is always exact if possible. And it is + // always as efficient as hand written code. If different representations + // are involved, care is taken to never require implicit conversions. + // Instead static_cast is used explicitly for every required conversion. + // If there are a mixture of integral and floating point representations, + // the use of common_type ensures that the most logical "intermediate" + // representation is used. + template + struct duration_cast_aux; + + // When the two periods are the same, all that is left to do is static_cast from + // the source representation to the target representation (which may be a no-op). + // This conversion is always exact as long as the static_cast from the source + // representation to the destination representation is exact. + template + struct duration_cast_aux + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + return ToDuration(static_cast(fd.count())); + } + }; + + // When the numerator of FromPeriod / ToPeriod is 1, then all we need to do is + // divide by the denominator of FromPeriod / ToPeriod. The common_type of + // the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is generally not exact because of the division (but could be + // if you get lucky on the run time value of fd.count()). + template + struct duration_cast_aux + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + typedef typename common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast( + static_cast(fd.count()) / static_cast(Period::den))); + } + }; + + // When the denominator of FromPeriod / ToPeriod is 1, then all we need to do is + // multiply by the numerator of FromPeriod / ToPeriod. The common_type of + // the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is always exact as long as the static_cast's involved are exact. + template + struct duration_cast_aux + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + typedef typename common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast( + static_cast(fd.count()) * static_cast(Period::num))); + } + }; + + // When neither the numerator or denominator of FromPeriod / ToPeriod is 1, then we need to + // multiply by the numerator and divide by the denominator of FromPeriod / ToPeriod. The + // common_type of the two representations is used for the intermediate computation before + // static_cast'ing to the destination. + // This conversion is generally not exact because of the division (but could be + // if you get lucky on the run time value of fd.count()). + template + struct duration_cast_aux + { + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + typedef typename common_type< + typename ToDuration::rep, + typename FromDuration::rep, + boost::intmax_t>::type C; + return ToDuration(static_cast( + static_cast(fd.count()) * static_cast(Period::num) + / static_cast(Period::den))); + } + }; + + template + struct duration_cast { + typedef typename ratio_divide::type Period; + typedef duration_cast_aux< + FromDuration, + ToDuration, + Period, + Period::num == 1, + Period::den == 1 + > Aux; + BOOST_CONSTEXPR ToDuration operator()(const FromDuration& fd) const + { + return Aux()(fd); + } + }; + +} // namespace detail + +//----------------------------------------------------------------------------// +// // +// 20.9.2 Time-related traits [time.traits] // +// // +//----------------------------------------------------------------------------// +//----------------------------------------------------------------------------// +// 20.9.2.1 treat_as_floating_point [time.traits.is_fp] // +// Probably should have been treat_as_floating_point. Editor notifed. // +//----------------------------------------------------------------------------// + + // Support bidirectional (non-exact) conversions for floating point rep types + // (or user defined rep types which specialize treat_as_floating_point). + template + struct treat_as_floating_point : boost::is_floating_point {}; + +//----------------------------------------------------------------------------// +// 20.9.2.2 duration_values [time.traits.duration_values] // +//----------------------------------------------------------------------------// + +namespace detail { + template ::value> + struct chrono_numeric_limits { + static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits::min) ();} + }; + + template + struct chrono_numeric_limits { + static BOOST_CHRONO_LIB_CONSTEXPR T lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW {return (std::numeric_limits::min) ();} + }; + + template <> + struct chrono_numeric_limits { + static BOOST_CHRONO_LIB_CONSTEXPR float lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW + { + return -(std::numeric_limits::max) (); + } + }; + + template <> + struct chrono_numeric_limits { + static BOOST_CHRONO_LIB_CONSTEXPR double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW + { + return -(std::numeric_limits::max) (); + } + }; + + template <> + struct chrono_numeric_limits { + static BOOST_CHRONO_LIB_CONSTEXPR long double lowest() BOOST_CHRONO_LIB_NOEXCEPT_OR_THROW + { + return -(std::numeric_limits::max)(); + } + }; + + template + struct numeric_limits : chrono_numeric_limits::type> + {}; + +} +template +struct duration_values +{ + static BOOST_CONSTEXPR Rep zero() {return Rep(0);} + static BOOST_CHRONO_LIB_CONSTEXPR Rep max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (std::numeric_limits::max)(); + } + + static BOOST_CHRONO_LIB_CONSTEXPR Rep min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return detail::numeric_limits::lowest(); + } +}; + +} // namespace chrono + +//----------------------------------------------------------------------------// +// 20.9.2.3 Specializations of common_type [time.traits.specializations] // +//----------------------------------------------------------------------------// + +template +struct common_type, + chrono::duration > +{ + typedef chrono::duration::type, + typename boost::ratio_gcd::type> type; +}; + + +//----------------------------------------------------------------------------// +// // +// 20.9.3 Class template duration [time.duration] // +// // +//----------------------------------------------------------------------------// + + +namespace chrono { + + template + class BOOST_SYMBOL_VISIBLE duration + { + //BOOST_CHRONO_STATIC_ASSERT(boost::is_integral::value, BOOST_CHRONO_A_DURATION_REPRESENTATION_MUST_BE_INTEGRAL, ()); + BOOST_CHRONO_STATIC_ASSERT(!boost::chrono::detail::is_duration::value, + BOOST_CHRONO_A_DURATION_REPRESENTATION_CAN_NOT_BE_A_DURATION, ()); + BOOST_CHRONO_STATIC_ASSERT(boost::ratio_detail::is_ratio::value, + BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_DURATION_MUST_BE_A_STD_RATIO, ()); + BOOST_CHRONO_STATIC_ASSERT(Period::num>0, + BOOST_CHRONO_DURATION_PERIOD_MUST_BE_POSITIVE, ()); + public: + typedef Rep rep; + typedef Period period; + private: + rep rep_; + public: + +#if defined BOOST_CHRONO_DURATION_DEFAULTS_TO_ZERO + BOOST_FORCEINLINE BOOST_CONSTEXPR + duration() : rep_(duration_values::zero()) { } +#elif defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + BOOST_CONSTEXPR duration() {} +#else + BOOST_CONSTEXPR duration() = default; +#endif + template + BOOST_SYMBOL_VISIBLE BOOST_FORCEINLINE BOOST_CONSTEXPR + explicit duration(const Rep2& r + , typename boost::enable_if < + mpl::and_ < + boost::is_convertible, + mpl::or_ < + treat_as_floating_point, + mpl::and_ < + mpl::not_ < treat_as_floating_point >, + mpl::not_ < treat_as_floating_point > + > + > + > + >::type* = 0 + ) : rep_(r) { } +#if defined BOOST_NO_CXX11_DEFAULTED_FUNCTIONS + duration& operator=(const duration& rhs) + { + if (&rhs != this) rep_= rhs.rep_; + return *this; + } +#else + duration& operator=(const duration& rhs) = default; +#endif + // conversions + template + BOOST_FORCEINLINE BOOST_CONSTEXPR + duration(const duration& d + , typename boost::enable_if < + mpl::or_ < + treat_as_floating_point, + mpl::and_ < + chrono_detail::is_evenly_divisible_by, + mpl::not_ < treat_as_floating_point > + > + > + >::type* = 0 + ) + : rep_(chrono::detail::duration_cast, duration>()(d).count()) {} + + // observer + + BOOST_CONSTEXPR + rep count() const {return rep_;} + + // arithmetic + + BOOST_CONSTEXPR + duration operator+() const {return duration(rep_);;} + BOOST_CONSTEXPR + duration operator-() const {return duration(-rep_);} + duration& operator++() {++rep_; return *this;} + duration operator++(int) {return duration(rep_++);} + duration& operator--() {--rep_; return *this;} + duration operator--(int) {return duration(rep_--);} + + duration& operator+=(const duration& d) + { + rep_ += d.count(); return *this; + } + duration& operator-=(const duration& d) + { + rep_ -= d.count(); return *this; + } + + duration& operator*=(const rep& rhs) {rep_ *= rhs; return *this;} + duration& operator/=(const rep& rhs) {rep_ /= rhs; return *this;} + duration& operator%=(const rep& rhs) {rep_ %= rhs; return *this;} + duration& operator%=(const duration& rhs) + { + rep_ %= rhs.count(); return *this; + } + // 20.9.3.4 duration special values [time.duration.special] + + static BOOST_CONSTEXPR duration zero() + { + return duration(duration_values::zero()); + } + static BOOST_CHRONO_LIB_CONSTEXPR duration min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return duration((duration_values::min)()); + } + static BOOST_CHRONO_LIB_CONSTEXPR duration max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return duration((duration_values::max)()); + } + }; + +//----------------------------------------------------------------------------// +// 20.9.3.5 duration non-member arithmetic [time.duration.nonmember] // +//----------------------------------------------------------------------------// + + // Duration + + + template + inline BOOST_CONSTEXPR + typename common_type, duration >::type + operator+(const duration& lhs, + const duration& rhs) + { + typedef typename common_type, + duration >::type common_duration; + return common_duration(common_duration(lhs).count()+common_duration(rhs).count()); + } + + // Duration - + + template + inline BOOST_CONSTEXPR + typename common_type, duration >::type + operator-(const duration& lhs, + const duration& rhs) + { + typedef typename common_type, + duration >::type common_duration; + return common_duration(common_duration(lhs).count()-common_duration(rhs).count()); + } + + // Duration * + + template + inline BOOST_CONSTEXPR + typename boost::enable_if < + mpl::and_ < + boost::is_convertible::type>, + boost::is_convertible::type> + >, + duration::type, Period> + >::type + operator*(const duration& d, const Rep2& s) + { + typedef typename common_type::type common_rep; + typedef duration common_duration; + return common_duration(common_duration(d).count()*static_cast(s)); + } + + template + inline BOOST_CONSTEXPR + typename boost::enable_if < + mpl::and_ < + boost::is_convertible::type>, + boost::is_convertible::type> + >, + duration::type, Period> + >::type + operator*(const Rep1& s, const duration& d) + { + return d * s; + } + + // Duration / + + template + inline BOOST_CONSTEXPR + typename boost::disable_if , + typename boost::chrono::detail::duration_divide_result< + duration, Rep2>::type + >::type + operator/(const duration& d, const Rep2& s) + { + typedef typename common_type::type common_rep; + typedef duration common_duration; + return common_duration(common_duration(d).count()/static_cast(s)); + } + + template + inline BOOST_CONSTEXPR + typename common_type::type + operator/(const duration& lhs, const duration& rhs) + { + typedef typename common_type, + duration >::type common_duration; + return common_duration(lhs).count() / common_duration(rhs).count(); + } + + #ifdef BOOST_CHRONO_EXTENSIONS + template + inline BOOST_CONSTEXPR + typename boost::disable_if , + typename boost::chrono::detail::duration_divide_result2< + Rep1, duration >::type + >::type + operator/(const Rep1& s, const duration& d) + { + typedef typename common_type::type common_rep; + typedef duration common_duration; + return static_cast(s)/common_duration(d).count(); + } + #endif + // Duration % + + template + inline BOOST_CONSTEXPR + typename boost::disable_if , + typename boost::chrono::detail::duration_modulo_result< + duration, Rep2>::type + >::type + operator%(const duration& d, const Rep2& s) + { + typedef typename common_type::type common_rep; + typedef duration common_duration; + return common_duration(common_duration(d).count()%static_cast(s)); + } + + template + inline BOOST_CONSTEXPR + typename common_type, duration >::type + operator%(const duration& lhs, + const duration& rhs) { + typedef typename common_type, + duration >::type common_duration; + + return common_duration(common_duration(lhs).count()%common_duration(rhs).count()); + } + + +//----------------------------------------------------------------------------// +// 20.9.3.6 duration comparisons [time.duration.comparisons] // +//----------------------------------------------------------------------------// + +namespace detail +{ + template + struct duration_eq + { + BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const + { + typedef typename common_type::type common_duration; + return common_duration(lhs).count() == common_duration(rhs).count(); + } + }; + + template + struct duration_eq + { + BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const + { + return lhs.count() == rhs.count(); + } + }; + + template + struct duration_lt + { + BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const RhsDuration& rhs) const + { + typedef typename common_type::type common_duration; + return common_duration(lhs).count() < common_duration(rhs).count(); + } + }; + + template + struct duration_lt + { + BOOST_CONSTEXPR bool operator()(const LhsDuration& lhs, const LhsDuration& rhs) const + { + return lhs.count() < rhs.count(); + } + }; + +} // namespace detail + + // Duration == + + template + inline BOOST_CONSTEXPR + bool + operator==(const duration& lhs, + const duration& rhs) + { + return boost::chrono::detail::duration_eq< + duration, duration >()(lhs, rhs); + } + + // Duration != + + template + inline BOOST_CONSTEXPR + bool + operator!=(const duration& lhs, + const duration& rhs) + { + return !(lhs == rhs); + } + + // Duration < + + template + inline BOOST_CONSTEXPR + bool + operator< (const duration& lhs, + const duration& rhs) + { + return boost::chrono::detail::duration_lt< + duration, duration >()(lhs, rhs); + } + + // Duration > + + template + inline BOOST_CONSTEXPR + bool + operator> (const duration& lhs, + const duration& rhs) + { + return rhs < lhs; + } + + // Duration <= + + template + inline BOOST_CONSTEXPR + bool + operator<=(const duration& lhs, + const duration& rhs) + { + return !(rhs < lhs); + } + + // Duration >= + + template + inline BOOST_CONSTEXPR + bool + operator>=(const duration& lhs, + const duration& rhs) + { + return !(lhs < rhs); + } + +//----------------------------------------------------------------------------// +// 20.9.3.7 duration_cast [time.duration.cast] // +//----------------------------------------------------------------------------// + + // Compile-time select the most efficient algorithm for the conversion... + template + inline BOOST_CONSTEXPR + typename boost::enable_if < + boost::chrono::detail::is_duration, ToDuration>::type + duration_cast(const duration& fd) + { + return boost::chrono::detail::duration_cast< + duration, ToDuration>()(fd); + } + +} // namespace chrono +} // namespace boost + +#ifndef BOOST_CHRONO_HEADER_ONLY +// the suffix header occurs after all of our code: +#include // pops abi_prefix.hpp pragmas +#endif + +#endif // BOOST_CHRONO_DURATION_HPP diff --git a/boost/chrono/floor.hpp b/boost/chrono/floor.hpp new file mode 100644 index 00000000..eb85fa74 --- /dev/null +++ b/boost/chrono/floor.hpp @@ -0,0 +1,36 @@ +// boost/chrono/round.hpp ------------------------------------------------------------// + +// (C) Copyright Howard Hinnant +// Copyright 2011 Vicente J. Botet Escriba + +// 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/chrono for documentation. + +#ifndef BOOST_CHRONO_FLOOR_HPP +#define BOOST_CHRONO_FLOOR_HPP + +#include + +namespace boost +{ + namespace chrono + { + + /** + * rounds down + */ + template + To floor(const duration& d) + { + To t = duration_cast(d); + if (t>d) --t; + return t; + } + + + } // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/include.hpp b/boost/chrono/include.hpp new file mode 100644 index 00000000..b58f76be --- /dev/null +++ b/boost/chrono/include.hpp @@ -0,0 +1,23 @@ + +// include +// +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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 code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o under lvm/libc++ to Boost + +#ifndef BOOST_CHRONO_INCLUDE_HPP +#define BOOST_CHRONO_INCLUDE_HPP + +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_CHRONO_INCLUDE_HPP diff --git a/boost/chrono/io/duration_get.hpp b/boost/chrono/io/duration_get.hpp new file mode 100644 index 00000000..081f0710 --- /dev/null +++ b/boost/chrono/io/duration_get.hpp @@ -0,0 +1,591 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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_CHRONO_IO_DURATION_GET_HPP +#define BOOST_CHRONO_IO_DURATION_GET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + * Duration formatting facet for input. + */ +namespace boost +{ + namespace chrono + { + + namespace detail + { + template ::value> + struct duration_io_intermediate + { + typedef Rep type; + }; + + template + struct duration_io_intermediate + { + typedef typename mpl::if_c::value, long double, typename mpl::if_c< + is_signed::value, long long, unsigned long long>::type>::type type; + }; + + template + struct duration_io_intermediate, false> + { + typedef process_times::type> type; + }; + + template + typename enable_if , bool>::type reduce(intermediate_type& r, + unsigned long long& den, std::ios_base::iostate& err) + { + typedef typename common_type::type common_type_t; + + // Reduce r * num / den + common_type_t t = integer::gcd(common_type_t(r), common_type_t(den)); + r /= t; + den /= t; + if (den != 1) + { + // Conversion to Period is integral and not exact + err |= std::ios_base::failbit; + return false; + } + return true; + } + template + typename disable_if , bool>::type reduce(intermediate_type&, unsigned long long&, + std::ios_base::iostate&) + { + return true; + } + + } + + /** + * @c duration_get is used to parse a character sequence, extracting + * components of a duration into a class duration. + * Each get member parses a format as produced by a corresponding format specifier to time_put<>::put. + * If the sequence being parsed matches the correct format, the + * corresponding member of the class duration argument are set to the + * value used to produce the sequence; + * otherwise either an error is reported or unspecified values are assigned. + * In other words, user confirmation is required for reliable parsing of + * user-entered durations, but machine-generated formats can be parsed + * reliably. This allows parsers to be aggressive about interpreting user + * variations on standard formats. + * + * If the end iterator is reached during parsing of the get() member + * function, the member sets std::ios_base::eofbit in err. + */ + template > + class duration_get: public std::locale::facet + { + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of character string passed to member functions. + */ + typedef std::basic_string string_type; + /** + * Type of iterator used to scan the character buffer. + */ + typedef InputIterator iter_type; + + /** + * Construct a @c duration_get facet. + * @param refs + * @Effects Construct a @c duration_get facet. + * If the @c refs argument is @c 0 then destruction of the object is + * delegated to the @c locale, or locales, containing it. This allows + * the user to ignore lifetime management issues. On the other had, + * if @c refs is @c 1 then the object must be explicitly deleted; + * the @c locale will not do so. In this case, the object can be + * maintained across the lifetime of multiple locales. + */ + + explicit duration_get(size_t refs = 0) : + std::locale::facet(refs) + { + } + + /** + * @param s start input stream iterator + * @param end end input stream iterator + * @param ios a reference to a ios_base + * @param err the ios_base state + * @param d the duration + * @param pattern begin of the formatting pattern + * @param pat_end end of the formatting pattern + * + * Requires: [pattern,pat_end) shall be a valid range. + * + * Effects: The function starts by evaluating err = std::ios_base::goodbit. + * It then enters a loop, reading zero or more characters from s at + * each iteration. Unless otherwise specified below, the loop + * terminates when the first of the following conditions holds: + * - The expression pattern == pat_end evaluates to true. + * - The expression err == std::ios_base::goodbit evaluates to false. + * - The expression s == end evaluates to true, in which case the + * function evaluates err = std::ios_base::eofbit | std::ios_base::failbit. + * - The next element of pattern is equal to '%', followed by a conversion + * specifier character, format. + * If the number of elements in the range [pattern,pat_end) is not + * sufficient to unambiguously determine whether the conversion + * specification is complete and valid, the function evaluates + * err = std::ios_base::failbit. Otherwise, the function evaluates + * s = get_value(s, end, ios, err, r) when the conversion specification is 'v' and + * s = get_value(s, end, ios, err, rt) when the conversion specification is 'u'. + * If err == std::ios_base::goodbit holds after + * the evaluation of the expression, the function increments pattern to + * point just past the end of the conversion specification and continues + * looping. + * - The expression isspace(*pattern, ios.getloc()) evaluates to true, in + * which case the function first increments pattern until + * pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true, + * then advances s until s == end || !isspace(*s, ios.getloc()) is true, + * and finally resumes looping. + * - The next character read from s matches the element pointed to by + * pattern in a case-insensitive comparison, in which case the function + * evaluates ++pattern, ++s and continues looping. Otherwise, the function + * evaluates err = std::ios_base::failbit. + * + * Once r and rt are retrieved, + * Returns: s + */ + template + iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, + duration &d, const char_type *pattern, const char_type *pat_end) const + { + if (std::has_facet >(ios.getloc())) + { + duration_units const&facet = std::use_facet >(ios.getloc()); + return get(facet, s, end, ios, err, d, pattern, pat_end); + } + else + { + duration_units_default facet; + return get(facet, s, end, ios, err, d, pattern, pat_end); + } + } + + template + iter_type get(duration_units const&facet, iter_type s, iter_type end, std::ios_base& ios, + std::ios_base::iostate& err, duration &d, const char_type *pattern, const char_type *pat_end) const + { + + typedef typename detail::duration_io_intermediate::type intermediate_type; + intermediate_type r; + rt_ratio rt; + bool value_found = false, unit_found = false; + + const std::ctype& ct = std::use_facet >(ios.getloc()); + while (pattern != pat_end && err == std::ios_base::goodbit) + { + if (s == end) + { + err |= std::ios_base::eofbit; + break; + } + if (ct.narrow(*pattern, 0) == '%') + { + if (++pattern == pat_end) + { + err |= std::ios_base::failbit; + return s; + } + char cmd = ct.narrow(*pattern, 0); + switch (cmd) + { + case 'v': + { + if (value_found) + { + err |= std::ios_base::failbit; + return s; + } + value_found = true; + s = get_value(s, end, ios, err, r); + if (err & (std::ios_base::badbit | std::ios_base::failbit)) + { + return s; + } + break; + } + case 'u': + { + if (unit_found) + { + err |= std::ios_base::failbit; + return s; + } + unit_found = true; + s = get_unit(facet, s, end, ios, err, rt); + if (err & (std::ios_base::badbit | std::ios_base::failbit)) + { + return s; + } + break; + } + default: + BOOST_ASSERT(false && "Boost::Chrono internal error."); + break; + } + + ++pattern; + } + else if (ct.is(std::ctype_base::space, *pattern)) + { + for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern) + ; + for (; s != end && ct.is(std::ctype_base::space, *s); ++s) + ; + } + else if (ct.toupper(*s) == ct.toupper(*pattern)) + { + ++s; + ++pattern; + } + else + { + err |= std::ios_base::failbit; + return s; + } + + } + + unsigned long long num = rt.num; + unsigned long long den = rt.den; + + // r should be multiplied by (num/den) / Period + // Reduce (num/den) / Period to lowest terms + unsigned long long gcd_n1_n2 = integer::gcd(num, Period::num); + unsigned long long gcd_d1_d2 = integer::gcd(den, Period::den); + num /= gcd_n1_n2; + den /= gcd_d1_d2; + unsigned long long n2 = Period::num / gcd_n1_n2; + unsigned long long d2 = Period::den / gcd_d1_d2; + if (num > (std::numeric_limits::max)() / d2 || den + > (std::numeric_limits::max)() / n2) + { + // (num/den) / Period overflows + err |= std::ios_base::failbit; + return s; + } + num *= d2; + den *= n2; + + typedef typename common_type::type common_type_t; + + // num / den is now factor to multiply by r + if (!detail::reduce(r, den, err)) return s; + + if (chrono::detail::gt(r, ( (duration_values::max)() / num))) + { + // Conversion to Period overflowed + err |= std::ios_base::failbit; + return s; + } + common_type_t t = r * num; + t /= den; + if (t > duration_values::zero()) + { + if ( (duration_values::max)() < Rep(t)) + { + // Conversion to Period overflowed + err |= std::ios_base::failbit; + return s; + } + } + // Success! Store it. + d = duration (Rep(t)); + + return s; + } + + /** + * + * @param s start input stream iterator + * @param end end input stream iterator + * @param ios a reference to a ios_base + * @param err the ios_base state + * @param d the duration + * Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if + * @code + * return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size()); + * @codeend + * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name + */ + template + iter_type get(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, + duration & d) const + { + if (std::has_facet >(ios.getloc())) + { + duration_units const&facet = std::use_facet >(ios.getloc()); + std::basic_string str = facet.get_pattern(); + return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size()); + } + else + { + duration_units_default facet; + std::basic_string str = facet.get_pattern(); + return get(facet, s, end, ios, err, d, str.data(), str.data() + str.size()); + } + } + + /** + * + * @param s start input stream iterator + * @param end end input stream iterator + * @param ios a reference to a ios_base + * @param err the ios_base state + * @param r a reference to the duration representation. + * @Effects As if + * @code + * return std::use_facet >(ios.getloc()).get(s, end, ios, err, r); + * @endcode + * + * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name + */ + template + iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, Rep& r) const + { + return std::use_facet >(ios.getloc()).get(s, end, ios, err, r); + } + template + iter_type get_value(iter_type s, iter_type end, std::ios_base& ios, std::ios_base::iostate& err, process_times& r) const + { + if (s == end) { + err |= std::ios_base::eofbit; + return s; + } else if (*s != '{') { // mandatory '{' + err |= std::ios_base::failbit; + return s; + } + ++s; + s = std::use_facet >(ios.getloc()).get(s, end, ios, err, r.real); + if (s == end) { + err |= std::ios_base::eofbit; + return s; + } else if (*s != ';') { // mandatory ';' + err |= std::ios_base::failbit; + return s; + } + ++s; + s = std::use_facet >(ios.getloc()).get(s, end, ios, err, r.user); + if (s == end) { + err |= std::ios_base::eofbit; + return s; + } else if (*s != ';') { // mandatory ';' + err |= std::ios_base::failbit; + return s; + } + ++s; + s = std::use_facet >(ios.getloc()).get(s, end, ios, err, r.system); + if (s == end) { + err |= std::ios_base::eofbit; + return s; + } else if (*s != '}') { // mandatory '}' + err |= std::ios_base::failbit; + return s; + } + return s; + } + + /** + * + * @param s start input stream iterator + * @param e end input stream iterator + * @param ios a reference to a ios_base + * @param err the ios_base state + * @param rt a reference to the duration run-time ratio. + * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name + */ + iter_type get_unit(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err, rt_ratio &rt) const + { + if (std::has_facet >(is.getloc())) + { + return get_unit(std::use_facet >(is.getloc()), i, e, is, err, rt); + } + else + { + duration_units_default facet; + return get_unit(facet, i, e, is, err, rt); + } + } + + + iter_type get_unit(duration_units const &facet, iter_type i, iter_type e, std::ios_base& is, + std::ios_base::iostate& err, rt_ratio &rt) const + { + + if (*i == '[') + { + // parse [N/D]s or [N/D]second or [N/D]seconds format + ++i; + i = std::use_facet >(is.getloc()).get(i, e, is, err, rt.num); + if ( (err & std::ios_base::failbit) != 0) + { + return i; + } + + if (i == e) + { + err |= std::ios_base::failbit; + return i; + } + CharT x = *i++; + if (x != '/') + { + err |= std::ios_base::failbit; + return i; + } + i = std::use_facet >(is.getloc()).get(i, e, is, err, rt.den); + if ( (err & std::ios_base::failbit) != 0) + { + return i; + } + if (i == e) + { + err |= std::ios_base::failbit; + return i; + } + if (*i != ']') + { + err |= std::ios_base::failbit; + return i; + } + ++i; + if (i == e) + { + err |= std::ios_base::failbit; + return i; + } + // parse s or second or seconds + return do_get_n_d_valid_unit(facet, i, e, is, err); + } + else + { + return do_get_valid_unit(facet, i, e, is, err, rt); + } + } + + /** + * Unique identifier for this type of facet. + */ + static std::locale::id id; + + /** + * @Effects Destroy the facet + */ + ~duration_get() + { + } + + protected: + + /** + * Extracts the run-time ratio associated to the duration when it is given in prefix form. + * + * This is an extension point of this facet so that we can take in account other periods that can have a useful + * translation in other contexts, as e.g. days and weeks. + * + * @param facet the duration_units facet + * @param i start input stream iterator. + * @param e end input stream iterator. + * @param ios a reference to a ios_base. + * @param err the ios_base state. + * @return @c s + */ + iter_type do_get_n_d_valid_unit(duration_units const &facet, iter_type i, iter_type e, + std::ios_base&, std::ios_base::iostate& err) const + { + // parse SI name, short or long + + const string_type* units = facet.get_n_d_valid_units_start(); + const string_type* units_end = facet.get_n_d_valid_units_end(); + + const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end, + //~ std::use_facet >(loc), + err); + if (err & (std::ios_base::badbit | std::ios_base::failbit)) + { + return i; + } + if (!facet.match_n_d_valid_unit(k)) + { + err |= std::ios_base::failbit; + } + return i; + } + + /** + * Extracts the run-time ratio associated to the duration when it is given in prefix form. + * + * This is an extension point of this facet so that we can take in account other periods that can have a useful + * translation in other contexts, as e.g. days and weeks. + * + * @param facet the duration_units facet + * @param i start input stream iterator. + * @param e end input stream iterator. + * @param ios a reference to a ios_base. + * @param err the ios_base state. + * @param rt a reference to the duration run-time ratio. + * @Effects + * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name. + */ + iter_type do_get_valid_unit(duration_units const &facet, iter_type i, iter_type e, + std::ios_base&, std::ios_base::iostate& err, rt_ratio &rt) const + { + // parse SI name, short or long + + const string_type* units = facet.get_valid_units_start(); + const string_type* units_end = facet.get_valid_units_end(); + + err = std::ios_base::goodbit; + const string_type* k = chrono_detail::scan_keyword(i, e, units, units_end, + //~ std::use_facet >(loc), + err); + if (err & (std::ios_base::badbit | std::ios_base::failbit)) + { + return i; + } + if (!facet.match_valid_unit(k, rt)) + { + err |= std::ios_base::failbit; + } + return i; + } + }; + + /** + * Unique identifier for this type of facet. + */ + template + std::locale::id duration_get::id; + + } // chrono +} +// boost + +#endif // header diff --git a/boost/chrono/io/duration_io.hpp b/boost/chrono/io/duration_io.hpp new file mode 100644 index 00000000..f3aca6ad --- /dev/null +++ b/boost/chrono/io/duration_io.hpp @@ -0,0 +1,295 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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 code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o to Boost + +#ifndef BOOST_CHRONO_IO_DURATION_IO_HPP +#define BOOST_CHRONO_IO_DURATION_IO_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace chrono + { + + /** + * duration parameterized manipulator. + */ + + class duration_fmt: public manip + { + duration_style style_; + public: + + /** + * explicit manipulator constructor from a @c duration_style + */ + explicit duration_fmt(duration_style style)BOOST_NOEXCEPT + : style_(style) + {} + + /** + * Change the duration_style ios state; + */ + void operator()(std::ios_base &ios) const + + { + set_duration_style(ios, style_); + } + }; + + /** + * duration_style i/o saver. + * + * See Boost.IO i/o state savers for a motivating compression. + */ + struct duration_style_io_saver + { + + //! the type of the state to restore + typedef std::ios_base state_type; + //! the type of aspect to save + typedef duration_style aspect_type; + + /** + * Explicit construction from an i/o stream. + * + * Store a reference to the i/o stream and the value of the associated @c duration_style. + */ + explicit duration_style_io_saver(state_type &s) : + s_save_(s), a_save_(get_duration_style(s)) + { + } + + /** + * Construction from an i/o stream and a @c duration_style to restore. + * + * Stores a reference to the i/o stream and the value @c new_value @c duration_style to set. + */ + duration_style_io_saver(state_type &s, aspect_type new_value) : + s_save_(s), a_save_(get_duration_style(s)) + { + set_duration_style(s, new_value); + } + + /** + * Destructor. + * + * Restores the i/o stream with the duration_style to be restored. + */ + ~duration_style_io_saver() + { + this->restore(); + } + + /** + * Restores the i/o stream with the duration_style to be restored. + */ + void restore() + { + set_duration_style(s_save_, a_save_); + } + + private: + duration_style_io_saver& operator=(duration_style_io_saver const& rhs) ; + + state_type& s_save_; + aspect_type a_save_; + }; + + template + struct duration_put_enabled + : integral_constant::value || is_floating_point::value + > + {}; + + + /** + * duration stream inserter + * @param os the output stream + * @param d to value to insert + * @return @c os + */ + + template + typename boost::enable_if_c< ! duration_put_enabled::value, std::basic_ostream& >::type + operator<<(std::basic_ostream& os, const duration& d) + { + std::basic_ostringstream ostr; + ostr << d.count(); + duration dd(0); + bool failed = false; + BOOST_TRY + { + std::ios_base::iostate err = std::ios_base::goodbit; + BOOST_TRY + { + typename std::basic_ostream::sentry opfx(os); + if (bool(opfx)) + { + if (!std::has_facet >(os.getloc())) + { + if (duration_put ().put(os, os, os.fill(), dd, ostr.str().c_str()) .failed()) + { + err = std::ios_base::badbit; + } + } + else if (std::use_facet >(os.getloc()) .put(os, os, os.fill(), dd, ostr.str().c_str()) .failed()) + { + err = std::ios_base::badbit; + } + os.width(0); + } + } + BOOST_CATCH(...) + { + bool flag = false; + BOOST_TRY + { + os.setstate(std::ios_base::failbit); + } + BOOST_CATCH (std::ios_base::failure ) + { + flag = true; + } + BOOST_CATCH_END + if (flag) throw; + } + BOOST_CATCH_END + if (err) os.setstate(err); + return os; + } + BOOST_CATCH(...) + { + failed = true; + } + BOOST_CATCH_END + if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit); + return os; + + } + + template + typename boost::enable_if_c< duration_put_enabled::value, std::basic_ostream& >::type + operator<<(std::basic_ostream& os, const duration& d) + { + bool failed = false; + BOOST_TRY + { + std::ios_base::iostate err = std::ios_base::goodbit; + BOOST_TRY + { + typename std::basic_ostream::sentry opfx(os); + if (bool(opfx)) + { + if (!std::has_facet >(os.getloc())) + { + if (duration_put ().put(os, os, os.fill(), d) .failed()) + { + err = std::ios_base::badbit; + } + } + else if (std::use_facet >(os.getloc()) .put(os, os, os.fill(), d) .failed()) + { + err = std::ios_base::badbit; + } + os.width(0); + } + } + BOOST_CATCH(...) + { + bool flag = false; + BOOST_TRY + { + os.setstate(std::ios_base::failbit); + } + BOOST_CATCH (std::ios_base::failure ) + { + flag = true; + } + BOOST_CATCH_END + if (flag) throw; + } + BOOST_CATCH_END + if (err) os.setstate(err); + return os; + } + BOOST_CATCH(...) + { + failed = true; + } + BOOST_CATCH_END + if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit); + return os; + } + + /** + * + * @param is the input stream + * @param d the duration + * @return @c is + */ + template + std::basic_istream& + operator>>(std::basic_istream& is, duration& d) + { + std::ios_base::iostate err = std::ios_base::goodbit; + + BOOST_TRY + { + typename std::basic_istream::sentry ipfx(is); + if (bool(ipfx)) + { + if (!std::has_facet >(is.getloc())) + { + duration_get ().get(is, std::istreambuf_iterator(), is, err, d); + } + else + { + std::use_facet >(is.getloc()) .get(is, std::istreambuf_iterator(), is, + err, d); + } + } + } + BOOST_CATCH (...) + { + bool flag = false; + BOOST_TRY + { + is.setstate(std::ios_base::failbit); + } + BOOST_CATCH (std::ios_base::failure ) + { + flag = true; + } + BOOST_CATCH_END + if (flag) { BOOST_RETHROW } + } + BOOST_CATCH_END + if (err) is.setstate(err); + return is; + } + + } // chrono + +} + +#endif // header diff --git a/boost/chrono/io/duration_put.hpp b/boost/chrono/io/duration_put.hpp new file mode 100644 index 00000000..623eae1b --- /dev/null +++ b/boost/chrono/io/duration_put.hpp @@ -0,0 +1,317 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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). +// + +/** + * Duration formatting facet for output. + */ +#ifndef BOOST_CHRONO_IO_DURATION_PUT_HPP +#define BOOST_CHRONO_IO_DURATION_PUT_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace chrono + { + + namespace detail + { + template + struct propagate { + typedef T type; + }; + template <> + struct propagate { + typedef boost::int_least64_t type; + }; + } + /** + * @tparam ChatT a character type + * @tparam OutputIterator a model of @c OutputIterator + * + * The @c duration_put facet provides facilities for formatted output of duration values. + * The member function of @c duration_put take a duration and format it into character string representation. + * + */ + template > + class duration_put: public std::locale::facet + { + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of character string passed to member functions. + */ + typedef std::basic_string string_type; + /** + * Type of iterator used to write in the character buffer. + */ + typedef OutputIterator iter_type; + + /** + * Construct a duration_put facet. + * @param refs + * @Effects Construct a duration_put facet. + * If the @c refs argument is @c 0 then destruction of the object is + * delegated to the @c locale, or locales, containing it. This allows + * the user to ignore lifetime management issues. On the other had, + * if @c refs is @c 1 then the object must be explicitly deleted; + * the @c locale will not do so. In this case, the object can be + * maintained across the lifetime of multiple locales. + */ + explicit duration_put(size_t refs = 0) : + std::locale::facet(refs) + { + } + + /** + * + * @param s an output stream iterator + * @param ios a reference to a ios_base + * @param fill the character used as filler + * @param d the duration + * @param pattern begin of the formatting pattern + * @param pat_end end of the formatting pattern + * + * @Effects Steps through the sequence from @c pattern to @c pat_end, + * identifying characters that are part of a pattern sequence. Each character + * that is not part of a pattern sequence is written to @c s immediately, and + * each pattern sequence, as it is identified, results in a call to + * @c put_value or @c put_unit; + * thus, pattern elements and other characters are interleaved in the output + * in the order in which they appear in the pattern. Pattern sequences are + * identified by converting each character @c c to a @c char value as if by + * @c ct.narrow(c,0), where @c ct is a reference to @c ctype obtained from + * @c ios.getloc(). The first character of each sequence is equal to @c '%', + * followed by a pattern specifier character @c spec, which can be @c 'v' for + * the duration value or @c 'u' for the duration unit. . + * For each valid pattern sequence identified, calls + * put_value(s, ios, fill, d) or put_unit(s, ios, fill, d). + * + * @Returns An iterator pointing immediately after the last character produced. + */ + template + iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration const& d, const CharT* pattern, + const CharT* pat_end, const char_type* val = 0) const + { + if (std::has_facet >(ios.getloc())) + { + duration_units const&facet = std::use_facet >( + ios.getloc()); + return put(facet, s, ios, fill, d, pattern, pat_end, val); + } + else + { + duration_units_default facet; + return put(facet, s, ios, fill, d, pattern, pat_end, val); + } + } + + template + iter_type put(duration_units const& units_facet, iter_type s, std::ios_base& ios, char_type fill, + duration const& d, const CharT* pattern, const CharT* pat_end, const char_type* val = 0) const + { + + const std::ctype& ct = std::use_facet >(ios.getloc()); + for (; pattern != pat_end; ++pattern) + { + if (ct.narrow(*pattern, 0) == '%') + { + if (++pattern == pat_end) + { + *s++ = pattern[-1]; + break; + } + char fmt = ct.narrow(*pattern, 0); + switch (fmt) + { + case 'v': + { + s = put_value(s, ios, fill, d, val); + break; + } + case 'u': + { + s = put_unit(units_facet, s, ios, fill, d); + break; + } + default: + BOOST_ASSERT(false && "Boost::Chrono internal error."); + break; + } + } + else + *s++ = *pattern; + } + return s; + } + + /** + * + * @param s an output stream iterator + * @param ios a reference to a ios_base + * @param fill the character used as filler + * @param d the duration + * @Effects imbue in @c ios the @c duration_units_default facet if not already present. + * Retrieves Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if + * @code + * return put(s, ios, d, str.data(), str.data() + str.size()); + * @endcode + * @Returns An iterator pointing immediately after the last character produced. + */ + template + iter_type put(iter_type s, std::ios_base& ios, char_type fill, duration const& d, const char_type* val = 0) const + { + if (std::has_facet >(ios.getloc())) + { + duration_units const&facet = std::use_facet >( + ios.getloc()); + std::basic_string str = facet.get_pattern(); + return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val); + } + else + { + duration_units_default facet; + std::basic_string str = facet.get_pattern(); + + return put(facet, s, ios, fill, d, str.data(), str.data() + str.size(), val); + } + } + + /** + * + * @param s an output stream iterator + * @param ios a reference to a ios_base + * @param fill the character used as filler + * @param d the duration + * @Effects As if s=std::use_facet >(ios.getloc()).put(s, ios, fill, static_cast (d.count())). + * @Returns s, iterator pointing immediately after the last character produced. + */ + template + iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration const& d, const char_type* val = 0) const + { + if (val) + { + while (*val) { + *s = *val; + s++; val++; + } + return s; + } + return std::use_facet >(ios.getloc()).put(s, ios, fill, + static_cast::type> (d.count())); + } + + template + iter_type put_value(iter_type s, std::ios_base& ios, char_type fill, duration, Period> const& d, const char_type* = 0) const + { + *s++ = CharT('{'); + s = put_value(s, ios, fill, process_real_cpu_clock::duration(d.count().real)); + *s++ = CharT(';'); + s = put_value(s, ios, fill, process_user_cpu_clock::duration(d.count().user)); + *s++ = CharT(';'); + s = put_value(s, ios, fill, process_system_cpu_clock::duration(d.count().system)); + *s++ = CharT('}'); + return s; + } + + /** + * + * @param s an output stream iterator + * @param ios a reference to a ios_base + * @param fill the character used as filler + * @param d the duration + * @Effects Let facet be the duration_units facet associated to ios. If the associated unit is named, + * as if + * @code + string_type str = facet.get_unit(get_duration_style(ios), d); + s=std::copy(str.begin(), str.end(), s); + * @endcode + * Otherwise, format the unit as "[Period::num/Period::den]" followed by the unit associated to [N/D] obtained using facet.get_n_d_unit(get_duration_style(ios), d) + * @Returns s, iterator pointing immediately after the last character produced. + */ + template + iter_type put_unit(iter_type s, std::ios_base& ios, char_type fill, duration const& d) const + { + if (std::has_facet >(ios.getloc())) + { + duration_units const&facet = std::use_facet >( + ios.getloc()); + return put_unit(facet, s, ios, fill, d); + } + else + { + duration_units_default facet; + return put_unit(facet, s, ios, fill, d); + } + } + + template + iter_type put_unit(duration_units const& facet, iter_type s, std::ios_base& ios, char_type fill, + duration const& d) const + { + if (facet.template is_named_unit()) { + string_type str = facet.get_unit(get_duration_style(ios), d); + s=std::copy(str.begin(), str.end(), s); + } else { + *s++ = CharT('['); + std::use_facet >(ios.getloc()).put(s, ios, fill, Period::num); + *s++ = CharT('/'); + std::use_facet >(ios.getloc()).put(s, ios, fill, Period::den); + *s++ = CharT(']'); + string_type str = facet.get_n_d_unit(get_duration_style(ios), d); + s=std::copy(str.begin(), str.end(), s); + } + return s; + } + template + iter_type put_unit(duration_units const& facet, iter_type s, std::ios_base& ios, char_type fill, + duration, Period> const& d) const + { + duration real(d.count().real); + if (facet.template is_named_unit()) { + string_type str = facet.get_unit(get_duration_style(ios), real); + s=std::copy(str.begin(), str.end(), s); + } else { + *s++ = CharT('['); + std::use_facet >(ios.getloc()).put(s, ios, fill, Period::num); + *s++ = CharT('/'); + std::use_facet >(ios.getloc()).put(s, ios, fill, Period::den); + *s++ = CharT(']'); + string_type str = facet.get_n_d_unit(get_duration_style(ios), real); + s=std::copy(str.begin(), str.end(), s); + } + return s; + } + + /** + * Unique identifier for this type of facet. + */ + static std::locale::id id; + + /** + * @Effects Destroy the facet + */ + ~duration_put() + { + } + + }; + + template + std::locale::id duration_put::id; + + } // chrono +} // boost + +#endif // header diff --git a/boost/chrono/io/duration_style.hpp b/boost/chrono/io/duration_style.hpp new file mode 100644 index 00000000..65b76a90 --- /dev/null +++ b/boost/chrono/io/duration_style.hpp @@ -0,0 +1,35 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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 code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o to Boost + +#ifndef BOOST_CHRONO_IO_DURATION_STYLE_HPP +#define BOOST_CHRONO_IO_DURATION_STYLE_HPP + +#include + +namespace boost +{ + namespace chrono + { + /** + * Scoped enumeration emulation stating whether the duration I/O style is long or short. + * prefix means duration::rep with whatever stream/locale settings are set for it followed by a long name representing the unit + * symbol means duration::rep with whatever stream/locale settings are set for it followed by a SI unit abbreviation + */ + BOOST_SCOPED_ENUM_DECLARE_BEGIN(duration_style) + { + prefix, symbol + } + BOOST_SCOPED_ENUM_DECLARE_END(duration_style) + + + } // chrono + +} + +#endif // header diff --git a/boost/chrono/io/duration_units.hpp b/boost/chrono/io/duration_units.hpp new file mode 100644 index 00000000..84faa819 --- /dev/null +++ b/boost/chrono/io/duration_units.hpp @@ -0,0 +1,1003 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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_CHRONO_IO_DURATION_UNITS_HPP +#define BOOST_CHRONO_IO_DURATION_UNITS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace chrono + { + class rt_ratio + { + public: + template + rt_ratio(Period const&) : + num(Period::type::num), den(Period::type::den) + { + } + + rt_ratio(intmax_t n = 0, intmax_t d = 0) : + num(n), den(d) + { + } + + intmax_t num; + intmax_t den; + }; + + /** + * @c duration_units facet gives useful information about the duration units, + * as the number of plural forms, the plural form associated to a duration, + * the text associated to a plural form and a duration's period, + */ + template + class duration_units: public std::locale::facet + { + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of character string passed to member functions. + */ + typedef std::basic_string string_type; + + /** + * Unique identifier for this type of facet. + */ + static std::locale::id id; + + /** + * Construct a @c duration_units facet. + * @param refs + * @Effects Construct a @c duration_units facet. + * If the @c refs argument is @c 0 then destruction of the object is + * delegated to the @c locale, or locales, containing it. This allows + * the user to ignore lifetime management issues. On the other had, + * if @c refs is @c 1 then the object must be explicitly deleted; + * the @c locale will not do so. In this case, the object can be + * maintained across the lifetime of multiple locales. + */ + explicit duration_units(size_t refs = 0) : + std::locale::facet(refs) + { + } + + /** + * @return pointer to the start of valid [N/D] units. + */ + virtual const string_type* get_n_d_valid_units_start() const =0; + /** + * @effect calls the do_... + * @return pointer to the end of valid [N/D] units. + */ + virtual const string_type* get_n_d_valid_units_end() const=0; + + /** + * @return pointer to the start of valid units, symbol or prefix with its different plural forms. + */ + virtual const string_type* get_valid_units_start() const=0; + /** + * @return pointer to the end of valid units. + */ + virtual const string_type* get_valid_units_end() const=0; + + /** + * @param k the found pointer to the [N/D] unit. + * @return true if @c k matches a valid unit. + */ + virtual bool match_n_d_valid_unit(const string_type* k) const = 0; + /** + * @param k the found pointer to the unit. + * @Effects @c rt is set to the valid Period when the @c k matches a valid unit. + * @return true if @c k matches a valid unit. + */ + virtual bool match_valid_unit(const string_type* k, rt_ratio& rt) const = 0; + + /** + * @effect calls the do_... + * @return the pattern to be used by default. + */ + virtual string_type get_pattern() const=0; + + /** + * @effect calls the do_... + * @return the unit associated to this duration. + */ + template + string_type get_unit(duration_style style, duration const& d) const + { + return do_get_unit(style, rt_ratio(Period()), static_cast(d.count())); + } + /** + * @effect calls the do_... + * @return the [N/D] suffix unit associated to this duration. + */ + template + string_type get_n_d_unit(duration_style style, duration const& d) const + { + return do_get_n_d_unit(style, rt_ratio(Period()), static_cast(d.count())); + } + + /** + * @effect calls the do_... + * @return true if the unit associated to the given Period is named, false otherwise. + */ + template + bool is_named_unit() const + { + return do_is_named_unit(rt_ratio(Period())); + } + + + protected: + + /** + * @Effects Destroys the facet + */ + virtual ~duration_units() + { + } + /** + * @return the [N/D] suffix unit associated to this duration. + */ + virtual string_type do_get_n_d_unit(duration_style style, rt_ratio rt, intmax_t v) const = 0; + /** + * @return the unit associated to this duration. + */ + virtual string_type do_get_unit(duration_style style,rt_ratio rt, intmax_t v) const = 0; + /** + * @return true if the unit associated to the given Period is named, false otherwise. + */ + virtual bool do_is_named_unit(rt_ratio rt) const =0; + + }; + + template + std::locale::id duration_units::id; + + namespace detail + { + template + struct duration_units_default_holder + { + typedef std::basic_string string_type; + static string_type* n_d_valid_units_; + static string_type* valid_units_; + static bool initialized_; + }; + template + typename duration_units_default_holder::string_type* duration_units_default_holder::n_d_valid_units_=0; + template + typename duration_units_default_holder::string_type* duration_units_default_holder::valid_units_=0; + template + bool duration_units_default_holder::initialized_ = false; + } + + /** + * This class is used to define the strings for the default English + */ + template + class duration_units_default: public duration_units + { + protected: + static const std::size_t pfs_ = 2; + + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of character string passed to member functions. + */ + typedef std::basic_string string_type; + + /** + * Construct a @c duration_units_default facet. + * @param refs + * @Effects Construct a @c duration_units_default facet. + * If the @c refs argument is @c 0 then destruction of the object is + * delegated to the @c locale, or locales, containing it. This allows + * the user to ignore lifetime management issues. On the other had, + * if @c refs is @c 1 then the object must be explicitly deleted; + * the @c locale will not do so. In this case, the object can be + * maintained across the lifetime of multiple locales. + */ + explicit duration_units_default(size_t refs = 0) : + duration_units (refs) + { + } + + /** + * Destroys the facet. + */ + ~duration_units_default() + { + } + + public: + + /** + * @param k the found pointer to the [N/D] unit. + * @return true if @c k matches a valid unit. + */ + bool match_n_d_valid_unit(const string_type* k) const + { + std::size_t index = (k - get_n_d_valid_units_start()) / (pfs_ + 1); + switch (index) + { + case 0: + break; + default: + return false; + } + return true; + } + /** + * @param k the found pointer to the unit. + * @Effects @c rt is set to the valid Period when the @c k matches a valid unit. + * @return true if @c k matches a valid unit. + */ + bool match_valid_unit(const string_type* k, rt_ratio& rt) const + { + std::size_t index = (k - get_valid_units_start()) / (pfs_ + 1); + switch (index) + { + case 0: + rt = rt_ratio(atto()); + break; + case 1: + rt = rt_ratio(femto()); + break; + case 2: + rt = rt_ratio(pico()); + break; + case 3: + rt = rt_ratio(nano()); + break; + case 4: + rt = rt_ratio(micro()); + break; + case 5: + rt = rt_ratio(milli()); + break; + case 6: + rt = rt_ratio(centi()); + break; + case 7: + rt = rt_ratio(deci()); + break; + case 8: + rt = rt_ratio(deca()); + break; + case 9: + rt = rt_ratio(hecto()); + break; + case 10: + rt = rt_ratio(kilo()); + break; + case 11: + rt = rt_ratio(mega()); + break; + case 12: + rt = rt_ratio(giga()); + break; + case 13: + rt = rt_ratio(tera()); + break; + case 14: + rt = rt_ratio(peta()); + break; + case 15: + rt = rt_ratio(exa()); + break; + case 16: + rt = rt_ratio(ratio<1> ()); + break; + case 17: + rt = rt_ratio(ratio<60> ()); + break; + case 18: + rt = rt_ratio(ratio<3600> ()); + break; + default: + return false; + } + return true; + } + + /** + * @return pointer to the start of valid [N/D] units. + */ + virtual const string_type* get_n_d_valid_units_start()const + { + return detail::duration_units_default_holder::n_d_valid_units_; + } + /** + * @return pointer to the end of valid [N/D] units. + */ + virtual const string_type* get_n_d_valid_units_end()const + { + return detail::duration_units_default_holder::n_d_valid_units_ + (pfs_ + 1); + } + + /** + * @return pointer to the start of valid units. + */ + virtual const string_type* get_valid_units_start() const + { + return detail::duration_units_default_holder::valid_units_; + } + /** + * @return pointer to the end of valid units. + */ + virtual const string_type* get_valid_units_end() const + { + return detail::duration_units_default_holder::valid_units_ + 19 * (pfs_ + 1); + } + + string_type get_pattern() const + { + static const CharT t[] = + { '%', 'v', ' ', '%', 'u' }; + static const string_type pattern(t, t + sizeof (t) / sizeof (t[0])); + + return pattern; + } + + protected: + /** + * + * This facet names the units associated to the following periods: + * atto,femto,pico,nano,micro,milli,centi,deci,ratio<1>,deca,hecto,kilo,mega,giga,tera,peta,exa,ratio<60> and ratio<3600>. + * @return true if the unit associated to the given Period is named, false otherwise. + */ + bool do_is_named_unit(rt_ratio rt) const + { + if (rt.num==1) { + switch (rt.den) + { + case BOOST_RATIO_INTMAX_C(1): + case BOOST_RATIO_INTMAX_C(10): + case BOOST_RATIO_INTMAX_C(100): + case BOOST_RATIO_INTMAX_C(1000): + case BOOST_RATIO_INTMAX_C(1000000): + case BOOST_RATIO_INTMAX_C(1000000000): + case BOOST_RATIO_INTMAX_C(1000000000000): + case BOOST_RATIO_INTMAX_C(1000000000000000): + case BOOST_RATIO_INTMAX_C(1000000000000000000): + return true; + default: + return false; + } + } else if (rt.den==1) { + switch (rt.num) + { + case BOOST_RATIO_INTMAX_C(10): + case BOOST_RATIO_INTMAX_C(60): + case BOOST_RATIO_INTMAX_C(100): + case BOOST_RATIO_INTMAX_C(1000): + case BOOST_RATIO_INTMAX_C(3600): + case BOOST_RATIO_INTMAX_C(1000000): + case BOOST_RATIO_INTMAX_C(1000000000): + case BOOST_RATIO_INTMAX_C(1000000000000): + case BOOST_RATIO_INTMAX_C(1000000000000000): + case BOOST_RATIO_INTMAX_C(1000000000000000000): + return true; + default: + return false; + } + } + return false; + + } + + /** + * In English the suffix used after [N/D] is the one associated to the period ratio<1>. + * @return the [N/D] suffix unit associated to this duration. + */ + string_type do_get_n_d_unit(duration_style style, rt_ratio, intmax_t v) const + { + return do_get_unit(style, ratio<1>(), do_get_plural_form(v)); + } + + /** + * @return the unit associated to this duration if it is named, "" otherwise. + */ + string_type do_get_unit(duration_style style, rt_ratio rt, intmax_t v) const + { + if (rt.num==1) { + switch (rt.den) + { + case BOOST_RATIO_INTMAX_C(1): + return do_get_unit(style, ratio<1>(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(10): + return do_get_unit(style, deci(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(100): + return do_get_unit(style, centi(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000): + return do_get_unit(style, milli(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000): + return do_get_unit(style, micro(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000): + return do_get_unit(style, nano(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000000): + return do_get_unit(style, pico(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000000000): + return do_get_unit(style, femto(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000000000000): + return do_get_unit(style, atto(), do_get_plural_form(v)); + default: + ; + } + } else if (rt.den==1) { + switch (rt.num) + { + case BOOST_RATIO_INTMAX_C(10): + return do_get_unit(style, deca(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(60): + return do_get_unit(style, ratio<60>(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(100): + return do_get_unit(style, hecto(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000): + return do_get_unit(style, kilo(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(3600): + return do_get_unit(style, ratio<3600>(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000): + return do_get_unit(style, mega(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000): + return do_get_unit(style, giga(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000000): + return do_get_unit(style, tera(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000000000): + return do_get_unit(style, peta(), do_get_plural_form(v)); + case BOOST_RATIO_INTMAX_C(1000000000000000000): + return do_get_unit(style, exa(), do_get_plural_form(v)); + default: + ; + } + } + BOOST_ASSERT(false&&"ratio parameter can not be translated"); + //throw "exception"; + return string_type(); + } + + protected: + /** + * @return the number of associated plural forms this facet manages. + */ + virtual std::size_t do_get_plural_forms() const + { + return static_get_plural_forms(); + } + static std::size_t static_get_plural_forms() + { + return pfs_; + } + /** + * Gets the associated plural form. + * @param value the duration representation + * @return the plural form associated to the @c value parameter. In English there are 2 plural forms + * 0 singular (-1 or 1) + * 1 plural for all others + */ + virtual std::size_t do_get_plural_form(int_least64_t value) const + { + return static_get_plural_form(value); + } + static std::size_t static_get_plural_form(int_least64_t value) + { + return (value == -1 || value == 1) ? 0 : 1; + } + + /** + * @param style the duration style. + * @param period the period associated to the duration seconds. + * @param pf the requested plural form. + * @return if style is symbol returns "s", otherwise if pf is 0 return "second", if pf is 1 "seconds" + */ + virtual string_type do_get_unit(duration_style style, ratio<1> u, std::size_t pf) const + { + return static_get_unit(style,u,pf); + } + static string_type static_get_unit(duration_style style, ratio<1> , std::size_t pf) + { + static const CharT t[] = + { 's' }; + static const string_type symbol(t, t + sizeof (t) / sizeof (t[0])); + static const CharT u[] = + { 's', 'e', 'c', 'o', 'n', 'd' }; + static const string_type singular(u, u + sizeof (u) / sizeof (u[0])); + static const CharT v[] = + { 's', 'e', 'c', 'o', 'n', 'd', 's' }; + static const string_type plural(v, v + sizeof (v) / sizeof (v[0])); + + if (style == duration_style::symbol) + { + return symbol; + } + if (pf == 0) + { + return singular; + } + if (pf == 1) + { + return plural; + } + BOOST_ASSERT(false&&"style/pf parameters not valid"); + //throw "exception"; + return string_type(); + } + + /** + * @param style the duration style. + * @param period the period associated to the duration minutes. + * @param pf the requested plural form. + * @return if style is symbol returns "min", otherwise if pf is 0 return "minute", if pf is 1 "minutes" + */ + virtual string_type do_get_unit(duration_style style, ratio<60> u, std::size_t pf) const + { + return static_get_unit(style,u,pf); + } + static string_type static_get_unit(duration_style style, ratio<60> , std::size_t pf) + { + static const CharT t[] = + { 'm', 'i', 'n' }; + static const string_type symbol(t, t + sizeof (t) / sizeof (t[0])); + + static const CharT u[] = + { 'm', 'i', 'n', 'u', 't', 'e' }; + static const string_type singular(u, u + sizeof (u) / sizeof (u[0])); + static const CharT v[] = + { 'm', 'i', 'n', 'u', 't', 'e', 's' }; + static const string_type plural(v, v + sizeof (v) / sizeof (v[0])); + + if (style == duration_style::symbol) return symbol; + if (pf == 0) return singular; + if (pf == 1) return plural; + BOOST_ASSERT(false&&"style/pf parameters not valid"); + //throw "exception"; + return string_type(); + + } + + /** + * @param style the duration style. + * @param period the period associated to the duration hours. + * @param pf the requested plural form. + * @return if style is symbol returns "h", otherwise if pf is 0 return "hour", if pf is 1 "hours" + */ + virtual string_type do_get_unit(duration_style style, ratio<3600> u, std::size_t pf) const + { + return static_get_unit(style,u,pf); + } + static string_type static_get_unit(duration_style style, ratio<3600> , std::size_t pf) + { + static const CharT t[] = + { 'h' }; + static const string_type symbol(t, t + sizeof (t) / sizeof (t[0])); + static const CharT u[] = + { 'h', 'o', 'u', 'r' }; + static const string_type singular(u, u + sizeof (u) / sizeof (u[0])); + static const CharT v[] = + { 'h', 'o', 'u', 'r', 's' }; + static const string_type plural(v, v + sizeof (v) / sizeof (v[0])); + + if (style == duration_style::symbol) return symbol; + if (pf == 0) return singular; + if (pf == 1) return plural; + BOOST_ASSERT(false&&"style/pf parameters not valid"); + //throw "exception"; + return string_type(); + + } + /** + * @param style the duration style. + * @param u the period tag atto. + * @param pf the requested plural form. + * @return the concatenation of the prefix associated to @c period + the one associated to seconds. + */ + virtual string_type do_get_unit(duration_style style, atto u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, atto u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + /** + * @param style the duration style. + * @param u the period tag femto. + * @param pf the requested plural form. + * @return the concatenation of the prefix associated to period @c u + the one associated to seconds. + */ + virtual string_type do_get_unit(duration_style style, femto u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, femto u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + /** + * @param style the duration style. + * @param u the period tag femto. + * @param pf the requested plural form. + * @return the concatenation of the prefix associated to period @c u + the one associated to seconds. + */ + virtual string_type do_get_unit(duration_style style, pico u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, pico u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, nano u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, nano u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, micro u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, micro u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, milli u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, milli u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, centi u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, centi u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, deci u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, deci u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, deca u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, deca u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, hecto u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, hecto u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, kilo u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, kilo u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, mega u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, mega u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, giga u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, giga u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, tera u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, tera u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, peta u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, peta u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + virtual string_type do_get_unit(duration_style style, exa u, std::size_t pf) const + { + return do_get_ratio_prefix(style, u) + do_get_unit(style, ratio<1> (), pf); + } + static string_type static_get_unit(duration_style style, exa u, std::size_t pf) + { + return static_get_ratio_prefix(style, u) + static_get_unit(style, ratio<1> (), pf); + } + + protected: + + /** + * @param style the duration style. + * @param u the period tag atto. + * @return depending on the value of @c style return the ratio_string symbol or prefix. + */ + virtual string_type do_get_ratio_prefix(duration_style style, atto u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, atto) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, femto u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, femto) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, pico u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, pico) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, nano u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, nano) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, micro u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, micro) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, milli u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, milli) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, centi u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, centi) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, deci u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, deci) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, deca u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, deca) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, hecto u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, hecto) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, kilo u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, kilo) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, mega u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, mega) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, giga u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, giga) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, tera u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, tera) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, peta u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, peta) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + virtual string_type do_get_ratio_prefix(duration_style style, exa u) const + { + return static_get_ratio_prefix(style, u); + } + static string_type static_get_ratio_prefix(duration_style style, exa) + { + if (style == duration_style::symbol) return ratio_string::symbol(); + return ratio_string::prefix(); + } + + protected: + template + string_type* fill_units(string_type* it, Period) const + { + std::size_t pfs = do_get_plural_forms(); + for (std::size_t pf = 0; pf < pfs; ++pf) + { + *it++ = do_get_unit(duration_style::prefix, Period(), pf); + } + *it++ = do_get_unit(duration_style::symbol, Period(), 0); + return it; + } + public: + template + static string_type* static_fill_units(string_type* it, Period) + { + std::size_t pfs = static_get_plural_forms(); + for (std::size_t pf = 0; pf < pfs; ++pf) + { + *it++ = static_get_unit(duration_style::prefix, Period(), pf); + } + *it++ = static_get_unit(duration_style::symbol, Period(), 0); + return it; + } + static string_type* static_init_valid_units(string_type* it) + { + it = static_fill_units(it, atto()); + it = static_fill_units(it, femto()); + it = static_fill_units(it, pico()); + it = static_fill_units(it, nano()); + it = static_fill_units(it, micro()); + it = static_fill_units(it, milli()); + it = static_fill_units(it, centi()); + it = static_fill_units(it, deci()); + it = static_fill_units(it, deca()); + it = static_fill_units(it, hecto()); + it = static_fill_units(it, kilo()); + it = static_fill_units(it, mega()); + it = static_fill_units(it, giga()); + it = static_fill_units(it, tera()); + it = static_fill_units(it, peta()); + it = static_fill_units(it, exa()); + it = static_fill_units(it, ratio<1> ()); + it = static_fill_units(it, ratio<60> ()); + it = static_fill_units(it, ratio<3600> ()); + return it; + } + }; + + namespace detail + { + + template + struct duration_units_default_initializer_t + { + duration_units_default_initializer_t() + { + if (!duration_units_default_holder::initialized_) + { + typedef typename duration_units_default_holder::string_type string_type; + duration_units_default_holder::n_d_valid_units_ = new string_type[3]; + duration_units_default_holder::valid_units_ = new string_type[19 * 3]; + + string_type* it = duration_units_default_holder::n_d_valid_units_; + it = duration_units_default::static_fill_units(it, ratio<1> ()); + it = duration_units_default::static_init_valid_units(duration_units_default_holder::valid_units_); + + duration_units_default_holder::initialized_ = true; + } + } + ~duration_units_default_initializer_t() + { + if (duration_units_default_holder::initialized_) + { + delete[] duration_units_default_holder::n_d_valid_units_; + duration_units_default_holder::n_d_valid_units_ = 0; + delete[] duration_units_default_holder::valid_units_; + duration_units_default_holder::valid_units_ = 0; + duration_units_default_holder::initialized_ = false; + } + } + }; + namespace /**/ + { + duration_units_default_initializer_t duration_units_default_initializer; + duration_units_default_initializer_t wduration_units_default_initializer; + } // namespace + } + } // chrono + +} // boost + +#endif // header diff --git a/boost/chrono/io/ios_base_state.hpp b/boost/chrono/io/ios_base_state.hpp new file mode 100644 index 00000000..1393e2e6 --- /dev/null +++ b/boost/chrono/io/ios_base_state.hpp @@ -0,0 +1,152 @@ +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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 code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o to Boost + +#ifndef BOOST_CHRONO_IO_IOS_BASE_STATE_HPP +#define BOOST_CHRONO_IO_IOS_BASE_STATE_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace chrono + { + + class fmt_masks : public ios_flags + { + typedef ios_flags base_type; + fmt_masks& operator=(fmt_masks const& rhs) ; + + public: + fmt_masks(std::ios_base& ios): base_type(ios) {} + enum type + { + uses_symbol = 1 << 0, + uses_local = 1 << 1 + }; + + inline duration_style get_duration_style() + { + return (flags() & uses_symbol) ? duration_style::symbol : duration_style::prefix; + } + inline void set_duration_style(duration_style style) + { + if (style == duration_style::symbol) + setf(uses_symbol); + else + unsetf(uses_symbol); + } + + inline timezone get_timezone() + { + return (flags() & uses_local) ? timezone::local : timezone::utc; + } + inline void set_timezone(timezone tz) + { + if (tz == timezone::local) + setf(uses_local); + else + unsetf(uses_local); + } + }; + namespace detail + { + namespace /**/ { + xalloc_key_initializer fmt_masks_xalloc_key_initializer; + } // namespace + } // namespace detail + + inline duration_style get_duration_style(std::ios_base & ios) + { + return fmt_masks(ios).get_duration_style(); + } + inline void set_duration_style(std::ios_base& ios, duration_style style) + { + fmt_masks(ios).set_duration_style(style); + } + inline std::ios_base& symbol_format(std::ios_base& ios) + { + fmt_masks(ios).setf(fmt_masks::uses_symbol); + return ios; + } + inline std::ios_base& name_format(std::ios_base& ios) + { + fmt_masks(ios).unsetf(fmt_masks::uses_symbol); + return ios; + } + + inline timezone get_timezone(std::ios_base & ios) + { + return fmt_masks(ios).get_timezone(); + } + inline void set_timezone(std::ios_base& ios, timezone tz) + { + fmt_masks(ios).set_timezone(tz); + } + inline std::ios_base& local_timezone(std::ios_base& ios) + { + fmt_masks(ios).setf(fmt_masks::uses_local); + return ios; + } + + inline std::ios_base& utc_timezone(std::ios_base& ios) + { + fmt_masks(ios).unsetf(fmt_masks::uses_local); + return ios; + } + + namespace detail + { + + template + struct ios_base_data_aux + { + std::basic_string time_fmt; + std::basic_string duration_fmt; + public: + + ios_base_data_aux() + //: + // time_fmt(""), + // duration_fmt("") + { + } + }; + template + struct ios_base_data {}; + namespace /**/ { + xalloc_key_initializer > ios_base_data_aux_xalloc_key_initializer; + xalloc_key_initializer > wios_base_data_aux_xalloc_key_initializer; +#if BOOST_CHRONO_HAS_UNICODE_SUPPORT + xalloc_key_initializer > u16ios_base_data_aux_xalloc_key_initializer; + xalloc_key_initializer > u32ios_base_data_aux_xalloc_key_initializer; +#endif + } // namespace + } // namespace detail + + template + inline std::basic_string get_time_fmt(std::ios_base & ios) + { + ios_state_not_null_ptr, detail::ios_base_data_aux > ptr(ios); + return ptr->time_fmt; + } + template + inline void set_time_fmt(std::ios_base& ios, std::basic_string< + CharT> const& fmt) + { + ios_state_not_null_ptr, detail::ios_base_data_aux > ptr(ios); + ptr->time_fmt = fmt; + } + + } // chrono +} // boost + +#endif // header diff --git a/boost/chrono/io/time_point_get.hpp b/boost/chrono/io/time_point_get.hpp new file mode 100644 index 00000000..44c641e6 --- /dev/null +++ b/boost/chrono/io/time_point_get.hpp @@ -0,0 +1,330 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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_CHRONO_IO_TIME_POINT_GET_HPP +#define BOOST_CHRONO_IO_TIME_POINT_GET_HPP + +#include +#include +#include +#include +#include +#include +#include + +/** + * Duration formatting facet for input. + */ +namespace boost +{ + namespace chrono + { + + template > + class time_point_get: public std::locale::facet + { + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of iterator used to scan the character buffer. + */ + typedef InputIterator iter_type; + + /** + * Construct a @c time_point_get facet. + * @param refs + * @Effects Construct a @c time_point_get facet. + * If the @c refs argument is @c 0 then destruction of the object is + * delegated to the @c locale, or locales, containing it. This allows + * the user to ignore lifetime management issues. On the other had, + * if @c refs is @c 1 then the object must be explicitly deleted; + * the @c locale will not do so. In this case, the object can be + * maintained across the lifetime of multiple locales. + */ + + explicit time_point_get(size_t refs = 0) : + std::locale::facet(refs) + { + } + + /** + * @param s start input stream iterator + * @param end end input stream iterator + * @param ios a reference to a ios_base + * @param err the ios_base state + * @param d the duration + * @param pattern begin of the formatting pattern + * @param pat_end end of the formatting pattern + * + * Requires: [pattern,pat_end) shall be a valid range. + * + * Effects: The function starts by evaluating err = std::ios_base::goodbit. + * It then enters a loop, reading zero or more characters from s at + * each iteration. Unless otherwise specified below, the loop + * terminates when the first of the following conditions holds: + * - The expression pattern == pat_end evaluates to true. + * - The expression err == std::ios_base::goodbit evaluates to false. + * - The expression s == end evaluates to true, in which case the + * function evaluates err = std::ios_base::eofbit | std::ios_base::failbit. + * - The next element of pattern is equal to '%', followed by a conversion + * specifier character, the functions @c get_duration or @c get_epoch are called depending on + * whether the format is @c 'd' or @c 'e'. + * If the number of elements in the range [pattern,pat_end) is not + * sufficient to unambiguously determine whether the conversion + * specification is complete and valid, the function evaluates + * err = std::ios_base::failbit. Otherwise, the function evaluates + * s = do_get(s, end, ios, err, d). If err == std::ios_base::goodbit holds after + * the evaluation of the expression, the function increments pattern to + * point just past the end of the conversion specification and continues + * looping. + * - The expression isspace(*pattern, ios.getloc()) evaluates to true, in + * which case the function first increments pattern until + * pattern == pat_end || !isspace(*pattern, ios.getloc()) evaluates to true, + * then advances s until s == end || !isspace(*s, ios.getloc()) is true, + * and finally resumes looping. + * - The next character read from s matches the element pointed to by + * pattern in a case-insensitive comparison, in which case the function + * evaluates ++pattern, ++s and continues looping. Otherwise, the function + * evaluates err = std::ios_base::failbit. + * + * Returns: s + */ + + template + iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err, + time_point &tp, const char_type *pattern, const char_type *pat_end) const + { + if (std::has_facet >(is.getloc())) + { + time_point_units const &facet = std::use_facet >(is.getloc()); + return get(facet, i, e, is, err, tp, pattern, pat_end); + } + else + { + time_point_units_default facet; + return get(facet, i, e, is, err, tp, pattern, pat_end); + } + } + + template + iter_type get(time_point_units const &facet, iter_type s, iter_type end, std::ios_base& ios, + std::ios_base::iostate& err, time_point &tp, const char_type *pattern, + const char_type *pat_end) const + { + + Duration d; + bool duration_found = false, epoch_found = false; + + const std::ctype& ct = std::use_facet >(ios.getloc()); + err = std::ios_base::goodbit; + while (pattern != pat_end && err == std::ios_base::goodbit) + { + if (s == end) + { + err |= std::ios_base::eofbit; + break; + } + if (ct.narrow(*pattern, 0) == '%') + { + if (++pattern == pat_end) + { + err |= std::ios_base::failbit; + return s; + } + char cmd = ct.narrow(*pattern, 0); + switch (cmd) + { + case 'd': + { + if (duration_found) + { + err |= std::ios_base::failbit; + return s; + } + duration_found = true; + s = get_duration(s, end, ios, err, d); + if (err & (std::ios_base::badbit | std::ios_base::failbit)) + { + return s; + } + break; + } + case 'e': + { + if (epoch_found) + { + err |= std::ios_base::failbit; + return s; + } + epoch_found = true; + s = get_epoch (facet, s, end, ios, err); + if (err & (std::ios_base::badbit | std::ios_base::failbit)) + { + return s; + } + break; + } + default: + BOOST_ASSERT(false && "Boost::Chrono internal error."); + break; + } + + ++pattern; + } + else if (ct.is(std::ctype_base::space, *pattern)) + { + for (++pattern; pattern != pat_end && ct.is(std::ctype_base::space, *pattern); ++pattern) + ; + for (; s != end && ct.is(std::ctype_base::space, *s); ++s) + ; + } + else if (ct.toupper(*s) == ct.toupper(*pattern)) + { + ++s; + ++pattern; + } + else + { + err |= std::ios_base::failbit; + } + } + + // Success! Store it. + tp = time_point (d); + return s; + } + + /** + * + * @param s an input stream iterator + * @param ios a reference to a ios_base + * @param d the duration + * Stores the duration pattern from the @c duration_unit facet in let say @c str. Last as if + * @code + * return get(s, end, ios, err, ios, d, str.data(), str.data() + str.size()); + * @codeend + * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid name + */ + template + iter_type get(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err, + time_point &tp) const + { + if (std::has_facet >(is.getloc())) + { + time_point_units const &facet = std::use_facet >(is.getloc()); + std::basic_string str = facet.get_pattern(); + return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size()); + } + else + { + time_point_units_default facet; + std::basic_string str = facet.get_pattern(); + return get(facet, i, e, is, err, tp, str.data(), str.data() + str.size()); + } + } + + /** + * As if + * @code + * return facet.get(s, end, ios, err, d); + * @endcode + * where @c facet is either the @c duration_get facet associated to the @c ios or an instance of the default @c duration_get facet. + * + * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid duration. + */ + template + iter_type get_duration(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err, + duration& d) const + { + if (std::has_facet >(is.getloc())) + { + duration_get const &facet = std::use_facet >(is.getloc()); + return get_duration(facet, i, e, is, err, d); + } + else + { + duration_get facet; + return get_duration(facet, i, e, is, err, d); + } + } + + template + iter_type get_duration(duration_get const& facet, iter_type s, iter_type end, std::ios_base& ios, + std::ios_base::iostate& err, duration& d) const + { + return facet.get(s, end, ios, err, d); + } + + /** + * + * @Effects Let @c facet be the @c time_point_units facet associated to @c is or a new instance of the default @c time_point_units_default facet. + * Let @c epoch be the epoch string associated to the Clock using this facet. + * Scans @c i to match @c epoch or @c e is reached. + * + * If not match before the @c e is reached @c std::ios_base::failbit is set in @c err. + * If @c e is reached @c std::ios_base::failbit is set in @c err. + * + * @Returns An iterator pointing just beyond the last character that can be determined to be part of a valid epoch. + */ + template + iter_type get_epoch(iter_type i, iter_type e, std::ios_base& is, std::ios_base::iostate& err) const + { + if (std::has_facet >(is.getloc())) + { + time_point_units const &facet = std::use_facet >(is.getloc()); + return get_epoch(facet, i, e, is, err); + } + else + { + time_point_units_default facet; + return get_epoch(facet, i, e, is, err); + } + } + + template + iter_type get_epoch(time_point_units const &facet, iter_type i, iter_type e, std::ios_base&, + std::ios_base::iostate& err) const + { + const std::basic_string epoch = facet.template get_epoch (); + std::ptrdiff_t k = chrono_detail::scan_keyword(i, e, &epoch, &epoch + 1, + //~ std::use_facet >(ios.getloc()), + err) - &epoch; + if (k == 1) + { + err |= std::ios_base::failbit; + return i; + } + return i; + } + + /** + * Unique identifier for this type of facet. + */ + static std::locale::id id; + + /** + * @Effects Destroy the facet + */ + ~time_point_get() + { + } + }; + + /** + * Unique identifier for this type of facet. + */ + template + std::locale::id time_point_get::id; + + } // chrono +} +// boost + +#endif // header diff --git a/boost/chrono/io/time_point_io.hpp b/boost/chrono/io/time_point_io.hpp new file mode 100644 index 00000000..3143efac --- /dev/null +++ b/boost/chrono/io/time_point_io.hpp @@ -0,0 +1,1249 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2010-2011 Vicente J. Botet Escriba +// 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). + +//===-------------------------- locale ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// This code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o to Boost and some functions from libc++/locale to emulate the missing time_get::get() + +#ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP +#define BOOST_CHRONO_IO_TIME_POINT_IO_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \ + || (defined(sun) || defined(__sun)) \ + || (defined __IBMCPP__) \ + || defined __ANDROID__ \ + || defined __QNXNTO__ \ + || (defined(_AIX) && defined __GNUC__) +#define BOOST_CHRONO_INTERNAL_TIMEGM +#endif + +#if (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \ + || ( (defined(sun) || defined(__sun)) && defined __GNUC__) \ + || (defined __IBMCPP__) \ + || defined __ANDROID__ \ + || (defined(_AIX) && defined __GNUC__) +#define BOOST_CHRONO_INTERNAL_GMTIME +#endif + +#define BOOST_CHRONO_USES_INTERNAL_TIME_GET + +namespace boost +{ + namespace chrono + { + typedef double fractional_seconds; + namespace detail + { + + + template > + struct time_get + { + std::time_get const &that_; + time_get(std::time_get const& that) : that_(that) {} + + typedef std::time_get facet; + typedef typename facet::iter_type iter_type; + typedef typename facet::char_type char_type; + typedef std::basic_string string_type; + + static int + get_up_to_n_digits( + InputIterator& b, InputIterator e, + std::ios_base::iostate& err, + const std::ctype& ct, + int n) + { + // Precondition: n >= 1 + if (b == e) + { + err |= std::ios_base::eofbit | std::ios_base::failbit; + return 0; + } + // get first digit + CharT c = *b; + if (!ct.is(std::ctype_base::digit, c)) + { + err |= std::ios_base::failbit; + return 0; + } + int r = ct.narrow(c, 0) - '0'; + for (++b, --n; b != e && n > 0; ++b, --n) + { + // get next digit + c = *b; + if (!ct.is(std::ctype_base::digit, c)) + return r; + r = r * 10 + ct.narrow(c, 0) - '0'; + } + if (b == e) + err |= std::ios_base::eofbit; + return r; + } + + + void get_day( + int& d, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 2); + if (!(err & std::ios_base::failbit) && 1 <= t && t <= 31) + d = t; + else + err |= std::ios_base::failbit; + } + + void get_month( + int& m, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 2); + if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12) + m = --t; + else + err |= std::ios_base::failbit; + } + + + void get_year4(int& y, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 4); + if (!(err & std::ios_base::failbit)) + y = t - 1900; + } + + void + get_hour(int& h, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 2); + if (!(err & std::ios_base::failbit) && t <= 23) + h = t; + else + err |= std::ios_base::failbit; + } + + void + get_minute(int& m, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 2); + if (!(err & std::ios_base::failbit) && t <= 59) + m = t; + else + err |= std::ios_base::failbit; + } + + void get_second(int& s, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 2); + if (!(err & std::ios_base::failbit) && t <= 60) + s = t; + else + err |= std::ios_base::failbit; + } + + void get_white_space(iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + for (; b != e && ct.is(std::ctype_base::space, *b); ++b) + ; + if (b == e) + err |= std::ios_base::eofbit; + } + + void get_12_hour(int& h, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 2); + if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12) + h = t; + else + err |= std::ios_base::failbit; + } + + void get_percent(iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + if (b == e) + { + err |= std::ios_base::eofbit | std::ios_base::failbit; + return; + } + if (ct.narrow(*b, 0) != '%') + err |= std::ios_base::failbit; + else if(++b == e) + err |= std::ios_base::eofbit; + } + + void get_day_year_num(int& d, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 3); + if (!(err & std::ios_base::failbit) && 1 <= t && t <= 366) + d = --t; + else + err |= std::ios_base::failbit; + } + + void + get_weekday(int& w, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + int t = get_up_to_n_digits(b, e, err, ct, 1); + if (!(err & std::ios_base::failbit) && t <= 6) + w = t; + else + err |= std::ios_base::failbit; + } +#if 0 + + void + get_am_pm(int& h, + iter_type& b, iter_type e, + std::ios_base::iostate& err, + const std::ctype& ct) const + { + const string_type* ap = am_pm(); + if (ap[0].size() + ap[1].size() == 0) + { + err |= ios_base::failbit; + return; + } + ptrdiff_t i = detail::scan_keyword(b, e, ap, ap+2, ct, err, false) - ap; + if (i == 0 && h == 12) + h = 0; + else if (i == 1 && h < 12) + h += 12; + } + +#endif + + InputIterator get( + iter_type b, iter_type e, + std::ios_base& iob, + std::ios_base::iostate& err, + std::tm* tm, + char fmt, char) const + { + err = std::ios_base::goodbit; + const std::ctype& ct = std::use_facet >(iob.getloc()); + + switch (fmt) + { + case 'a': + case 'A': + { + std::tm tm2; + std::memset(&tm2, 0, sizeof(std::tm)); + that_.get_weekday(b, e, iob, err, &tm2); + //tm->tm_wday = tm2.tm_wday; + } + break; + case 'b': + case 'B': + case 'h': + { + std::tm tm2; + std::memset(&tm2, 0, sizeof(std::tm)); + that_.get_monthname(b, e, iob, err, &tm2); + //tm->tm_mon = tm2.tm_mon; + } + break; +// case 'c': +// { +// const string_type& fm = c(); +// b = get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size()); +// } +// break; + case 'd': + case 'e': + get_day(tm->tm_mday, b, e, err, ct); + break; + case 'D': + { + const char_type fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; + b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); + } + break; + case 'F': + { + const char_type fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; + b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); + } + break; + case 'H': + get_hour(tm->tm_hour, b, e, err, ct); + break; + case 'I': + get_12_hour(tm->tm_hour, b, e, err, ct); + break; + case 'j': + get_day_year_num(tm->tm_yday, b, e, err, ct); + break; + case 'm': + get_month(tm->tm_mon, b, e, err, ct); + break; + case 'M': + get_minute(tm->tm_min, b, e, err, ct); + break; + case 'n': + case 't': + get_white_space(b, e, err, ct); + break; +// case 'p': +// get_am_pm(tm->tm_hour, b, e, err, ct); +// break; + case 'r': + { + const char_type fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; + b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); + } + break; + case 'R': + { + const char_type fm[] = {'%', 'H', ':', '%', 'M'}; + b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); + } + break; + case 'S': + get_second(tm->tm_sec, b, e, err, ct); + break; + case 'T': + { + const char_type fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; + b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); + } + break; + case 'w': + { + get_weekday(tm->tm_wday, b, e, err, ct); + } + break; + case 'x': + return that_.get_date(b, e, iob, err, tm); +// case 'X': +// return that_.get_time(b, e, iob, err, tm); +// { +// const string_type& fm = X(); +// b = that_.get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size()); +// } +// break; +// case 'y': +// get_year(tm->tm_year, b, e, err, ct); + break; + case 'Y': + get_year4(tm->tm_year, b, e, err, ct); + break; + case '%': + get_percent(b, e, err, ct); + break; + default: + err |= std::ios_base::failbit; + } + return b; + } + + + InputIterator get( + iter_type b, iter_type e, + std::ios_base& iob, + std::ios_base::iostate& err, std::tm* tm, + const char_type* fmtb, const char_type* fmte) const + { + const std::ctype& ct = std::use_facet >(iob.getloc()); + err = std::ios_base::goodbit; + while (fmtb != fmte && err == std::ios_base::goodbit) + { + if (b == e) + { + err = std::ios_base::failbit; + break; + } + if (ct.narrow(*fmtb, 0) == '%') + { + if (++fmtb == fmte) + { + err = std::ios_base::failbit; + break; + } + char cmd = ct.narrow(*fmtb, 0); + char opt = '\0'; + if (cmd == 'E' || cmd == '0') + { + if (++fmtb == fmte) + { + err = std::ios_base::failbit; + break; + } + opt = cmd; + cmd = ct.narrow(*fmtb, 0); + } + b = get(b, e, iob, err, tm, cmd, opt); + ++fmtb; + } + else if (ct.is(std::ctype_base::space, *fmtb)) + { + for (++fmtb; fmtb != fmte && ct.is(std::ctype_base::space, *fmtb); ++fmtb) + ; + for ( ; b != e && ct.is(std::ctype_base::space, *b); ++b) + ; + } + else if (ct.toupper(*b) == ct.toupper(*fmtb)) + { + ++b; + ++fmtb; + } + else + err = std::ios_base::failbit; + } + if (b == e) + err |= std::ios_base::eofbit; + return b; + } + + }; + + + template + class time_manip: public manip > + { + std::basic_string fmt_; + timezone tz_; + public: + + time_manip(timezone tz, std::basic_string fmt) + // todo move semantics + : + fmt_(fmt), tz_(tz) + { + } + + /** + * Change the timezone and time format ios state; + */ + void operator()(std::ios_base &ios) const + { + set_time_fmt (ios, fmt_); + set_timezone(ios, tz_); + } + }; + + class time_man: public manip + { + timezone tz_; + public: + + time_man(timezone tz) + // todo move semantics + : + tz_(tz) + { + } + + /** + * Change the timezone and time format ios state; + */ + void operator()(std::ios_base &ios) const + { + //set_time_fmt(ios, ""); + set_timezone(ios, tz_); + } + }; + + } + + template + inline detail::time_manip time_fmt(timezone tz, const CharT* fmt) + { + return detail::time_manip(tz, fmt); + } + + template + inline detail::time_manip time_fmt(timezone tz, std::basic_string fmt) + { + // todo move semantics + return detail::time_manip(tz, fmt); + } + + inline detail::time_man time_fmt(timezone f) + { + return detail::time_man(f); + } + + /** + * time_fmt_io_saver i/o saver. + * + * See Boost.IO i/o state savers for a motivating compression. + */ + template > + struct time_fmt_io_saver + { + + //! the type of the state to restore + //typedef std::basic_ostream state_type; + typedef std::ios_base state_type; + + //! the type of aspect to save + typedef std::basic_string aspect_type; + + /** + * Explicit construction from an i/o stream. + * + * Store a reference to the i/o stream and the value of the associated @c time format . + */ + explicit time_fmt_io_saver(state_type &s) : + s_save_(s), a_save_(get_time_fmt(s_save_)) + { + } + + /** + * Construction from an i/o stream and a @c time format to restore. + * + * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter. + */ + time_fmt_io_saver(state_type &s, aspect_type new_value) : + s_save_(s), a_save_(get_time_fmt(s_save_)) + { + set_time_fmt(s_save_, new_value); + } + + /** + * Destructor. + * + * Restores the i/o stream with the format to be restored. + */ + ~time_fmt_io_saver() + { + this->restore(); + } + + /** + * Restores the i/o stream with the time format to be restored. + */ + void restore() + { + set_time_fmt(s_save_, a_save_); + } + private: + state_type& s_save_; + aspect_type a_save_; + }; + + /** + * timezone_io_saver i/o saver. + * + * See Boost.IO i/o state savers for a motivating compression. + */ + struct timezone_io_saver + { + + //! the type of the state to restore + typedef std::ios_base state_type; + //! the type of aspect to save + typedef timezone aspect_type; + + /** + * Explicit construction from an i/o stream. + * + * Store a reference to the i/o stream and the value of the associated @c timezone. + */ + explicit timezone_io_saver(state_type &s) : + s_save_(s), a_save_(get_timezone(s_save_)) + { + } + + /** + * Construction from an i/o stream and a @c timezone to restore. + * + * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter. + */ + timezone_io_saver(state_type &s, aspect_type new_value) : + s_save_(s), a_save_(get_timezone(s_save_)) + { + set_timezone(s_save_, new_value); + } + + /** + * Destructor. + * + * Restores the i/o stream with the format to be restored. + */ + ~timezone_io_saver() + { + this->restore(); + } + + /** + * Restores the i/o stream with the timezone to be restored. + */ + void restore() + { + set_timezone(s_save_, a_save_); + } + private: + timezone_io_saver& operator=(timezone_io_saver const& rhs) ; + + state_type& s_save_; + aspect_type a_save_; + }; + + /** + * + * @param os + * @param tp + * @Effects Behaves as a formatted output function. After constructing a @c sentry object, if the @ sentry + * converts to true, calls to @c facet.put(os,os,os.fill(),tp) where @c facet is the @c time_point_put + * facet associated to @c os or a new created instance of the default @c time_point_put facet. + * @return @c os. + */ + template + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_point& tp) + { + + bool failed = false; + BOOST_TRY + { + std::ios_base::iostate err = std::ios_base::goodbit; + BOOST_TRY + { + typename std::basic_ostream::sentry opfx(os); + if (bool(opfx)) + { + if (!std::has_facet >(os.getloc())) + { + if (time_point_put ().put(os, os, os.fill(), tp) .failed()) + { + err = std::ios_base::badbit; + } + } + else + { + if (std::use_facet >(os.getloc()) .put(os, os, os.fill(), tp).failed()) + { + err = std::ios_base::badbit; + } + } + os.width(0); + } + } + BOOST_CATCH (...) + { + bool flag = false; + BOOST_TRY + { + os.setstate(std::ios_base::failbit); + } + BOOST_CATCH (std::ios_base::failure ) + { + flag = true; + } + BOOST_CATCH_END + if (flag) throw; + } + BOOST_CATCH_END + if (err) os.setstate(err); + return os; + } + BOOST_CATCH (...) + { + failed = true; + } + BOOST_CATCH_END + if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit); + return os; + } + + template + std::basic_istream& + operator>>(std::basic_istream& is, time_point& tp) + { + std::ios_base::iostate err = std::ios_base::goodbit; + + BOOST_TRY + { + typename std::basic_istream::sentry ipfx(is); + if (bool(ipfx)) + { + if (!std::has_facet >(is.getloc())) + { + time_point_get ().get(is, std::istreambuf_iterator(), is, err, tp); + } + else + { + std::use_facet >(is.getloc()).get(is, std::istreambuf_iterator(), is, + err, tp); + } + } + } + BOOST_CATCH (...) + { + bool flag = false; + BOOST_TRY + { + is.setstate(std::ios_base::failbit); + } + BOOST_CATCH (std::ios_base::failure ) + { + flag = true; + } + BOOST_CATCH_END + if (flag) throw; + } + BOOST_CATCH_END + if (err) is.setstate(err); + return is; + } + + + namespace detail + { + +//#if defined BOOST_CHRONO_INTERNAL_TIMEGM + + inline int32_t is_leap(int32_t year) + { + if(year % 400 == 0) + return 1; + if(year % 100 == 0) + return 0; + if(year % 4 == 0) + return 1; + return 0; + } + inline int32_t days_from_0(int32_t year) + { + year--; + return 365 * year + (year / 400) - (year/100) + (year / 4); + } + inline int32_t days_from_1970(int32_t year) + { + static const int days_from_0_to_1970 = days_from_0(1970); + return days_from_0(year) - days_from_0_to_1970; + } + inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day) + { + static const int32_t days[2][12] = + { + { 0,31,59,90,120,151,181,212,243,273,304,334}, + { 0,31,60,91,121,152,182,213,244,274,305,335} + }; + + return days[is_leap(year)][month-1] + day - 1; + } + + inline time_t internal_timegm(std::tm const *t) + { + int year = t->tm_year + 1900; + int month = t->tm_mon; + if(month > 11) + { + year += month/12; + month %= 12; + } + else if(month < 0) + { + int years_diff = (-month + 11)/12; + year -= years_diff; + month+=12 * years_diff; + } + month++; + int day = t->tm_mday; + int day_of_year = days_from_1jan(year,month,day); + int days_since_epoch = days_from_1970(year) + day_of_year ; + + time_t seconds_in_day = 3600 * 24; + time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec; + + return result; + } +//#endif + + /** + * from_ymd could be made more efficient by using a table + * day_count_table indexed by the y%400. + * This table could contain the day_count + * by*365 + by/4 - by/100 + by/400 + * + * from_ymd = (by/400)*days_by_400_years+day_count_table[by%400] + + * days_in_year_before[is_leap_table[by%400]][m-1] + d; + */ + inline unsigned days_before_years(int32_t y) + { + return y * 365 + y / 4 - y / 100 + y / 400; + } + + // Returns year/month/day triple in civil calendar + // Preconditions: z is number of days since 1970-01-01 and is in the range: + // [numeric_limits::min(), numeric_limits::max()-719468]. + template + //constexpr + void + inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT_MSG(std::numeric_limits::digits >= 18, + "This algorithm has not been ported to a 16 bit unsigned integer"); + BOOST_STATIC_ASSERT_MSG(std::numeric_limits::digits >= 20, + "This algorithm has not been ported to a 16 bit signed integer"); + z += 719468; + const Int era = (z >= 0 ? z : z - 146096) / 146097; + const unsigned doe = static_cast(z - era * 146097); // [0, 146096] + const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] + y = static_cast(yoe) + era * 400; + const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] + const unsigned mp = (5*doy + 2)/153; // [0, 11] + d = doy - (153*mp+2)/5 + 1; // [1, 31] + m = mp + (mp < 10 ? 3 : -9); // [1, 12] + y += (m <= 2); + --m; + } + inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm) + { + if (t==0) return 0; + if (tm==0) return 0; + +#if 0 + static const unsigned char + day_of_year_month[2][366] = + { + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }, + + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 + + } }; + + static const int32_t days_in_year_before[2][13] = + { + { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }, + { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 } + }; +#endif + + const time_t seconds_in_day = 3600 * 24; + int32_t days_since_epoch = static_cast(*t / seconds_in_day); + int32_t hms = static_cast(*t - seconds_in_day*days_since_epoch); + if (hms < 0) { + days_since_epoch-=1; + hms = seconds_in_day+hms; + } + +#if 0 + int32_t x = days_since_epoch; + int32_t y = static_cast (static_cast (x + 2) * 400 + / 146097); + const int32_t ym1 = y - 1; + int32_t doy = x - days_before_years(y); + const int32_t doy1 = x - days_before_years(ym1); + const int32_t N = std::numeric_limits::digits - 1; + const int32_t mask1 = doy >> N; // arithmetic rshift - not portable - but nearly universal + const int32_t mask0 = ~mask1; + doy = (doy & mask0) | (doy1 & mask1); + y = (y & mask0) | (ym1 & mask1); + //y -= 32767 + 2; + y += 70; + tm->tm_year=y; + const int32_t leap = is_leap(y); + tm->tm_mon = day_of_year_month[leap][doy]-1; + tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ; +#else + int32_t y; + unsigned m, d; + civil_from_days(days_since_epoch, y, m, d); + tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d; +#endif + + tm->tm_hour = hms / 3600; + const int ms = hms % 3600; + tm->tm_min = ms / 60; + tm->tm_sec = ms % 60; + + tm->tm_isdst = -1; + (void)mktime(tm); + return tm; + } + + } // detail +#ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT + +#if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT + + template + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_point& tp) + { + typename std::basic_ostream::sentry ok(os); + if (bool(ok)) + { + bool failed = false; + BOOST_TRY + { + const CharT* pb = 0; //nullptr; + const CharT* pe = pb; + std::basic_string fmt = get_time_fmt (os); + pb = fmt.data(); + pe = pb + fmt.size(); + + timezone tz = get_timezone(os); + std::locale loc = os.getloc(); + time_t t = system_clock::to_time_t(time_point_cast(tp)); + std::tm tm; + std::memset(&tm, 0, sizeof(std::tm)); + if (tz == timezone::local) + { +#if defined BOOST_WINDOWS && ! defined(__CYGWIN__) +#if BOOST_MSVC < 1400 // localtime_s doesn't exist in vc7.1 + std::tm *tmp = 0; + if ((tmp=localtime(&t)) == 0) + failed = true; + else + tm =*tmp; +# else + if (localtime_s(&tm, &t) != 0) failed = true; +# endif +#else + if (localtime_r(&t, &tm) == 0) failed = true; +#endif + } + else + { +#if defined BOOST_CHRONO_INTERNAL_GMTIME + if (detail::internal_gmtime(&t, &tm) == 0) failed = true; + +#elif defined BOOST_WINDOWS && ! defined(__CYGWIN__) + std::tm *tmp = 0; + if((tmp = gmtime(&t)) == 0) + failed = true; + else + tm = *tmp; +#else + if (gmtime_r(&t, &tm) == 0) failed = true; + tm.tm_isdst = -1; + (void)mktime(&tm); + +#endif + + } + if (!failed) + { + const std::time_put& tpf = std::use_facet >(loc); + if (pb == pe) + { + CharT pattern[] = + { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' }; + pb = pattern; + pe = pb + sizeof (pattern) / sizeof(CharT); + failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed(); + if (!failed) + { + duration d = tp - system_clock::from_time_t(t) + seconds(tm.tm_sec); + if (d.count() < 10) os << CharT('0'); + //if (! os.good()) { + // throw "exception"; + //} + std::ios::fmtflags flgs = os.flags(); + os.setf(std::ios::fixed, std::ios::floatfield); + //if (! os.good()) { + //throw "exception"; + //} + os.precision(9); + os << d.count(); + //if (! os.good()) { + //throw "exception"; + //} + os.flags(flgs); + if (tz == timezone::local) + { + CharT sub_pattern[] = + { ' ', '%', 'z' }; + pb = sub_pattern; + pe = pb + +sizeof (sub_pattern) / sizeof(CharT); + failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed(); + } + else + { + CharT sub_pattern[] = + { ' ', '+', '0', '0', '0', '0', 0 }; + os << sub_pattern; + } + } + } + else + { + failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed(); + } + } + } + BOOST_CATCH (...) + { + failed = true; + } + BOOST_CATCH_END + if (failed) + { + os.setstate(std::ios_base::failbit | std::ios_base::badbit); + } + } + return os; + } +#endif + + namespace detail + { + + template + minutes extract_z(InputIterator& b, InputIterator e, std::ios_base::iostate& err, const std::ctype& ct) + { + int min = 0; + if (b != e) + { + char cn = ct.narrow(*b, 0); + if (cn != '+' && cn != '-') + { + err |= std::ios_base::failbit; + return minutes(0); + } + int sn = cn == '-' ? -1 : 1; + int hr = 0; + for (int i = 0; i < 2; ++i) + { + if (++b == e) + { + err |= std::ios_base::eofbit | std::ios_base::failbit; + return minutes(0); + } + cn = ct.narrow(*b, 0); + if (! ('0' <= cn && cn <= '9')) + { + err |= std::ios_base::failbit; + return minutes(0); + } + hr = hr * 10 + cn - '0'; + } + for (int i = 0; i < 2; ++i) + { + if (++b == e) + { + err |= std::ios_base::eofbit | std::ios_base::failbit; + return minutes(0); + } + cn = ct.narrow(*b, 0); + if (! ('0' <= cn && cn <= '9')) + { + err |= std::ios_base::failbit; + return minutes(0); + } + min = min * 10 + cn - '0'; + } + if (++b == e) { + err |= std::ios_base::eofbit; + } + min += hr * 60; + min *= sn; + } + else + { + err |= std::ios_base::eofbit | std::ios_base::failbit; + } + return minutes(min); + } + + } // detail + +#if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT + + template + std::basic_istream& + operator>>(std::basic_istream& is, time_point& tp) + { + typename std::basic_istream::sentry ok(is); + if (bool(ok)) + { + std::ios_base::iostate err = std::ios_base::goodbit; + BOOST_TRY + { + const CharT* pb = 0; //nullptr; + const CharT* pe = pb; + std::basic_string fmt = get_time_fmt (is); + pb = fmt.data(); + pe = pb + fmt.size(); + + timezone tz = get_timezone(is); + std::locale loc = is.getloc(); + const std::time_get& tg = std::use_facet >(loc); + const std::ctype& ct = std::use_facet >(loc); + tm tm; // {0} + std::memset(&tm, 0, sizeof(std::tm)); + + typedef std::istreambuf_iterator It; + if (pb == pe) + { + CharT pattern[] = + { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' }; + pb = pattern; + pe = pb + sizeof (pattern) / sizeof(CharT); + +#if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET + const detail::time_get& dtg(tg); + dtg.get(is, 0, is, err, &tm, pb, pe); +#else + tg.get(is, 0, is, err, &tm, pb, pe); +#endif + if (err & std::ios_base::failbit) goto exit; + fractional_seconds sec; + CharT c = CharT(); + std::ios::fmtflags flgs = is.flags(); + is.setf(std::ios::fixed, std::ios::floatfield); + is.precision(9); + is >> sec; + is.flags(flgs); + if (is.fail()) + { + err |= std::ios_base::failbit; + goto exit; + } + It i(is); + It eof; + c = *i; + if (++i == eof || c != ' ') + { + err |= std::ios_base::failbit; + goto exit; + } + minutes min = detail::extract_z(i, eof, err, ct); + + if (err & std::ios_base::failbit) goto exit; + time_t t; + +#if defined BOOST_CHRONO_INTERNAL_TIMEGM + t = detail::internal_timegm(&tm); +#else + t = timegm(&tm); +#endif + tp = time_point_cast( + system_clock::from_time_t(t) - min + round (duration (sec)) + ); + } + else + { + const CharT z[2] = + { '%', 'z' }; + const CharT* fz = std::search(pb, pe, z, z + 2); +#if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET + const detail::time_get& dtg(tg); + dtg.get(is, 0, is, err, &tm, pb, fz); +#else + tg.get(is, 0, is, err, &tm, pb, fz); +#endif + minutes minu(0); + if (fz != pe) + { + if (err != std::ios_base::goodbit) + { + err |= std::ios_base::failbit; + goto exit; + } + It i(is); + It eof; + minu = detail::extract_z(i, eof, err, ct); + if (err & std::ios_base::failbit) goto exit; + if (fz + 2 != pe) + { + if (err != std::ios_base::goodbit) + { + err |= std::ios_base::failbit; + goto exit; + } +#if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET + const detail::time_get& dtg(tg); + dtg.get(is, 0, is, err, &tm, fz + 2, pe); +#else + tg.get(is, 0, is, err, &tm, fz + 2, pe); +#endif + if (err & std::ios_base::failbit) goto exit; + } + } + tm.tm_isdst = -1; + time_t t; + if (tz == timezone::utc || fz != pe) + { +#if defined BOOST_CHRONO_INTERNAL_TIMEGM + t = detail::internal_timegm(&tm); +#else + t = timegm(&tm); +#endif + } + else + { + t = mktime(&tm); + } + tp = time_point_cast( + system_clock::from_time_t(t) - minu + ); + } + } + BOOST_CATCH (...) + { + err |= std::ios_base::badbit | std::ios_base::failbit; + } + BOOST_CATCH_END + exit: is.setstate(err); + } + return is; + } + +#endif +#endif //UTC + } // chrono + +} + +#endif // header diff --git a/boost/chrono/io/time_point_put.hpp b/boost/chrono/io/time_point_put.hpp new file mode 100644 index 00000000..9c8c7cad --- /dev/null +++ b/boost/chrono/io/time_point_put.hpp @@ -0,0 +1,261 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// 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). +// + +/** + * Duration formatting facet for output. + */ +#ifndef BOOST_CHRONO_IO_TIME_POINT_PUT_HPP +#define BOOST_CHRONO_IO_TIME_POINT_PUT_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace chrono + { + + /** + * @tparam ChatT a character type + * @tparam OutputIterator a model of @c OutputIterator + * + * The @c time_point_put facet provides facilities for formatted output of @c time_point values. + * The member function of @c time_point_put take a @c time_point and format it into character string representation. + * + */ + template > + class time_point_put: public std::locale::facet + { + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of character string passed to member functions. + */ + typedef std::basic_string string_type; + /** + * Type of iterator used to write in the character buffer. + */ + typedef OutputIterator iter_type; + + /** + * Construct a time_point_put facet. + * @param refs + * @Effects Construct a time_point_put facet. + * If the @c refs argument is @c 0 then destruction of the object is + * delegated to the @c locale, or locales, containing it. This allows + * the user to ignore lifetime management issues. On the other had, + * if @c refs is @c 1 then the object must be explicitly deleted; + * the @c locale will not do so. In this case, the object can be + * maintained across the lifetime of multiple locales. + */ + explicit time_point_put(size_t refs = 0) : + std::locale::facet(refs) + { + } + + /** + * @param i an output stream iterator + * @param ios a reference to a ios_base + * @param fill the character used as filler + * @param tp the @c time_point + * @param pattern begin of the formatting pattern + * @param pat_end end of the formatting pattern + * + * @Effects Steps through the sequence from @c pattern to @c pat_end, + * identifying characters that are part of a pattern sequence. Each character + * that is not part of a pattern sequence is written to @c s immediately, and + * each pattern sequence, as it is identified, results in a call to + * @c put_duration or @c put_epoch; + * thus, pattern elements and other characters are interleaved in the output + * in the order in which they appear in the pattern. Pattern sequences are + * identified by converting each character @c c to a @c char value as if by + * @c ct.narrow(c,0), where @c ct is a reference to @c ctype obtained from + * @c ios.getloc(). The first character of each sequence is equal to @c '%', + * followed by a pattern specifier character @c spec, which can be @c 'd' for + * the duration value or @c 'e' for the epoch. + * For each valid pattern sequence identified, calls + * put_duration(s, ios, fill, tp.time_since_epoch()) or put_epoch(s, ios). + * + * @Returns An iterator pointing immediately after the last character produced. + */ + + template + iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point const& tp, const CharT* pattern, + const CharT* pat_end) const + { + if (std::has_facet >(ios.getloc())) + { + time_point_units const &facet = + std::use_facet >(ios.getloc()); + return put(facet, i, ios, fill, tp, pattern, pat_end); + } + else + { + time_point_units_default facet; + return put(facet, i, ios, fill, tp, pattern, pat_end); + } + } + + template + iter_type put(time_point_units const& units_facet, iter_type s, std::ios_base& ios, char_type fill, + time_point const& tp, const CharT* pattern, const CharT* pat_end) const + { + + const std::ctype& ct = std::use_facet >(ios.getloc()); + for (; pattern != pat_end; ++pattern) + { + if (ct.narrow(*pattern, 0) == '%') + { + if (++pattern == pat_end) + { + *s++ = pattern[-1]; + break; + } + char fmt = ct.narrow(*pattern, 0); + switch (fmt) + { + case 'd': + { + s = put_duration(s, ios, fill, tp.time_since_epoch()); + break; + } + case 'e': + { + s = put_epoch (units_facet, s, ios); + break; + } + default: + BOOST_ASSERT(false && "Boost::Chrono internal error."); + break; + } + } + else + *s++ = *pattern; + } + return s; + } + + /** + * @param i an output stream iterator + * @param ios a reference to a ios_base + * @param fill the character used as filler + * @param tp the @c time_point + * @param pattern begin of the formatting pattern + * @param pat_end end of the formatting pattern + * + * @Effects Stores the time_point pattern from the @c time_point_unit facet in let say @c str. Last as if + * @code + * return put(s, ios, dill, tp, str.data(), str.data() + str.size()); + * @endcode + * @Returns An iterator pointing immediately after the last character produced. + */ + template + iter_type put(iter_type i, std::ios_base& ios, char_type fill, time_point const& tp) const + { + if (std::has_facet >(ios.getloc())) + { + time_point_units const &facet = + std::use_facet >(ios.getloc()); + std::basic_string str = facet.get_pattern(); + return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size()); + } + else + { + time_point_units_default facet; + std::basic_string str = facet.get_pattern(); + return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size()); + } + } + + /** + * @param i an output stream iterator + * @param ios a reference to a ios_base + * @param fill the character used as filler + * @param d the @c duration + * @Effects As if facet.put(s, ios, fill, d) where facet is the @c duration_put facet associated + * to the @c ios or a new instance of @c duration_put. + * @Returns An iterator pointing immediately after the last character produced. + */ + template + iter_type put_duration(iter_type i, std::ios_base& ios, char_type fill, duration const& d) const + { + if (std::has_facet >(ios.getloc())) + { + duration_put const &facet = std::use_facet >(ios.getloc()); + return facet.put(i, ios, fill, d); + } + else + { + duration_put facet; + return facet.put(i, ios, fill, d); + } + } + + /** + * + * @param i an output stream iterator + * @param ios a reference to a ios_base + * @Effects As if + * @code + * string_type str = facet.template get_epoch(); + * s=std::copy(str.begin(), str.end(), s); + * @endcode + * where facet is the @c time_point_units facet associated + * to the @c ios or a new instance of @c time_point_units_default. + * @Returns s, iterator pointing immediately after the last character produced. + */ + + template + iter_type put_epoch(iter_type i, std::ios_base& os) const + { + if (std::has_facet >(os.getloc())) + { + time_point_units const &facet = std::use_facet >(os.getloc()); + return put_epoch (facet, i, os); + } + else + { + time_point_units_default facet; + return put_epoch (facet, i, os); + } + } + + template + iter_type put_epoch(time_point_units const& facet, iter_type s, std::ios_base&) const + { + string_type str = facet.template get_epoch(); + s= std::copy(str.begin(), str.end(), s); + return s; + } + + /** + * Unique identifier for this type of facet. + */ + static std::locale::id id; + + /** + * @Effects Destroy the facet + */ + ~time_point_put() + { + } + + }; + + template + std::locale::id time_point_put::id; + + } // chrono +} // boost + +#endif // header diff --git a/boost/chrono/io/time_point_units.hpp b/boost/chrono/io/time_point_units.hpp new file mode 100644 index 00000000..6a4999a5 --- /dev/null +++ b/boost/chrono/io/time_point_units.hpp @@ -0,0 +1,260 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2011 Vicente J. Botet Escriba +// Copyright (c) Microsoft Corporation 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). +// + +#ifndef BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP +#define BOOST_CHRONO_IO_TIME_POINT_UNITS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace chrono + { + /** + * customization point to the epoch associated to the clock @c Clock + * The default calls @c f.do_get_epoch(Clock()). The user can overload this function. + * @return the string epoch associated to the @c Clock + */ + template + std::basic_string get_epoch_custom(Clock, TPUFacet& f) + { + return f.do_get_epoch(Clock()); + } + + /** + * @c time_point_units facet gives useful information about the time_point pattern, + * the text associated to a time_point's epoch, + */ + template + class time_point_units: public std::locale::facet + { + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of character string used by member functions. + */ + typedef std::basic_string string_type; + + /** + * Unique identifier for this type of facet. + */ + static std::locale::id id; + + /** + * Construct a @c time_point_units facet. + * @param refs + * @Effects Construct a @c time_point_units facet. + * If the @c refs argument is @c 0 then destruction of the object is + * delegated to the @c locale, or locales, containing it. This allows + * the user to ignore lifetime management issues. On the other had, + * if @c refs is @c 1 then the object must be explicitly deleted; + * the @c locale will not do so. In this case, the object can be + * maintained across the lifetime of multiple locales. + */ + explicit time_point_units(size_t refs = 0) : + std::locale::facet(refs) + { + } + + /** + * @return the pattern to be used by default. + */ + virtual string_type get_pattern() const =0; + + /** + * @return the epoch associated to the clock @c Clock calling @c do_get_epoch(Clock()) + */ + template + string_type get_epoch() const + { + return get_epoch_custom(Clock(), *this); + } + + protected: + /** + * Destroy the facet. + */ + virtual ~time_point_units() {} + + public: + + /** + * + * @param c a dummy instance of @c system_clock. + * @return The epoch string associated to the @c system_clock. + */ + virtual string_type do_get_epoch(system_clock) const=0; + + /** + * + * @param c a dummy instance of @c steady_clock. + * @return The epoch string associated to the @c steady_clock. + */ + virtual string_type do_get_epoch(steady_clock) const=0; + +#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS) + /** + * + * @param c a dummy instance of @c process_real_cpu_clock. + * @return The epoch string associated to the @c process_real_cpu_clock. + */ + virtual string_type do_get_epoch(process_real_cpu_clock) const=0; +#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP + /** + * + * @param c a dummy instance of @c process_user_cpu_clock. + * @return The epoch string associated to the @c process_user_cpu_clock. + */ + virtual string_type do_get_epoch(process_user_cpu_clock) const=0; + /** + * + * @param c a dummy instance of @c process_system_cpu_clock. + * @return The epoch string associated to the @c process_system_cpu_clock. + */ + virtual string_type do_get_epoch(process_system_cpu_clock) const=0; + /** + * + * @param c a dummy instance of @c process_cpu_clock. + * @return The epoch string associated to the @c process_cpu_clock. + */ + virtual string_type do_get_epoch(process_cpu_clock) const=0; +#endif +#endif +#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK) + /** + * + * @param c a dummy instance of @c thread_clock. + * @return The epoch string associated to the @c thread_clock. + */ + virtual string_type do_get_epoch(thread_clock) const=0; +#endif + + }; + + template + std::locale::id time_point_units::id; + + + // This class is used to define the strings for the default English + template + class time_point_units_default: public time_point_units + { + public: + /** + * Type of character the facet is instantiated on. + */ + typedef CharT char_type; + /** + * Type of character string returned by member functions. + */ + typedef std::basic_string string_type; + + explicit time_point_units_default(size_t refs = 0) : + time_point_units (refs) + { + } + ~time_point_units_default() {} + + /** + * @return the default pattern "%d%e". + */ + string_type get_pattern() const + { + static const CharT t[] = + { '%', 'd', '%', 'e' }; + static const string_type pattern(t, t + sizeof (t) / sizeof (t[0])); + + return pattern; + } + + //protected: + /** + * @param c a dummy instance of @c system_clock. + * @return The epoch string returned by @c clock_string::since(). + */ + string_type do_get_epoch(system_clock ) const + { + return clock_string::since(); + } + /** + * @param c a dummy instance of @c steady_clock. + * @return The epoch string returned by @c clock_string::since(). + */ + string_type do_get_epoch(steady_clock ) const + { + return clock_string::since(); + } + +#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS) + /** + * @param c a dummy instance of @c process_real_cpu_clock. + * @return The epoch string returned by @c clock_string::since(). + */ + string_type do_get_epoch(process_real_cpu_clock ) const + { + return clock_string::since(); + } +#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP + /** + * @param c a dummy instance of @c process_user_cpu_clock. + * @return The epoch string returned by @c clock_string::since(). + */ + string_type do_get_epoch(process_user_cpu_clock ) const + { + return clock_string::since(); + } + /** + * @param c a dummy instance of @c process_system_cpu_clock. + * @return The epoch string returned by @c clock_string::since(). + */ + string_type do_get_epoch(process_system_cpu_clock ) const + { + return clock_string::since(); + } + /** + * @param c a dummy instance of @c process_cpu_clock. + * @return The epoch string returned by @c clock_string::since(). + */ + string_type do_get_epoch(process_cpu_clock ) const + { + return clock_string::since(); + } + +#endif +#endif +#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK) + /** + * @param c a dummy instance of @c thread_clock. + * @return The epoch string returned by @c clock_string::since(). + */ + string_type do_get_epoch(thread_clock ) const + { + return clock_string::since(); + } +#endif + + }; + + + } // chrono + +} // boost + +#endif // header diff --git a/boost/chrono/io/timezone.hpp b/boost/chrono/io/timezone.hpp new file mode 100644 index 00000000..67975da9 --- /dev/null +++ b/boost/chrono/io/timezone.hpp @@ -0,0 +1,30 @@ +// (C) Copyright Howard Hinnant +// (C) Copyright 2010-2011 Vicente J. Botet Escriba +// 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 code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o to Boost + +#ifndef BOOST_CHRONO_IO_TIMEZONE_HPP +#define BOOST_CHRONO_IO_TIMEZONE_HPP +#include + +namespace boost +{ + namespace chrono + { + /** + * Scoped enumeration emulation stating whether the time_point for system_clock I/O is UTC or local. + */ + BOOST_SCOPED_ENUM_DECLARE_BEGIN(timezone) + { + utc, local + } + BOOST_SCOPED_ENUM_DECLARE_END(timezone) + + } // chrono +} // boost + +#endif // header diff --git a/boost/chrono/io/utility/ios_base_state_ptr.hpp b/boost/chrono/io/utility/ios_base_state_ptr.hpp new file mode 100644 index 00000000..15c8ac4d --- /dev/null +++ b/boost/chrono/io/utility/ios_base_state_ptr.hpp @@ -0,0 +1,437 @@ +// boost/chrono/utility/ios_base_pword_ptr.hpp ------------------------------------------------------------// + +// Copyright 2011 Vicente J. Botet Escriba + +// 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/chrono for documentation. + +#ifndef BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP +#define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP + +#include +#include + +/** + * + + + */ +namespace boost +{ + namespace chrono + { + namespace detail + { + + /** + * xalloc key holder. + */ + template + struct xalloc_key_holder + { + static int value; //< the xalloc value associated to T. + static bool initialized; //< whether the value has been initialized or not. + }; + + template + int xalloc_key_holder::value = 0; + + template + bool xalloc_key_holder::initialized = false; + + } + + /** + * xalloc key initialiazer. + * + * Declare a static variable of this type to ensure that the xalloc_key_holder is initialized correctly. + */ + template + struct xalloc_key_initializer + { + xalloc_key_initializer() + { + if (!detail::xalloc_key_holder::initialized) + { + detail::xalloc_key_holder::value = std::ios_base::xalloc(); + detail::xalloc_key_holder::initialized = true; + } + } + }; + /** + * @c ios_state_ptr is a smart pointer to a ios_base specific state. + */ + template + class ios_state_ptr + { + ios_state_ptr& operator=(ios_state_ptr const& rhs) ; + + public: + /** + * The pointee type + */ + typedef T element_type; + /** + * Explicit constructor. + * @param ios the ios + * @Effects Constructs a @c ios_state_ptr by storing the associated @c ios. + */ + explicit ios_state_ptr(std::ios_base& ios) : + ios_(ios) + { + + } + /** + * Nothing to do as xalloc index can not be removed. + */ + ~ios_state_ptr() + { + } + + /** + * @Effects Allocates the index if not already done. + * Registers the callback responsible of maintaining the state pointer coherency, if not already done. + * Retrieves the associated ios pointer + * @return the retrieved pointer statically casted to const. + */ + T const* get() const BOOST_NOEXCEPT + { + register_once(index(), ios_); + void* &pw = ios_.pword(index()); + if (pw == 0) + { + return 0; + } + return static_cast (pw); + } + /** + * @Effects Allocates the index if not already done. + * Registers the callback responsible of maintaining the state pointer coherency, if not already done. + * Retrieves the associated ios pointer + * @return the retrieved pointer. + */ + T * get() BOOST_NOEXCEPT + { + register_once(index(), ios_); + void* &pw = ios_.pword(index()); + if (pw == 0) + { + return 0; + } + return static_cast (pw); + } + /** + * @Effects as if @c return get(); + * @return the retrieved pointer. + */ + T * operator->()BOOST_NOEXCEPT + { + return get(); + } + /** + * @Effects as if @c return get(); + * @return the retrieved pointer. + */ + T const * operator->() const BOOST_NOEXCEPT + { + return get(); + } + + /** + * @Effects as if @c return *get(); + * @return a reference to the retrieved state. + * @Remark The behavior is undefined if @c get()==0. + */ + T & operator*() BOOST_NOEXCEPT + { + return *get(); + } + /** + * @Effects as if @c return *get(); + * @return a reference to the retrieved state. + * @Remark The behavior is undefined if @c get()==0. + */ + T const & operator *() const BOOST_NOEXCEPT + { + return *get(); + } + + /** + * @Effects reset the current pointer after storing in a temporary variable the pointer to the current state. + * @return the stored state pointer. + */ + T * release() BOOST_NOEXCEPT + { + void*& pw = ios_.pword(index()); + T* ptr = static_cast (pw); + pw = 0; + return ptr; + } + + /** + * + * @param new_ptr the new pointer. + * @Effects deletes the current state and replace it with the new one. + */ + void reset(T* new_ptr = 0)BOOST_NOEXCEPT + { + register_once(index(), ios_); + void*& pw = ios_.pword(index()); + delete static_cast (pw); + pw = new_ptr; + } + +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + typedef T* (ios_state_ptr::*bool_type)(); + operator bool_type() const BOOST_NOEXCEPT + { + return (get()!=0)?&ios_state_ptr::release:0; + } + bool operator!() const BOOST_NOEXCEPT + { + return (get()==0)?&ios_state_ptr::release:0; + } +#else + /** + * Explicit conversion to bool. + */ + explicit operator bool() const BOOST_NOEXCEPT + { + return get()!=0; + } +#endif + + std::ios_base& getios()BOOST_NOEXCEPT + { + return ios_; + } + std::ios_base& getios() const BOOST_NOEXCEPT + { + return ios_; + } + /** + * Implicit conversion to the ios_base + */ + operator std::ios_base&() BOOST_NOEXCEPT + { + return ios_; + } + /** + * Implicit conversion to the ios_base const + */ + operator std::ios_base&() const BOOST_NOEXCEPT + { + return ios_; + } + private: + static inline bool is_registerd(std::ios_base& ios) + { + long iw = ios.iword(index()); + return (iw == 1); + } + static inline void set_registered(std::ios_base& ios) + { + long& iw = ios.iword(index()); + iw = 1; + } + static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index) + { + switch (evt) + { + case std::ios_base::erase_event: + { + void*& pw = ios.pword(index); + if (pw != 0) + { + T* ptr = static_cast (pw); + delete ptr; + pw = 0; + } + break; + } + case std::ios_base::copyfmt_event: + { + void*& pw = ios.pword(index); + if (pw != 0) + { + pw = new T(*static_cast (pw)); + } + break; + } + default: + break; + } + } + + static inline int index() + { + return detail::xalloc_key_holder::value; + } + + static inline void register_once(int indx, std::ios_base& ios) + { + // needs a mask registered + if (!is_registerd(ios)) + { + set_registered(ios); + ios.register_callback(callback, indx); + } + } + + + protected: + std::ios_base& ios_; + //static detail::xalloc_key_initializer xalloc_key_initializer_; + + }; + //template + //detail::xalloc_key_initializer ios_state_ptr::xalloc_key_initializer_; + + + /** + * @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr. + * @tparm T + * @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable + */ + template + class ios_state_not_null_ptr: public ios_state_ptr + { + typedef ios_state_ptr base_type; + public: + explicit ios_state_not_null_ptr(std::ios_base& ios) : + base_type(ios) + { + if (this->get() == 0) + { + this->base_type::reset(new T()); + } + } + ~ios_state_not_null_ptr() + { + } + + void reset(T* new_value) BOOST_NOEXCEPT + { + BOOST_ASSERT(new_value!=0); + this->base_type::reset(new_value); + } + + }; + + /** + * This class is useful to associate some flags to an std::ios_base. + */ + template + class ios_flags + { + public: + /** + * + * @param ios the associated std::ios_base. + * @Postcondition flags()==0 + */ + explicit ios_flags(std::ios_base& ios) : + ios_(ios) + { + } + ~ios_flags() + { + } + /** + * @Returns The format control information. + */ + long flags() const BOOST_NOEXCEPT + { + return value(); + } + + /** + * @param v the new bit mask. + * @Postcondition v == flags(). + * @Returns The previous value of @c flags(). + */ + long flags(long v)BOOST_NOEXCEPT + { + long tmp = flags(); + ref() = v; + return tmp; + } + + /** + * @param v the new value + * @Effects: Sets @c v in @c flags(). + * @Returns: The previous value of @c flags(). + */ + long setf(long v) + { + long tmp = value(); + ref() |= v; + return tmp; + } + + /** + * @param mask the bit mask to clear. + * @Effects: Clears @c mask in @c flags(). + */ + void unsetf(long mask) + { + ref() &= ~mask; + } + + /** + * + * @param v + * @param mask + * @Effects: Clears @c mask in @c flags(), sets v & mask in @c flags(). + * @Returns: The previous value of flags(). + */ + long setf(long v, long mask) + { + long tmp = value(); + unsetf(mask); + ref() |= v & mask; + return tmp; + } + + /** + * implicit conversion to the @c ios_base + */ + operator std::ios_base&()BOOST_NOEXCEPT + { + return ios_; + } + /** + * implicit conversion to the @c ios_base const + */ + operator std::ios_base const&() const BOOST_NOEXCEPT + { + return ios_; + } + private: + long value() const BOOST_NOEXCEPT + { + return ios_.iword(index()); + } + long& ref()BOOST_NOEXCEPT + { + return ios_.iword(index()); + } + static inline int index() + { + return detail::xalloc_key_holder::value; + } + ios_flags& operator=(ios_flags const& rhs) ; + + std::ios_base& ios_; + //static detail::xalloc_key_initializer xalloc_key_initializer_; + + }; + //template + //detail::xalloc_key_initializer ios_flags::xalloc_key_initializer_; + + } // namespace chrono +} // namespace boost + +#endif // header diff --git a/boost/chrono/io/utility/manip_base.hpp b/boost/chrono/io/utility/manip_base.hpp new file mode 100644 index 00000000..f4a5f562 --- /dev/null +++ b/boost/chrono/io/utility/manip_base.hpp @@ -0,0 +1,101 @@ +// boost/chrono/utility/manip_base.hpp ------------------------------------------------------------// + +// Copyright 2011 Vicente J. Botet Escriba + +// 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/chrono for documentation. + +#ifndef BOOST_CHRONO_UTILITY_MANIP_BASE_PTR_HPP +#define BOOST_CHRONO_UTILITY_MANIP_BASE_PTR_HPP + +#include + +/** + * + + */ + +namespace boost +{ + namespace chrono + { + + /** + * manip is a manipulator mixin class following the CRTP. + * @tparam Final the derived from manip and final type + * + * @Example + * @code + + class mendl: public manip + { + public: + explicit mendl(size_t how_many) : + count(how_many) {} + template + void operator()(out_stream &out) const + { + for (size_t line = 0; line < count; ++line) + { + out.put(out.widen('\n')); + } + out.flush(); + } + private: + size_t count; + }; + + * @codeend + */ + template + class manip + { + public: + /** + * + * @param ios the io stream or ios_base. + * @Effects calls to the manipulator final functor. + */ + //template + void operator()(std::ios_base &ios) const + { + (*static_cast (this))(ios); + } + }; + + /** + * @c manip stream inserter + * @param out the io stream or ios_base. + * @param op the manipulator instance. + * @Effects if @c out is good calls to the manipulator functor @op. + * @return @c out + */ + template + out_stream &operator<<(out_stream &out, const manip &op) + { + if (out.good()) + op(out); + return out; + } + + /** + * @c manip stream extractor + * @param in the io stream or ios_base. + * @param op the manipulator instance. + * @Effects if @c in is good calls to the manipulator functor @op. + * @return @c in + */ + template + in_stream &operator>>(in_stream &in, const manip &op) + { + if (in.good()) + op(in); + return in; + } + + } // namespace chrono +} // namespace boost + +#endif // header diff --git a/boost/chrono/io/utility/to_string.hpp b/boost/chrono/io/utility/to_string.hpp new file mode 100644 index 00000000..4717ba6a --- /dev/null +++ b/boost/chrono/io/utility/to_string.hpp @@ -0,0 +1,50 @@ +// boost/chrono/utility/to_string.hpp +// +// Copyright 2011 Vicente J. Botet Escriba +// 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_CHRONO_UTILITY_TO_STRING_HPP +#define BOOST_CHRONO_UTILITY_TO_STRING_HPP + +#include +#include +#include + +namespace boost +{ + namespace chrono + { + template + std::basic_string to_basic_string(T const&v) { + std::basic_stringstream sstr; + sstr << v; + return sstr.str(); + } + + template + std::string to_string(T const&v) { + return to_basic_string(v); + } +#ifndef BOOST_NO_STD_WSTRING + template + std::wstring to_wstring(T const&v) { + return to_basic_string(v); + } +#endif +#if BOOST_CHRONO_HAS_UNICODE_SUPPORT + template + std::basic_string to_u16string(T const&v) { + return to_basic_string(v); + } + template + std::basic_string to_u32string(T const&v) { + return to_basic_string(v); + } +#endif + } // chrono + +} // boost + +#endif // header diff --git a/boost/chrono/io_v1/chrono_io.hpp b/boost/chrono/io_v1/chrono_io.hpp new file mode 100644 index 00000000..afcc9ed7 --- /dev/null +++ b/boost/chrono/io_v1/chrono_io.hpp @@ -0,0 +1,635 @@ + +// chrono_io +// +// (C) Copyright Howard Hinnant +// (C) Copyright 2010 Vicente J. Botet Escriba +// 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 code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o under lvm/libc++ to Boost + +#ifndef BOOST_CHRONO_IO_V1_CHRONO_IO_HPP +#define BOOST_CHRONO_IO_V1_CHRONO_IO_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +namespace chrono +{ + +template +class duration_punct + : public std::locale::facet +{ +public: + typedef std::basic_string string_type; + enum {use_long, use_short}; + +private: + bool use_short_; + string_type long_seconds_; + string_type long_minutes_; + string_type long_hours_; + string_type short_seconds_; + string_type short_minutes_; + string_type short_hours_; + + template + string_type short_name(Period) const + {return ::boost::ratio_string::short_name() + short_seconds_;} + + string_type short_name(ratio<1>) const {return short_seconds_;} + string_type short_name(ratio<60>) const {return short_minutes_;} + string_type short_name(ratio<3600>) const {return short_hours_;} + + template + string_type long_name(Period) const + {return ::boost::ratio_string::long_name() + long_seconds_;} + + string_type long_name(ratio<1>) const {return long_seconds_;} + string_type long_name(ratio<60>) const {return long_minutes_;} + string_type long_name(ratio<3600>) const {return long_hours_;} + + void init_C(); +public: + static std::locale::id id; + + explicit duration_punct(int use = use_long) + : use_short_(use==use_short) {init_C();} + + duration_punct(int use, + const string_type& long_seconds, const string_type& long_minutes, + const string_type& long_hours, const string_type& short_seconds, + const string_type& short_minutes, const string_type& short_hours); + + duration_punct(int use, const duration_punct& d); + + template + string_type short_name() const + {return short_name(typename Period::type());} + + template + string_type long_name() const + {return long_name(typename Period::type());} + + template + string_type plural() const + {return long_name(typename Period::type());} + + template + string_type singular() const + { + return string_type(long_name(typename Period::type()), 0, long_name(typename Period::type()).size()-1); + } + + template + string_type name() const + { + if (use_short_) return short_name(); + else { + return long_name(); + } + } + template + string_type name(D v) const + { + if (use_short_) return short_name(); + else + { + if (v==-1 || v==1) + return singular(); + else + return plural(); + } + } + + bool is_short_name() const {return use_short_;} + bool is_long_name() const {return !use_short_;} +}; + +template +std::locale::id +duration_punct::id; + +template +void +duration_punct::init_C() +{ + short_seconds_ = CharT('s'); + short_minutes_ = CharT('m'); + short_hours_ = CharT('h'); + const CharT s[] = {'s', 'e', 'c', 'o', 'n', 'd', 's'}; + const CharT m[] = {'m', 'i', 'n', 'u', 't', 'e', 's'}; + const CharT h[] = {'h', 'o', 'u', 'r', 's'}; + long_seconds_.assign(s, s + sizeof(s)/sizeof(s[0])); + long_minutes_.assign(m, m + sizeof(m)/sizeof(m[0])); + long_hours_.assign(h, h + sizeof(h)/sizeof(h[0])); +} + +template +duration_punct::duration_punct(int use, + const string_type& long_seconds, const string_type& long_minutes, + const string_type& long_hours, const string_type& short_seconds, + const string_type& short_minutes, const string_type& short_hours) + : use_short_(use==use_short), + long_seconds_(long_seconds), + long_minutes_(long_minutes), + long_hours_(long_hours), + short_seconds_(short_seconds), + short_minutes_(short_minutes), + short_hours_(short_hours) +{} + +template +duration_punct::duration_punct(int use, const duration_punct& d) + : use_short_(use==use_short), + long_seconds_(d.long_seconds_), + long_minutes_(d.long_minutes_), + long_hours_(d.long_hours_), + short_seconds_(d.short_seconds_), + short_minutes_(d.short_minutes_), + short_hours_(d.short_hours_) +{} + +template +std::basic_ostream& +duration_short(std::basic_ostream& os) +{ + typedef duration_punct Facet; + std::locale loc = os.getloc(); + if (std::has_facet(loc)) + { + const Facet& f = std::use_facet(loc); + if (f.is_long_name()) + os.imbue(std::locale(loc, new Facet(Facet::use_short, f))); + } + else + os.imbue(std::locale(loc, new Facet(Facet::use_short))); + return os; +} + +template +std::basic_ostream& +duration_long(std::basic_ostream& os) +{ + typedef duration_punct Facet; + std::locale loc = os.getloc(); + if (std::has_facet(loc)) + { + const Facet& f = std::use_facet(loc); + if (f.is_short_name()) + os.imbue(std::locale(loc, new Facet(Facet::use_long, f))); + } + return os; +} + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const duration& d) +{ + typedef duration_punct Facet; + std::locale loc = os.getloc(); + if (!std::has_facet(loc)) + os.imbue(std::locale(loc, new Facet)); + const Facet& f = std::use_facet(os.getloc()); + return os << d.count() << ' ' << f.template name(d.count()); +} + +namespace chrono_detail { +template ::value> +struct duration_io_intermediate +{ + typedef Rep type; +}; + +template +struct duration_io_intermediate +{ + typedef typename mpl::if_c + < + is_floating_point::value, + long double, + typename mpl::if_c + < + is_signed::value, + long long, + unsigned long long + >::type + >::type type; +}; + +template +typename enable_if, bool>::type +reduce(intermediate_type& r, unsigned long long& den, std::ios_base::iostate& err) +{ + typedef typename common_type::type common_type_t; + + // Reduce r * num / den + common_type_t t = integer::gcd(common_type_t(r), common_type_t(den)); + r /= t; + den /= t; + if (den != 1) + { + // Conversion to Period is integral and not exact + err |= std::ios_base::failbit; + return false; + } + return true; +} +template +typename disable_if, bool>::type +reduce(intermediate_type& , unsigned long long& , std::ios_base::iostate& ) +{ + return true; +} + +} + +template +std::basic_istream& +operator>>(std::basic_istream& is, duration& d) +{ + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + typedef duration_punct Facet; + std::locale loc = is.getloc(); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (!std::has_facet(loc)) { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.imbue(std::locale(loc, new Facet)); + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + loc = is.getloc(); + const Facet& f = std::use_facet(loc); + typedef typename chrono_detail::duration_io_intermediate::type intermediate_type; + intermediate_type r; + std::ios_base::iostate err = std::ios_base::goodbit; + // read value into r + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is >> r; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (is.good()) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // now determine unit + typedef std::istreambuf_iterator in_iterator; + in_iterator i(is); + in_iterator e; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (i != e && *i == ' ') // mandatory ' ' after value + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + ++i; + if (i != e) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // unit is num / den (yet to be determined) + unsigned long long num = 0; + unsigned long long den = 0; + if (*i == '[') + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // parse [N/D]s or [N/D]seconds format + ++i; + CharT x; + is >> num >> x >> den; + if (!is.good() || (x != '/')) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit); + return is; + } + i = in_iterator(is); + if (*i != ']') + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit); + return is; + } + ++i; + const std::basic_string units[] = + { + f.template singular >(), + f.template plural >(), + f.template short_name >() + }; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + const std::basic_string* k = chrono_detail::scan_keyword(i, e, + units, units + sizeof(units)/sizeof(units[0]), + //~ std::use_facet >(loc), + err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err); + switch ((k - units) / 3) + { + case 0: + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + break; + default: + is.setstate(err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + } + else + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // parse SI name, short or long + const std::basic_string units[] = + { + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular(), + f.template plural(), + f.template short_name(), + f.template singular >(), + f.template plural >(), + f.template short_name >(), + f.template singular >(), + f.template plural >(), + f.template short_name >(), + f.template singular >(), + f.template plural >(), + f.template short_name >() + }; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + const std::basic_string* k = chrono_detail::scan_keyword(i, e, + units, units + sizeof(units)/sizeof(units[0]), + //~ std::use_facet >(loc), + err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + switch ((k - units) / 3) + { + case 0: + num = 1ULL; + den = 1000000000000000000ULL; + break; + case 1: + num = 1ULL; + den = 1000000000000000ULL; + break; + case 2: + num = 1ULL; + den = 1000000000000ULL; + break; + case 3: + num = 1ULL; + den = 1000000000ULL; + break; + case 4: + num = 1ULL; + den = 1000000ULL; + break; + case 5: + num = 1ULL; + den = 1000ULL; + break; + case 6: + num = 1ULL; + den = 100ULL; + break; + case 7: + num = 1ULL; + den = 10ULL; + break; + case 8: + num = 10ULL; + den = 1ULL; + break; + case 9: + num = 100ULL; + den = 1ULL; + break; + case 10: + num = 1000ULL; + den = 1ULL; + break; + case 11: + num = 1000000ULL; + den = 1ULL; + break; + case 12: + num = 1000000000ULL; + den = 1ULL; + break; + case 13: + num = 1000000000000ULL; + den = 1ULL; + break; + case 14: + num = 1000000000000000ULL; + den = 1ULL; + break; + case 15: + num = 1000000000000000000ULL; + den = 1ULL; + break; + case 16: + num = 1; + den = 1; + break; + case 17: + num = 60; + den = 1; + break; + case 18: + num = 3600; + den = 1; + break; + default: + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // unit is num/den + // r should be multiplied by (num/den) / Period + // Reduce (num/den) / Period to lowest terms + unsigned long long gcd_n1_n2 = integer::gcd(num, Period::num); + unsigned long long gcd_d1_d2 = integer::gcd(den, Period::den); + num /= gcd_n1_n2; + den /= gcd_d1_d2; + unsigned long long n2 = Period::num / gcd_n1_n2; + unsigned long long d2 = Period::den / gcd_d1_d2; + if (num > (std::numeric_limits::max)() / d2 || + den > (std::numeric_limits::max)() / n2) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // (num/den) / Period overflows + is.setstate(err|is.failbit); + return is; + } + num *= d2; + den *= n2; + + typedef typename common_type::type common_type_t; + + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // num / den is now factor to multiply by r + if (!chrono_detail::reduce(r, den, err)) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + + //if (r > ((duration_values::max)() / num)) + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (chrono::detail::gt(r,((duration_values::max)() / num))) + { + // Conversion to Period overflowed + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + common_type_t t = r * num; + t /= den; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + + if (t > duration_values::zero()) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if ( (duration_values::max)() < Rep(t)) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // Conversion to Period overflowed + is.setstate(err|is.failbit); + return is; + } + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // Success! Store it. + d = duration(Rep(t)); + is.setstate(err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + else { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit | is.eofbit); + return is; + } + } + else + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (i == e) + is.setstate(is.failbit|is.eofbit); + else + is.setstate(is.failbit); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + } + else { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + //is.setstate(is.failbit); + return is; + } +} + + +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const time_point& tp) +{ + return os << tp.time_since_epoch() << clock_string::since(); +} + +template +std::basic_istream& +operator>>(std::basic_istream& is, + time_point& tp) +{ + Duration d; + is >> d; + if (is.good()) + { + const std::basic_string units=clock_string::since(); + std::ios_base::iostate err = std::ios_base::goodbit; + typedef std::istreambuf_iterator in_iterator; + in_iterator i(is); + in_iterator e; + std::ptrdiff_t k = chrono_detail::scan_keyword(i, e, + &units, &units + 1, + //~ std::use_facet >(is.getloc()), + err) - &units; + is.setstate(err); + if (k == 1) + { + is.setstate(err | is.failbit); + // failed to read epoch string + return is; + } + tp = time_point(d); + } + else + is.setstate(is.failbit); + return is; +} +} // chrono + +} + +#endif // BOOST_CHRONO_CHRONO_IO_HPP diff --git a/boost/chrono/process_cpu_clocks.hpp b/boost/chrono/process_cpu_clocks.hpp new file mode 100644 index 00000000..93d3c94a --- /dev/null +++ b/boost/chrono/process_cpu_clocks.hpp @@ -0,0 +1,525 @@ +// boost/chrono/process_cpu_clocks.hpp -----------------------------------------------------------// + +// Copyright 2009-2011 Vicente J. Botet Escriba +// Copyright (c) Microsoft Corporation 2014 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/system for documentation. + +#ifndef BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP +#define BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP + +#include + + +#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS) + +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include // must be the last #include +#endif + +namespace boost { namespace chrono { + + class BOOST_CHRONO_DECL process_real_cpu_clock { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; + +#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP + class BOOST_CHRONO_DECL process_user_cpu_clock { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; + + class BOOST_CHRONO_DECL process_system_cpu_clock { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; +#endif + + template + struct process_times + : arithmetic, + multiplicative, Rep, + less_than_comparable > > > + { + //typedef process_real_cpu_clock::rep rep; + typedef Rep rep; + process_times() + : real(0) + , user(0) + , system(0){} + +#if ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 + template + explicit process_times( + Rep2 r) + : real(r) + , user(r) + , system(r){} +#endif + template + explicit process_times( + process_times const& rhs) + : real(rhs.real) + , user(rhs.user) + , system(rhs.system){} + process_times( + rep r, + rep u, + rep s) + : real(r) + , user(u) + , system(s){} + + rep real; // real (i.e wall clock) time + rep user; // user cpu time + rep system; // system cpu time + +#if ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0 + operator rep() const + { + return real; + } +#endif + template + bool operator==(process_times const& rhs) { + return (real==rhs.real && + user==rhs.user && + system==rhs.system); + } + + process_times& operator+=( + process_times const& rhs) + { + real+=rhs.real; + user+=rhs.user; + system+=rhs.system; + return *this; + } + process_times& operator-=( + process_times const& rhs) + { + real-=rhs.real; + user-=rhs.user; + system-=rhs.system; + return *this; + } + process_times& operator*=( + process_times const& rhs) + { + real*=rhs.real; + user*=rhs.user; + system*=rhs.system; + return *this; + } + process_times& operator*=(rep const& rhs) + { + real*=rhs; + user*=rhs; + system*=rhs; + return *this; + } + process_times& operator/=(process_times const& rhs) + { + real/=rhs.real; + user/=rhs.user; + system/=rhs.system; + return *this; + } + process_times& operator/=(rep const& rhs) + { + real/=rhs; + user/=rhs; + system/=rhs; + return *this; + } + bool operator<(process_times const & rhs) const + { + if (real < rhs.real) return true; + if (real > rhs.real) return false; + if (user < rhs.user) return true; + if (user > rhs.user) return false; + if (system < rhs.system) return true; + else return false; + } + + template + void print(std::basic_ostream& os) const + { + os << "{"<< real <<";"<< user <<";"<< system << "}"; + } + + template + void read(std::basic_istream& is) + { + typedef std::istreambuf_iterator in_iterator; + in_iterator i(is); + in_iterator e; + if (i == e || *i++ != '{') // mandatory '{' + { + is.setstate(is.failbit | is.eofbit); + return; + } + CharT x,y,z; + is >> real >> x >> user >> y >> system >> z; + if (!is.good() || (x != ';')|| (y != ';')|| (z != '}')) + { + is.setstate(is.failbit); + } + } + }; +} +template +struct common_type< + chrono::process_times, + chrono::process_times +> +{ + typedef chrono::process_times::type> type; +}; + +template +struct common_type< + chrono::process_times, + Rep2 +> +{ + typedef chrono::process_times::type> type; +}; + +template +struct common_type< + Rep1, + chrono::process_times +> +{ + typedef chrono::process_times::type> type; +}; + + +namespace chrono +{ + template + inline BOOST_CONSTEXPR + bool + operator==(const duration, Period1>& lhs, + const duration, Period2>& rhs) + { + return boost::chrono::detail::duration_eq< + duration, duration + >()(duration(lhs.count().real), duration(rhs.count().real)); + } + + template + inline BOOST_CONSTEXPR + bool + operator==(const duration, Period1>& lhs, + const duration& rhs) + { + return boost::chrono::detail::duration_eq< + duration, duration >()(duration(lhs.count().real), rhs); + } + + template + inline BOOST_CONSTEXPR + bool + operator==(const duration& lhs, + const duration, Period2>& rhs) + { + return rhs == lhs; + } + + + // Duration < + + template + inline BOOST_CONSTEXPR + bool + operator< (const duration, Period1>& lhs, + const duration& rhs) + { + return boost::chrono::detail::duration_lt< + duration, duration >()(duration(lhs.count().real), rhs); + } + + template + inline BOOST_CONSTEXPR + bool + operator< (const duration& lhs, + const duration, Period2>& rhs) + { + return boost::chrono::detail::duration_lt< + duration, duration >()(lhs, duration(rhs.count().real)); + } + + template + inline BOOST_CONSTEXPR + bool + operator< (const duration, Period1>& lhs, + const duration, Period2>& rhs) + { + return boost::chrono::detail::duration_lt< + duration, duration + >()(duration(lhs.count().real), duration(rhs.count().real)); + } + + + typedef process_times process_cpu_clock_times; +#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP + class BOOST_CHRONO_DECL process_cpu_clock + { + public: + + typedef process_cpu_clock_times times; + typedef boost::chrono::duration duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); +#endif + }; +#endif + + template + std::basic_ostream& + operator<<(std::basic_ostream& os, + process_times const& rhs) + { + rhs.print(os); + return os; + } + + template + std::basic_istream& + operator>>(std::basic_istream& is, + process_times& rhs) + { + rhs.read(is); + return is; + } + + template + struct duration_values > + { + typedef process_times Res; + public: + static Res zero() + { + return Res(); + } + static Res max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits::max)(), + (std::numeric_limits::max)(), + (std::numeric_limits::max)()); + } + static Res min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits::min)(), + (std::numeric_limits::min)(), + (std::numeric_limits::min)()); + } + }; + + template + struct clock_string + { + static std::basic_string name() + { + static const CharT + u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'r', 'e', 'a', 'l', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + +#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP + template + struct clock_string + { + static std::basic_string name() + { + static const CharT + u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'u', 's', 'e', 'r', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + + template + struct clock_string + { + static std::basic_string name() + { + static const CharT + u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 's', 'y', 's', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + + template + struct clock_string + { + static std::basic_string name() + { + static const CharT u[] = + { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string since() + { + const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; + const std::basic_string str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; +#endif + +} // namespace chrono +} // namespace boost + +namespace std { + + template + struct numeric_limits > + { + typedef boost::chrono::process_times Res; + + public: + static const bool is_specialized = true; + static Res min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits::min)(), + (std::numeric_limits::min)(), + (std::numeric_limits::min)()); + } + static Res max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return Res((std::numeric_limits::max)(), + (std::numeric_limits::max)(), + (std::numeric_limits::max)()); + } + static Res lowest() BOOST_NOEXCEPT_OR_NOTHROW + { + return (min)(); + } + static const int digits = std::numeric_limits::digits+ + std::numeric_limits::digits+ + std::numeric_limits::digits; + static const int digits10 = std::numeric_limits::digits10+ + std::numeric_limits::digits10+ + std::numeric_limits::digits10; + static const bool is_signed = Rep::is_signed; + static const bool is_integer = Rep::is_integer; + static const bool is_exact = Rep::is_exact; + static const int radix = 0; + //~ static Res epsilon() throw() { return 0; } + //~ static Res round_error() throw() { return 0; } + //~ static const int min_exponent = 0; + //~ static const int min_exponent10 = 0; + //~ static const int max_exponent = 0; + //~ static const int max_exponent10 = 0; + //~ static const bool has_infinity = false; + //~ static const bool has_quiet_NaN = false; + //~ static const bool has_signaling_NaN = false; + //~ static const float_denorm_style has_denorm = denorm_absent; + //~ static const bool has_denorm_loss = false; + //~ static Res infinity() throw() { return 0; } + //~ static Res quiet_NaN() throw() { return 0; } + //~ static Res signaling_NaN() throw() { return 0; } + //~ static Res denorm_min() throw() { return 0; } + //~ static const bool is_iec559 = false; + //~ static const bool is_bounded = true; + //~ static const bool is_modulo = false; + //~ static const bool traps = false; + //~ static const bool tinyness_before = false; + //~ static const float_round_style round_style = round_toward_zero; + + }; +} + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include // pops abi_prefix.hpp pragmas +#else +#include +#endif +#endif + +#endif // BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP diff --git a/boost/chrono/round.hpp b/boost/chrono/round.hpp new file mode 100644 index 00000000..09741fcf --- /dev/null +++ b/boost/chrono/round.hpp @@ -0,0 +1,59 @@ +// boost/chrono/round.hpp ------------------------------------------------------------// + +// (C) Copyright Howard Hinnant +// Copyright 2011 Vicente J. Botet Escriba + +// 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/chrono for documentation. + +#ifndef BOOST_CHRONO_ROUND_HPP +#define BOOST_CHRONO_ROUND_HPP + +#include +#include +//#include + +namespace boost +{ + namespace chrono + { + + /** + * rounds to nearest, to even on tie + */ + template + To round(const duration& d) + { + typedef typename common_type >::type result_type; + result_type diff0; + result_type diff1; + + To t0 = duration_cast(d); + To t1 = t0; + if (t0>d) { + --t1; + diff0 = t0 - d; + diff1 = d - t1; + } else { + ++t1; + diff0 = d - t0; + diff1 = t1 - d; + } + + if (diff0 == diff1) + { + if (t0.count() & 1) + return t1; + return t0; + } + else if (diff0 < diff1) + return t0; + return t1; + } + + } // namespace chrono +} // namespace boost + +#endif diff --git a/boost/chrono/system_clocks.hpp b/boost/chrono/system_clocks.hpp new file mode 100644 index 00000000..5ba6a3b0 --- /dev/null +++ b/boost/chrono/system_clocks.hpp @@ -0,0 +1,233 @@ +// boost/chrono/system_clocks.hpp --------------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* + +This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. +Many thanks to Howard for making his code available under the Boost license. +The original code was modified to conform to Boost conventions and to section +20.9 Time utilities [time] of the C++ committee's working paper N2798. +See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. + +time2_demo contained this comment: + + Much thanks to Andrei Alexandrescu, + Walter Brown, + Peter Dimov, + Jeff Garland, + Terry Golubiewski, + Daniel Krugler, + Anthony Williams. +*/ + +/* + +TODO: + + * Fully implement error handling, with test cases. + * Consider issues raised by Michael Marcin: + + > In the past I've seen QueryPerformanceCounter give incorrect results, + > especially with SpeedStep processors on laptops. This was many years ago and + > might have been fixed by service packs and drivers. + > + > Typically you check the results of QPC against GetTickCount to see if the + > results are reasonable. + > http://support.microsoft.com/kb/274323 + > + > I've also heard of problems with QueryPerformanceCounter in multi-processor + > systems. + > + > I know some people SetThreadAffinityMask to 1 for the current thread call + > their QueryPerformance* functions then restore SetThreadAffinityMask. This + > seems horrible to me because it forces your program to jump to another + > physical processor if it isn't already on cpu0 but they claim it worked well + > in practice because they called the timing functions infrequently. + > + > In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for + > high resolution timers to avoid these issues. + +*/ + +#ifndef BOOST_CHRONO_SYSTEM_CLOCKS_HPP +#define BOOST_CHRONO_SYSTEM_CLOCKS_HPP + +#include +#include +#include +#include +#include + +#include + +# if defined( BOOST_CHRONO_POSIX_API ) +# if ! defined(CLOCK_REALTIME) && ! defined (__hpux__) +# error does not supply CLOCK_REALTIME +# endif +# endif + +#ifdef BOOST_CHRONO_WINDOWS_API +// The system_clock tick is 100 nanoseconds +# define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::duration > +#else +# define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::nanoseconds +#endif + +// this must occur after all of the includes and before any code appears: +#ifndef BOOST_CHRONO_HEADER_ONLY +#include // must be the last #include +#endif + + +//----------------------------------------------------------------------------// +// // +// 20.9 Time utilities [time] // +// synopsis // +// // +//----------------------------------------------------------------------------// + +namespace boost { +namespace chrono { + + // Clocks + class BOOST_CHRONO_DECL system_clock; +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + class BOOST_CHRONO_DECL steady_clock; +#endif + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + typedef steady_clock high_resolution_clock; // as permitted by [time.clock.hires] +#else + typedef system_clock high_resolution_clock; // as permitted by [time.clock.hires] +#endif + +//----------------------------------------------------------------------------// +// // +// 20.9.5 Clocks [time.clock] // +// // +//----------------------------------------------------------------------------// + +// If you're porting, clocks are the system-specific (non-portable) part. +// You'll need to know how to get the current time and implement that under now(). +// You'll need to know what units (tick period) and representation makes the most +// sense for your clock and set those accordingly. +// If you know how to map this clock to time_t (perhaps your clock is std::time, which +// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t(). + +//----------------------------------------------------------------------------// +// 20.9.5.1 Class system_clock [time.clock.system] // +//----------------------------------------------------------------------------// + + class BOOST_CHRONO_DECL system_clock + { + public: + typedef BOOST_SYSTEM_CLOCK_DURATION duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = false; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec); +#endif + + static BOOST_CHRONO_INLINE std::time_t to_time_t(const time_point& t) BOOST_NOEXCEPT; + static BOOST_CHRONO_INLINE time_point from_time_t(std::time_t t) BOOST_NOEXCEPT; + }; + +//----------------------------------------------------------------------------// +// 20.9.5.2 Class steady_clock [time.clock.steady] // +//----------------------------------------------------------------------------// + +// As permitted by [time.clock.steady] +// The class steady_clock is conditionally supported. + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + class BOOST_CHRONO_DECL steady_clock + { + public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = true; + + static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now(system::error_code & ec); +#endif + }; +#endif +//----------------------------------------------------------------------------// +// 20.9.5.3 Class high_resolution_clock [time.clock.hires] // +//----------------------------------------------------------------------------// + +// As permitted, steady_clock or system_clock is a typedef for high_resolution_clock. +// See synopsis. + + + template + struct clock_string + { + static std::basic_string name() + { + static const CharT u[] = + { 's', 'y', 's', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string since() + { + static const CharT + u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'J', 'a', 'n', ' ', '1', ',', ' ', '1', '9', '7', '0' }; + static const std::basic_string str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + }; + +#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY + + template + struct clock_string + { + static std::basic_string name() + { + static const CharT + u[] = + { 's', 't', 'e', 'a', 'd', 'y', '_', 'c', 'l', 'o', 'c', 'k' }; + static const std::basic_string str(u, u + sizeof(u) + / sizeof(u[0])); + return str; + } + static std::basic_string since() + { + const CharT u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't' }; + const std::basic_string str(u, u + sizeof(u) / sizeof(u[0])); + return str; + } + }; + +#endif + +} // namespace chrono +} // namespace boost + +#ifndef BOOST_CHRONO_HEADER_ONLY +// the suffix header occurs after all of our code: +#include // pops abi_prefix.hpp pragmas +#else +#include +#endif + +#endif // BOOST_CHRONO_SYSTEM_CLOCKS_HPP diff --git a/boost/chrono/thread_clock.hpp b/boost/chrono/thread_clock.hpp new file mode 100644 index 00000000..207697b4 --- /dev/null +++ b/boost/chrono/thread_clock.hpp @@ -0,0 +1,75 @@ +// boost/chrono/thread_clock.hpp -----------------------------------------------------------// + +// Copyright 2009-2011 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// See http://www.boost.org/libs/system for documentation. + +#include + +#ifndef BOOST_CHRONO_THREAD_CLOCK_HPP +#define BOOST_CHRONO_THREAD_CLOCK_HPP + +#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK) + +#include +#include +#include +#include +#include + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include // must be the last #include +#endif + +namespace boost { namespace chrono { + +class BOOST_CHRONO_DECL thread_clock { +public: + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + BOOST_STATIC_CONSTEXPR bool is_steady = BOOST_CHRONO_THREAD_CLOCK_IS_STEADY; + + static BOOST_CHRONO_INLINE time_point now( ) BOOST_NOEXCEPT; +#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING + static BOOST_CHRONO_INLINE time_point now( system::error_code & ec ); +#endif +}; + +template +struct clock_string +{ + static std::basic_string name() + { + static const CharT u[] = + { 't', 'h', 'r', 'e', 'a', 'd', '_', + 'c', 'l','o', 'c', 'k'}; + static const std::basic_string str(u, u + sizeof(u)/sizeof(u[0])); + return str; + } + static std::basic_string since() + { + const CharT u[] = + { ' ', 's', 'i', 'n', 'c', 'e', ' ', 't', 'h', 'r', 'e', 'a', 'd', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p'}; + const std::basic_string str(u, u + sizeof(u)/sizeof(u[0])); + return str; + } +}; + +} // namespace chrono +} // namespace boost + + +#ifndef BOOST_CHRONO_HEADER_ONLY +#include // pops abi_prefix.hpp pragmas +#else +#include +#endif + +#endif + +#endif // BOOST_CHRONO_THREAD_CLOCK_HPP diff --git a/boost/chrono/time_point.hpp b/boost/chrono/time_point.hpp new file mode 100644 index 00000000..fc230955 --- /dev/null +++ b/boost/chrono/time_point.hpp @@ -0,0 +1,379 @@ +// duration.hpp --------------------------------------------------------------// + +// Copyright 2008 Howard Hinnant +// Copyright 2008 Beman Dawes +// Copyright 2009-2012 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +/* + +This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. +Many thanks to Howard for making his code available under the Boost license. +The original code was modified to conform to Boost conventions and to section +20.9 Time utilities [time] of the C++ committee's working paper N2798. +See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. + +time2_demo contained this comment: + + Much thanks to Andrei Alexandrescu, + Walter Brown, + Peter Dimov, + Jeff Garland, + Terry Golubiewski, + Daniel Krugler, + Anthony Williams. +*/ + + +#ifndef BOOST_CHRONO_TIME_POINT_HPP +#define BOOST_CHRONO_TIME_POINT_HPP + +#include + +#ifndef BOOST_CHRONO_HEADER_ONLY +// this must occur after all of the includes and before any code appears: +#include // must be the last #include +#endif + +//----------------------------------------------------------------------------// +// // +// 20.9 Time utilities [time] // +// synopsis // +// // +//----------------------------------------------------------------------------// + +namespace boost { +namespace chrono { + + template + class time_point; + + +} // namespace chrono + + +// common_type trait specializations + +template + struct common_type, + chrono::time_point >; + + +//----------------------------------------------------------------------------// +// 20.9.2.3 Specializations of common_type [time.traits.specializations] // +//----------------------------------------------------------------------------// + + +template +struct common_type, + chrono::time_point > +{ + typedef chrono::time_point::type> type; +}; + + + +namespace chrono { + + // time_point arithmetic + template + inline BOOST_CONSTEXPR + time_point >::type> + operator+( + const time_point& lhs, + const duration& rhs); + template + inline BOOST_CONSTEXPR + time_point, Duration2>::type> + operator+( + const duration& lhs, + const time_point& rhs); + template + inline BOOST_CONSTEXPR + time_point >::type> + operator-( + const time_point& lhs, + const duration& rhs); + template + inline BOOST_CONSTEXPR + typename common_type::type + operator-( + const time_point& lhs, + const time_point& rhs); + + // time_point comparisons + template + inline BOOST_CONSTEXPR + bool operator==( + const time_point& lhs, + const time_point& rhs); + template + inline BOOST_CONSTEXPR + bool operator!=( + const time_point& lhs, + const time_point& rhs); + template + inline BOOST_CONSTEXPR + bool operator< ( + const time_point& lhs, + const time_point& rhs); + template + inline BOOST_CONSTEXPR + bool operator<=( + const time_point& lhs, + const time_point& rhs); + template + inline BOOST_CONSTEXPR + bool operator> ( + const time_point& lhs, + const time_point& rhs); + template + inline BOOST_CONSTEXPR + bool operator>=( + const time_point& lhs, + const time_point& rhs); + + // time_point_cast + template + inline BOOST_CONSTEXPR + time_point time_point_cast(const time_point& t); + +//----------------------------------------------------------------------------// +// // +// 20.9.4 Class template time_point [time.point] // +// // +//----------------------------------------------------------------------------// + + template + class time_point + { + BOOST_CHRONO_STATIC_ASSERT(boost::chrono::detail::is_duration::value, + BOOST_CHRONO_SECOND_TEMPLATE_PARAMETER_OF_TIME_POINT_MUST_BE_A_BOOST_CHRONO_DURATION, (Duration)); + public: + typedef Clock clock; + typedef Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; + typedef Duration difference_type; + + private: + duration d_; + + public: + BOOST_FORCEINLINE BOOST_CONSTEXPR + time_point() : d_(duration::zero()) + {} + BOOST_FORCEINLINE BOOST_CONSTEXPR + explicit time_point(const duration& d) + : d_(d) + {} + + // conversions + template + BOOST_FORCEINLINE BOOST_CONSTEXPR + time_point(const time_point& t + , typename boost::enable_if + < + boost::is_convertible + >::type* = 0 + ) + : d_(t.time_since_epoch()) + { + } + // observer + + BOOST_CONSTEXPR + duration time_since_epoch() const + { + return d_; + } + + // arithmetic + +#ifdef BOOST_CHRONO_EXTENSIONS + BOOST_CONSTEXPR + time_point operator+() const {return *this;} + BOOST_CONSTEXPR + time_point operator-() const {return time_point(-d_);} + time_point& operator++() {++d_; return *this;} + time_point operator++(int) {return time_point(d_++);} + time_point& operator--() {--d_; return *this;} + time_point operator--(int) {return time_point(d_--);} + + time_point& operator+=(const rep& r) {d_ += duration(r); return *this;} + time_point& operator-=(const rep& r) {d_ -= duration(r); return *this;} + +#endif + + time_point& operator+=(const duration& d) {d_ += d; return *this;} + time_point& operator-=(const duration& d) {d_ -= d; return *this;} + + // special values + + static BOOST_CHRONO_LIB_CONSTEXPR time_point + min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return time_point((duration::min)()); + } + static BOOST_CHRONO_LIB_CONSTEXPR time_point + max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return time_point((duration::max)()); + } + }; + +//----------------------------------------------------------------------------// +// 20.9.4.5 time_point non-member arithmetic [time.point.nonmember] // +//----------------------------------------------------------------------------// + + // time_point operator+(time_point x, duration y); + + template + inline BOOST_CONSTEXPR + time_point >::type> + operator+(const time_point& lhs, + const duration& rhs) + { + typedef typename common_type >::type CDuration; + typedef time_point< + Clock, + CDuration + > TimeResult; + return TimeResult(lhs.time_since_epoch() + CDuration(rhs)); + } + + // time_point operator+(duration x, time_point y); + + template + inline BOOST_CONSTEXPR + time_point, Duration2>::type> + operator+(const duration& lhs, + const time_point& rhs) + { + return rhs + lhs; + } + + // time_point operator-(time_point x, duration y); + + template + inline BOOST_CONSTEXPR + time_point >::type> + operator-(const time_point& lhs, + const duration& rhs) + { + return lhs + (-rhs); + } + + // duration operator-(time_point x, time_point y); + + template + inline BOOST_CONSTEXPR + typename common_type::type + operator-(const time_point& lhs, + const time_point& rhs) + { + return lhs.time_since_epoch() - rhs.time_since_epoch(); + } + +//----------------------------------------------------------------------------// +// 20.9.4.6 time_point comparisons [time.point.comparisons] // +//----------------------------------------------------------------------------// + + // time_point == + + template + inline BOOST_CONSTEXPR + bool + operator==(const time_point& lhs, + const time_point& rhs) + { + return lhs.time_since_epoch() == rhs.time_since_epoch(); + } + + // time_point != + + template + inline BOOST_CONSTEXPR + bool + operator!=(const time_point& lhs, + const time_point& rhs) + { + return !(lhs == rhs); + } + + // time_point < + + template + inline BOOST_CONSTEXPR + bool + operator<(const time_point& lhs, + const time_point& rhs) + { + return lhs.time_since_epoch() < rhs.time_since_epoch(); + } + + // time_point > + + template + inline BOOST_CONSTEXPR + bool + operator>(const time_point& lhs, + const time_point& rhs) + { + return rhs < lhs; + } + + // time_point <= + + template + inline BOOST_CONSTEXPR + bool + operator<=(const time_point& lhs, + const time_point& rhs) + { + return !(rhs < lhs); + } + + // time_point >= + + template + inline BOOST_CONSTEXPR + bool + operator>=(const time_point& lhs, + const time_point& rhs) + { + return !(lhs < rhs); + } + +//----------------------------------------------------------------------------// +// 20.9.4.7 time_point_cast [time.point.cast] // +//----------------------------------------------------------------------------// + + template + inline BOOST_CONSTEXPR + time_point + time_point_cast(const time_point& t) + { + return time_point( + duration_cast(t.time_since_epoch())); + } + +} // namespace chrono +} // namespace boost + +#ifndef BOOST_CHRONO_HEADER_ONLY +// the suffix header occurs after all of our code: +#include // pops abi_prefix.hpp pragmas +#endif + +#endif // BOOST_CHRONO_TIME_POINT_HPP diff --git a/boost/concept/assert.hpp b/boost/concept/assert.hpp new file mode 100644 index 00000000..cf981795 --- /dev/null +++ b/boost/concept/assert.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2006. 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_CONCEPT_ASSERT_DWA2006430_HPP +# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP + +# include +# include + +// The old protocol used a constraints() member function in concept +// checking classes. If the compiler supports SFINAE, we can detect +// that function and seamlessly support the old concept checking +// classes. In this release, backward compatibility with the old +// concept checking classes is enabled by default, where available. +// The old protocol is deprecated, though, and backward compatibility +// will no longer be the default in the next release. + +# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \ + && !defined(BOOST_NO_SFINAE) \ + \ + && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4)) + +// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to +// check for the presence of particularmember functions. + +# define BOOST_OLD_CONCEPT_SUPPORT + +# endif + +# ifdef BOOST_MSVC +# include +# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# include +# else +# include +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); + // +# define BOOST_CONCEPT_ASSERT(ModelInParens) \ + BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens) + +#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP diff --git a/boost/concept/detail/backward_compatibility.hpp b/boost/concept/detail/backward_compatibility.hpp new file mode 100644 index 00000000..66d573ef --- /dev/null +++ b/boost/concept/detail/backward_compatibility.hpp @@ -0,0 +1,16 @@ +// Copyright David Abrahams 2009. 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_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP +# define BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP + +namespace boost +{ + namespace concepts {} + +# if defined(BOOST_HAS_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD) + namespace concept = concepts; +# endif +} // namespace boost::concept + +#endif // BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP diff --git a/boost/concept/detail/borland.hpp b/boost/concept/detail/borland.hpp new file mode 100644 index 00000000..300d5d40 --- /dev/null +++ b/boost/concept/detail/borland.hpp @@ -0,0 +1,30 @@ +// Copyright David Abrahams 2006. 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_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP + +# include +# include + +namespace boost { namespace concepts { + +template +struct require; + +template +struct require +{ + enum { instantiate = sizeof((((Model*)0)->~Model()), 3) }; +}; + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + enum \ + { \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + boost::concepts::require::instantiate \ + } + +}} // namespace boost::concept + +#endif // BOOST_CONCEPT_DETAIL_BORLAND_DWA2006429_HPP diff --git a/boost/concept/detail/concept_def.hpp b/boost/concept/detail/concept_def.hpp new file mode 100644 index 00000000..750561ee --- /dev/null +++ b/boost/concept/detail/concept_def.hpp @@ -0,0 +1,34 @@ +// Copyright David Abrahams 2006. 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_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# include +# include +# include +# include +#endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP + +// BOOST_concept(SomeName, (p1)(p2)...(pN)) +// +// Expands to "template struct SomeName" +// +// Also defines an equivalent SomeNameConcept for backward compatibility. +// Maybe in the next release we can kill off the "Concept" suffix for good. +# define BOOST_concept(name, params) \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name; /* forward declaration */ \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct BOOST_PP_CAT(name,Concept) \ + : name< BOOST_PP_SEQ_ENUM(params) > \ + { \ + }; \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name + +// Helper for BOOST_concept, above. +# define BOOST_CONCEPT_typename(r, ignored, index, t) \ + BOOST_PP_COMMA_IF(index) typename t + diff --git a/boost/concept/detail/concept_undef.hpp b/boost/concept/detail/concept_undef.hpp new file mode 100644 index 00000000..713db891 --- /dev/null +++ b/boost/concept/detail/concept_undef.hpp @@ -0,0 +1,5 @@ +// Copyright David Abrahams 2006. 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) +# undef BOOST_concept_typename +# undef BOOST_concept diff --git a/boost/concept/detail/general.hpp b/boost/concept/detail/general.hpp new file mode 100644 index 00000000..525ea656 --- /dev/null +++ b/boost/concept/detail/general.hpp @@ -0,0 +1,77 @@ +// Copyright David Abrahams 2006. 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_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP + +# include +# include +# include + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + +// This implementation works on Comeau and GCC, all the way back to +// 2.95 +namespace boost { namespace concepts { + +template +struct requirement_; + +namespace detail +{ + template struct instantiate {}; +} + +template +struct requirement +{ + static void failed() { ((Model*)0)->~Model(); } +}; + +struct failed {}; + +template +struct requirement +{ + static void failed() { ((Model*)0)->~Model(); } +}; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + +template +struct constraint +{ + static void failed() { ((Model*)0)->constraints(); } +}; + +template +struct requirement_ + : mpl::if_< + concepts::not_satisfied + , constraint + , requirement + >::type +{}; + +# else + +// For GCC-2.x, these can't have exactly the same name +template +struct requirement_ + : requirement +{}; + +# endif + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + typedef ::boost::concepts::detail::instantiate< \ + &::boost::concepts::requirement_::failed> \ + BOOST_PP_CAT(boost_concept_check,__LINE__) \ + BOOST_ATTRIBUTE_UNUSED + +}} + +#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP diff --git a/boost/concept/detail/has_constraints.hpp b/boost/concept/detail/has_constraints.hpp new file mode 100644 index 00000000..a309db3d --- /dev/null +++ b/boost/concept/detail/has_constraints.hpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2006. 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_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP + +# include +# include +# include + +namespace boost { namespace concepts { + +namespace detail +{ + +// Here we implement the metafunction that detects whether a +// constraints metafunction exists + typedef char yes; + typedef char (&no)[2]; + + template + struct wrap_constraints {}; + +#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) || defined(__CUDACC__) + // Work around the following bogus error in Sun Studio 11, by + // turning off the has_constraints function entirely: + // Error: complex expression not allowed in dependent template + // argument expression + inline no has_constraints_(...); +#else + template + inline yes has_constraints_(Model*, wrap_constraints* = 0); + inline no has_constraints_(...); +#endif +} + +// This would be called "detail::has_constraints," but it has a strong +// tendency to show up in error messages. +template +struct not_satisfied +{ + BOOST_STATIC_CONSTANT( + bool + , value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) ); + typedef mpl::bool_ type; +}; + +}} // namespace boost::concepts::detail + +#endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP diff --git a/boost/concept/detail/msvc.hpp b/boost/concept/detail/msvc.hpp new file mode 100644 index 00000000..078dd223 --- /dev/null +++ b/boost/concept/detail/msvc.hpp @@ -0,0 +1,123 @@ +// Copyright David Abrahams 2006. 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_CONCEPT_CHECK_MSVC_DWA2006429_HPP +# define BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP + +# include +# include +# include + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + +# ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4100) +# endif + +namespace boost { namespace concepts { + + +template +struct check +{ + virtual void failed(Model* x) + { + x->~Model(); + } +}; + +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION +struct failed {}; +template +struct check +{ + virtual void failed(Model* x) + { + x->~Model(); + } +}; +# endif + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + +namespace detail +{ + // No need for a virtual function here, since evaluating + // not_satisfied below will have already instantiated the + // constraints() member. + struct constraint {}; +} + +template +struct require + : mpl::if_c< + not_satisfied::value + , detail::constraint +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION + , check +# else + , check +# endif + >::type +{}; + +# else + +template +struct require +# ifndef BOOST_NO_PARTIAL_SPECIALIZATION + : check +# else + : check +# endif +{}; + +# endif + +# if BOOST_WORKAROUND(BOOST_MSVC, == 1310) + +// +// The iterator library sees some really strange errors unless we +// do things this way. +// +template +struct require +{ + virtual void failed(Model*) + { + require(); + } +}; + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ +enum \ +{ \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concepts::require) \ +} + +# else // Not vc-7.1 + +template +require +require_(void(*)(Model)); + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ +enum \ +{ \ + BOOST_PP_CAT(boost_concept_check,__LINE__) = \ + sizeof(::boost::concepts::require_((ModelFnPtr)0)) \ +} + +# endif +}} + +# ifdef BOOST_MSVC +# pragma warning(pop) +# endif + +#endif // BOOST_CONCEPT_CHECK_MSVC_DWA2006429_HPP diff --git a/boost/concept/usage.hpp b/boost/concept/usage.hpp new file mode 100644 index 00000000..e73370fb --- /dev/null +++ b/boost/concept/usage.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2006. 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_CONCEPT_USAGE_DWA2006919_HPP +# define BOOST_CONCEPT_USAGE_DWA2006919_HPP + +# include +# include +# include + +namespace boost { namespace concepts { + +template +struct usage_requirements +{ + ~usage_requirements() { ((Model*)0)->~Model(); } +}; + +# if BOOST_WORKAROUND(__GNUC__, <= 3) + +# define BOOST_CONCEPT_USAGE(model) \ + model(); /* at least 2.96 and 3.4.3 both need this :( */ \ + BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \ + ~model() + +# else + +# define BOOST_CONCEPT_USAGE(model) \ + BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \ + ~model() + +# endif + +}} // namespace boost::concepts + +#endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP diff --git a/boost/concept_check.hpp b/boost/concept_check.hpp new file mode 100644 index 00000000..25f118b6 --- /dev/null +++ b/boost/concept_check.hpp @@ -0,0 +1,1082 @@ +// +// (C) Copyright Jeremy Siek 2000. +// Copyright 2002 The Trustees of Indiana University. +// +// 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) +// +// Revision History: +// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek) +// 02 April 2001: Removed limits header altogether. (Jeremy Siek) +// 01 April 2001: Modified to use new header. (JMaddock) +// + +// See http://www.boost.org/libs/concept_check for documentation. + +#ifndef BOOST_CONCEPT_CHECKS_HPP +# define BOOST_CONCEPT_CHECKS_HPP + +# include + +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include + +#if (defined _MSC_VER) +# pragma warning( push ) +# pragma warning( disable : 4510 ) // default constructor could not be generated +# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required +#endif + +namespace boost +{ + + // + // Backward compatibility + // + + template + inline void function_requires(Model* = 0) + { + BOOST_CONCEPT_ASSERT((Model)); + } + template inline void ignore_unused_variable_warning(T const&) {} + +# define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + + + // + // Begin concept definitions + // + BOOST_concept(Integer, (T)) + { + BOOST_CONCEPT_USAGE(Integer) + { + x.error_type_must_be_an_integer_type(); + } + private: + T x; + }; + + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct Integer< ::boost::long_long_type> {}; + template <> struct Integer< ::boost::ulong_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct Integer<__int64> {}; + template <> struct Integer {}; +# endif + + BOOST_concept(SignedInteger,(T)) { + BOOST_CONCEPT_USAGE(SignedInteger) { + x.error_type_must_be_a_signed_integer_type(); + } + private: + T x; + }; + template <> struct SignedInteger { }; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct SignedInteger< ::boost::long_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct SignedInteger<__int64> {}; +# endif + + BOOST_concept(UnsignedInteger,(T)) { + BOOST_CONCEPT_USAGE(UnsignedInteger) { + x.error_type_must_be_an_unsigned_integer_type(); + } + private: + T x; + }; + + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct UnsignedInteger< ::boost::ulong_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct UnsignedInteger {}; +# endif + + //=========================================================================== + // Basic Concepts + + BOOST_concept(DefaultConstructible,(TT)) + { + BOOST_CONCEPT_USAGE(DefaultConstructible) { + TT a; // require default constructor + ignore_unused_variable_warning(a); + } + }; + + BOOST_concept(Assignable,(TT)) + { + BOOST_CONCEPT_USAGE(Assignable) { +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = b; // require assignment operator +#endif + const_constraints(b); + } + private: + void const_constraints(const TT& x) { +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = x; // const required for argument to assignment +#else + ignore_unused_variable_warning(x); +#endif + } + private: + TT a; + TT b; + }; + + + BOOST_concept(CopyConstructible,(TT)) + { + BOOST_CONCEPT_USAGE(CopyConstructible) { + TT a(b); // require copy constructor + TT* ptr = &a; // require address of operator + const_constraints(a); + ignore_unused_variable_warning(ptr); + } + private: + void const_constraints(const TT& a) { + TT c(a); // require const copy constructor + const TT* ptr = &a; // require const address of operator + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(ptr); + } + TT b; + }; + + // The SGI STL version of Assignable requires copy constructor and operator= + BOOST_concept(SGIAssignable,(TT)) + { + BOOST_CONCEPT_USAGE(SGIAssignable) { + TT c(a); +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = b; // require assignment operator +#endif + const_constraints(b); + ignore_unused_variable_warning(c); + } + private: + void const_constraints(const TT& x) { + TT c(x); +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = x; // const required for argument to assignment +#endif + ignore_unused_variable_warning(c); + } + TT a; + TT b; + }; + + BOOST_concept(Convertible,(X)(Y)) + { + BOOST_CONCEPT_USAGE(Convertible) { + Y y = x; + ignore_unused_variable_warning(y); + } + private: + X x; + }; + + // The C++ standard requirements for many concepts talk about return + // types that must be "convertible to bool". The problem with this + // requirement is that it leaves the door open for evil proxies that + // define things like operator|| with strange return types. Two + // possible solutions are: + // 1) require the return type to be exactly bool + // 2) stay with convertible to bool, and also + // specify stuff about all the logical operators. + // For now we just test for convertible to bool. + template + void require_boolean_expr(const TT& t) { + bool x = t; + ignore_unused_variable_warning(x); + } + + BOOST_concept(EqualityComparable,(TT)) + { + BOOST_CONCEPT_USAGE(EqualityComparable) { + require_boolean_expr(a == b); + require_boolean_expr(a != b); + } + private: + TT a, b; + }; + + BOOST_concept(LessThanComparable,(TT)) + { + BOOST_CONCEPT_USAGE(LessThanComparable) { + require_boolean_expr(a < b); + } + private: + TT a, b; + }; + + // This is equivalent to SGI STL's LessThanComparable. + BOOST_concept(Comparable,(TT)) + { + BOOST_CONCEPT_USAGE(Comparable) { + require_boolean_expr(a < b); + require_boolean_expr(a > b); + require_boolean_expr(a <= b); + require_boolean_expr(a >= b); + } + private: + TT a, b; + }; + +#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ + BOOST_concept(NAME, (First)(Second)) \ + { \ + BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ + private: \ + bool constraints_() { return a OP b; } \ + First a; \ + Second b; \ + } + +#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \ + BOOST_concept(NAME, (Ret)(First)(Second)) \ + { \ + BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ + private: \ + Ret constraints_() { return a OP b; } \ + First a; \ + Second b; \ + } + + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp); + + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp); + + //=========================================================================== + // Function Object Concepts + + BOOST_concept(Generator,(Func)(Return)) + { + BOOST_CONCEPT_USAGE(Generator) { test(is_void()); } + + private: + void test(boost::mpl::false_) + { + // Do we really want a reference here? + const Return& r = f(); + ignore_unused_variable_warning(r); + } + + void test(boost::mpl::true_) + { + f(); + } + + Func f; + }; + + BOOST_concept(UnaryFunction,(Func)(Return)(Arg)) + { + BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void()); } + + private: + void test(boost::mpl::false_) + { + f(arg); // "priming the pump" this way keeps msvc6 happy (ICE) + Return r = f(arg); + ignore_unused_variable_warning(r); + } + + void test(boost::mpl::true_) + { + f(arg); + } + +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy construktor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::UnaryFunction::arg" + // in class without a constructor [-Wuninitialized]) + UnaryFunction(); +#endif + + Func f; + Arg arg; + }; + + BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second)) + { + BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void()); } + private: + void test(boost::mpl::false_) + { + f(first,second); + Return r = f(first, second); // require operator() + (void)r; + } + + void test(boost::mpl::true_) + { + f(first,second); + } + +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::BinaryFunction::arg" + // in class without a constructor [-Wuninitialized]) + BinaryFunction(); +#endif + + Func f; + First first; + Second second; + }; + + BOOST_concept(UnaryPredicate,(Func)(Arg)) + { + BOOST_CONCEPT_USAGE(UnaryPredicate) { + require_boolean_expr(f(arg)); // require operator() returning bool + } + private: +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::UnaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + UnaryPredicate(); +#endif + + Func f; + Arg arg; + }; + + BOOST_concept(BinaryPredicate,(Func)(First)(Second)) + { + BOOST_CONCEPT_USAGE(BinaryPredicate) { + require_boolean_expr(f(a, b)); // require operator() returning bool + } + private: +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::BinaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + BinaryPredicate(); +#endif + Func f; + First a; + Second b; + }; + + // use this when functor is used inside a container class like std::set + BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + { + BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { + const_constraints(f); + } + private: + void const_constraints(const Func& fun) { + // operator() must be a const member function + require_boolean_expr(fun(a, b)); + } +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. + // (warning: non-static reference "const double& boost::Const_BinaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + Const_BinaryPredicate(); +#endif + + Func f; + First a; + Second b; + }; + + BOOST_concept(AdaptableGenerator,(Func)(Return)) + : Generator + { + typedef typename Func::result_type result_type; + + BOOST_CONCEPT_USAGE(AdaptableGenerator) + { + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg)) + : UnaryFunction + { + typedef typename Func::argument_type argument_type; + typedef typename Func::result_type result_type; + + ~AdaptableUnaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second)) + : BinaryFunction< + Func + , typename Func::result_type + , typename Func::first_argument_type + , typename Func::second_argument_type + > + { + typedef typename Func::first_argument_type first_argument_type; + typedef typename Func::second_argument_type second_argument_type; + typedef typename Func::result_type result_type; + + ~AdaptableBinaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptablePredicate,(Func)(Arg)) + : UnaryPredicate + , AdaptableUnaryFunction + { + }; + + BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + , AdaptableBinaryFunction + { + }; + + //=========================================================================== + // Iterator Concepts + + BOOST_concept(InputIterator,(TT)) + : Assignable + , EqualityComparable + { + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::iterator_category iterator_category; + + BOOST_CONCEPT_USAGE(InputIterator) + { + BOOST_CONCEPT_ASSERT((SignedInteger)); + BOOST_CONCEPT_ASSERT((Convertible)); + + TT j(i); + (void)*i; // require dereference operator + ++j; // require preincrement operator + i++; // require postincrement operator + } + private: + TT i; + }; + + BOOST_concept(OutputIterator,(TT)(ValueT)) + : Assignable + { + BOOST_CONCEPT_USAGE(OutputIterator) { + + ++i; // require preincrement operator + i++; // require postincrement operator + *i++ = t; // require postincrement and assignment + } + private: + TT i, j; + ValueT t; + }; + + BOOST_concept(ForwardIterator,(TT)) + : InputIterator + { + BOOST_CONCEPT_USAGE(ForwardIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category + , std::forward_iterator_tag + >)); + + typename InputIterator::reference r = *i; + ignore_unused_variable_warning(r); + } + + private: + TT i; + }; + + BOOST_concept(Mutable_ForwardIterator,(TT)) + : ForwardIterator + { + BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) { + *i++ = *j; // require postincrement and assignment + } + private: + TT i, j; + }; + + BOOST_concept(BidirectionalIterator,(TT)) + : ForwardIterator + { + BOOST_CONCEPT_USAGE(BidirectionalIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category + , std::bidirectional_iterator_tag + >)); + + --i; // require predecrement operator + i--; // require postdecrement operator + } + private: + TT i; + }; + + BOOST_concept(Mutable_BidirectionalIterator,(TT)) + : BidirectionalIterator + , Mutable_ForwardIterator + { + BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator) + { + *i-- = *j; // require postdecrement and assignment + } + private: + TT i, j; + }; + + BOOST_concept(RandomAccessIterator,(TT)) + : BidirectionalIterator + , Comparable + { + BOOST_CONCEPT_USAGE(RandomAccessIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category + , std::random_access_iterator_tag + >)); + + i += n; // require assignment addition operator + i = i + n; i = n + i; // require addition with difference type + i -= n; // require assignment subtraction operator + i = i - n; // require subtraction with difference type + n = i - j; // require difference operator + (void)i[n]; // require element access operator + } + + private: + TT a, b; + TT i, j; + typename std::iterator_traits::difference_type n; + }; + + BOOST_concept(Mutable_RandomAccessIterator,(TT)) + : RandomAccessIterator + , Mutable_BidirectionalIterator + { + BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator) + { + i[n] = *i; // require element access and assignment + } + private: + TT i; + typename std::iterator_traits::difference_type n; + }; + + //=========================================================================== + // Container s + + BOOST_concept(Container,(C)) + : Assignable + { + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + typedef typename C::const_reference const_reference; + typedef typename C::const_pointer const_pointer; + typedef typename C::const_iterator const_iterator; + + BOOST_CONCEPT_USAGE(Container) + { + BOOST_CONCEPT_ASSERT((InputIterator)); + const_constraints(c); + } + + private: + void const_constraints(const C& cc) { + i = cc.begin(); + i = cc.end(); + n = cc.size(); + n = cc.max_size(); + b = cc.empty(); + } + C c; + bool b; + const_iterator i; + size_type n; + }; + + BOOST_concept(Mutable_Container,(C)) + : Container + { + typedef typename C::reference reference; + typedef typename C::iterator iterator; + typedef typename C::pointer pointer; + + BOOST_CONCEPT_USAGE(Mutable_Container) + { + BOOST_CONCEPT_ASSERT(( + Assignable)); + + BOOST_CONCEPT_ASSERT((InputIterator)); + + i = c.begin(); + i = c.end(); + c.swap(c2); + } + + private: + iterator i; + C c, c2; + }; + + BOOST_concept(ForwardContainer,(C)) + : Container + { + BOOST_CONCEPT_USAGE(ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + ForwardIterator< + typename ForwardContainer::const_iterator + >)); + } + }; + + BOOST_concept(Mutable_ForwardContainer,(C)) + : ForwardContainer + , Mutable_Container + { + BOOST_CONCEPT_USAGE(Mutable_ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + Mutable_ForwardIterator< + typename Mutable_ForwardContainer::iterator + >)); + } + }; + + BOOST_concept(ReversibleContainer,(C)) + : ForwardContainer + { + typedef typename + C::const_reverse_iterator + const_reverse_iterator; + + BOOST_CONCEPT_USAGE(ReversibleContainer) + { + BOOST_CONCEPT_ASSERT(( + BidirectionalIterator< + typename ReversibleContainer::const_iterator>)); + + BOOST_CONCEPT_ASSERT((BidirectionalIterator)); + + const_constraints(c); + } + private: + void const_constraints(const C& cc) + { + const_reverse_iterator i = cc.rbegin(); + i = cc.rend(); + } + C c; + }; + + BOOST_concept(Mutable_ReversibleContainer,(C)) + : Mutable_ForwardContainer + , ReversibleContainer + { + typedef typename C::reverse_iterator reverse_iterator; + + BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer) + { + typedef typename Mutable_ForwardContainer::iterator iterator; + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + + reverse_iterator i = c.rbegin(); + i = c.rend(); + } + private: + C c; + }; + + BOOST_concept(RandomAccessContainer,(C)) + : ReversibleContainer + { + typedef typename C::size_type size_type; + typedef typename C::const_reference const_reference; + + BOOST_CONCEPT_USAGE(RandomAccessContainer) + { + BOOST_CONCEPT_ASSERT(( + RandomAccessIterator< + typename RandomAccessContainer::const_iterator + >)); + + const_constraints(c); + } + private: + void const_constraints(const C& cc) + { + const_reference r = cc[n]; + ignore_unused_variable_warning(r); + } + + C c; + size_type n; + }; + + BOOST_concept(Mutable_RandomAccessContainer,(C)) + : Mutable_ReversibleContainer + , RandomAccessContainer + { + private: + typedef Mutable_RandomAccessContainer self; + public: + BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer) + { + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); + + typename self::reference r = c[i]; + ignore_unused_variable_warning(r); + } + + private: + typename Mutable_ReversibleContainer::size_type i; + C c; + }; + + // A Sequence is inherently mutable + BOOST_concept(Sequence,(S)) + : Mutable_ForwardContainer + // Matt Austern's book puts DefaultConstructible here, the C++ + // standard places it in Container --JGS + // ... so why aren't we following the standard? --DWA + , DefaultConstructible + { + BOOST_CONCEPT_USAGE(Sequence) + { + S + c(n, t), + c2(first, last); + + c.insert(p, t); + c.insert(p, n, t); + c.insert(p, first, last); + + c.erase(p); + c.erase(p, q); + + typename Sequence::reference r = c.front(); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(c2); + ignore_unused_variable_warning(r); + const_constraints(c); + } + private: + void const_constraints(const S& c) { + typename Sequence::const_reference r = c.front(); + ignore_unused_variable_warning(r); + } + + typename S::value_type t; + typename S::size_type n; + typename S::value_type* first, *last; + typename S::iterator p, q; + }; + + BOOST_concept(FrontInsertionSequence,(S)) + : Sequence + { + BOOST_CONCEPT_USAGE(FrontInsertionSequence) + { + c.push_front(t); + c.pop_front(); + } + private: + S c; + typename S::value_type t; + }; + + BOOST_concept(BackInsertionSequence,(S)) + : Sequence + { + BOOST_CONCEPT_USAGE(BackInsertionSequence) + { + c.push_back(t); + c.pop_back(); + typename BackInsertionSequence::reference r = c.back(); + ignore_unused_variable_warning(r); + const_constraints(c); + } + private: + void const_constraints(const S& cc) { + typename BackInsertionSequence::const_reference + r = cc.back(); + ignore_unused_variable_warning(r); + } + S c; + typename S::value_type t; + }; + + BOOST_concept(AssociativeContainer,(C)) + : ForwardContainer + , DefaultConstructible + { + typedef typename C::key_type key_type; + typedef typename C::key_compare key_compare; + typedef typename C::value_compare value_compare; + typedef typename C::iterator iterator; + + BOOST_CONCEPT_USAGE(AssociativeContainer) + { + i = c.find(k); + r = c.equal_range(k); + c.erase(k); + c.erase(i); + c.erase(r.first, r.second); + const_constraints(c); + BOOST_CONCEPT_ASSERT((BinaryPredicate)); + + typedef typename AssociativeContainer::value_type value_type_; + BOOST_CONCEPT_ASSERT((BinaryPredicate)); + } + + // Redundant with the base concept, but it helps below. + typedef typename C::const_iterator const_iterator; + private: + void const_constraints(const C& cc) + { + ci = cc.find(k); + n = cc.count(k); + cr = cc.equal_range(k); + } + + C c; + iterator i; + std::pair r; + const_iterator ci; + std::pair cr; + typename C::key_type k; + typename C::size_type n; + }; + + BOOST_concept(UniqueAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(UniqueAssociativeContainer) + { + C c(first, last); + + pos_flag = c.insert(t); + c.insert(first, last); + + ignore_unused_variable_warning(c); + } + private: + std::pair pos_flag; + typename C::value_type t; + typename C::value_type* first, *last; + }; + + BOOST_concept(MultipleAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(MultipleAssociativeContainer) + { + C c(first, last); + + pos = c.insert(t); + c.insert(first, last); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(pos); + } + private: + typename C::iterator pos; + typename C::value_type t; + typename C::value_type* first, *last; + }; + + BOOST_concept(SimpleAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(SimpleAssociativeContainer) + { + typedef typename C::key_type key_type; + typedef typename C::value_type value_type; + BOOST_MPL_ASSERT((boost::is_same)); + } + }; + + BOOST_concept(PairAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(PairAssociativeContainer) + { + typedef typename C::key_type key_type; + typedef typename C::value_type value_type; + typedef typename C::mapped_type mapped_type; + typedef std::pair required_value_type; + BOOST_MPL_ASSERT((boost::is_same)); + } + }; + + BOOST_concept(SortedAssociativeContainer,(C)) + : AssociativeContainer + , ReversibleContainer + { + BOOST_CONCEPT_USAGE(SortedAssociativeContainer) + { + C + c(kc), + c2(first, last), + c3(first, last, kc); + + p = c.upper_bound(k); + p = c.lower_bound(k); + r = c.equal_range(k); + + c.insert(p, t); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(c2); + ignore_unused_variable_warning(c3); + const_constraints(c); + } + + void const_constraints(const C& c) + { + kc = c.key_comp(); + vc = c.value_comp(); + + cp = c.upper_bound(k); + cp = c.lower_bound(k); + cr = c.equal_range(k); + } + + private: + typename C::key_compare kc; + typename C::value_compare vc; + typename C::value_type t; + typename C::key_type k; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + + typedef SortedAssociativeContainer self; + iterator p; + const_iterator cp; + std::pair r; + std::pair cr; + typename C::value_type* first, *last; + }; + + // HashedAssociativeContainer + + BOOST_concept(Collection,(C)) + { + BOOST_CONCEPT_USAGE(Collection) + { + boost::function_requires >(); + boost::function_requires >(); + boost::function_requires >(); + const_constraints(c); + i = c.begin(); + i = c.end(); + c.swap(c); + } + + void const_constraints(const C& cc) { + ci = cc.begin(); + ci = cc.end(); + n = cc.size(); + b = cc.empty(); + } + + private: + typedef typename C::value_type value_type; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::reference reference; + typedef typename C::const_reference const_reference; + // typedef typename C::pointer pointer; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + + C c; + bool b; + iterator i; + const_iterator ci; + size_type n; + }; +} // namespace boost + +#if (defined _MSC_VER) +# pragma warning( pop ) +#endif + +# include + +#endif // BOOST_CONCEPT_CHECKS_HPP + diff --git a/boost/config.hpp b/boost/config.hpp new file mode 100644 index 00000000..f00a9805 --- /dev/null +++ b/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/boost/config/abi/borland_prefix.hpp b/boost/config/abi/borland_prefix.hpp new file mode 100644 index 00000000..3a0e5ae2 --- /dev/null +++ b/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/boost/config/abi/borland_suffix.hpp b/boost/config/abi/borland_suffix.hpp new file mode 100644 index 00000000..940535f3 --- /dev/null +++ b/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/boost/config/abi/msvc_prefix.hpp b/boost/config/abi/msvc_prefix.hpp new file mode 100644 index 00000000..97f06cdc --- /dev/null +++ b/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/boost/config/abi/msvc_suffix.hpp b/boost/config/abi/msvc_suffix.hpp new file mode 100644 index 00000000..a64d783e --- /dev/null +++ b/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/boost/config/abi_prefix.hpp b/boost/config/abi_prefix.hpp new file mode 100644 index 00000000..3b134749 --- /dev/null +++ b/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( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/boost/config/abi_suffix.hpp b/boost/config/abi_suffix.hpp new file mode 100644 index 00000000..93916166 --- /dev/null +++ b/boost/config/abi_suffix.hpp @@ -0,0 +1,27 @@ +// 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( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + + diff --git a/boost/config/auto_link.hpp b/boost/config/auto_link.hpp new file mode 100644 index 00000000..271f8379 --- /dev/null +++ b/boost/config/auto_link.hpp @@ -0,0 +1,466 @@ +// (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. + +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 + +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. + + +***************************************************************************/ + +#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(__BORLANDC__) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) + +#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) + + // vc14.1: +# define BOOST_LIB_TOOLSET "vc141" + +# elif defined(__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" + +# 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(__BORLANDC__) + +// +// figure out whether we want the debug builds or not: +// +#if __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) + +#ifdef BOOST_AUTO_LINK_TAGGED +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib") +# 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 ".lib") +# endif +#elif defined(BOOST_AUTO_LINK_NOMANGLE) +# pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# 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) ".lib") +# 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) ".lib") +# 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 ".lib") +# 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 ".lib") +# 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 + + diff --git a/boost/config/compiler/borland.hpp b/boost/config/compiler/borland.hpp new file mode 100644 index 00000000..6190e390 --- /dev/null +++ b/boost/config/compiler/borland.hpp @@ -0,0 +1,332 @@ +// (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 "Unknown compiler version - please run the configure tests and report the results" +//# else +//# pragma message( "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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 __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_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) diff --git a/boost/config/compiler/clang.hpp b/boost/config/compiler/clang.hpp new file mode 100644 index 00000000..da736bc4 --- /dev/null +++ b/boost/config/compiler/clang.hpp @@ -0,0 +1,336 @@ +// (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 + + +#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_IMPORT +#endif +#define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) + +// +// 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_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 +#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 + +// 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 __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 +// +// __builtin_unreachable: +#if defined(__has_builtin) && __has_builtin(__builtin_unreachable) +#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); +#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 + diff --git a/boost/config/compiler/codegear.hpp b/boost/config/compiler/codegear.hpp new file mode 100644 index 00000000..44ca8428 --- /dev/null +++ b/boost/config/compiler/codegear.hpp @@ -0,0 +1,235 @@ +// (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: + +#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 +// +// versions check: +// last known and checked version is 0x621 +#if (__CODEGEARC__ > 0x621) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message( "Unknown compiler version - please run the configure tests and report the results") +# endif +#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 + +// +// 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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 + +// +// 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__) + diff --git a/boost/config/compiler/comeau.hpp b/boost/config/compiler/comeau.hpp new file mode 100644 index 00000000..09841604 --- /dev/null +++ b/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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + diff --git a/boost/config/compiler/common_edg.hpp b/boost/config/compiler/common_edg.hpp new file mode 100644 index 00000000..d49ceb68 --- /dev/null +++ b/boost/config/compiler/common_edg.hpp @@ -0,0 +1,156 @@ +// (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_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_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_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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 + +#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/boost/config/compiler/compaq_cxx.hpp b/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 00000000..4d6b8ab3 --- /dev/null +++ b/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/boost/config/compiler/cray.hpp b/boost/config/compiler/cray.hpp new file mode 100644 index 00000000..5f810781 --- /dev/null +++ b/boost/config/compiler/cray.hpp @@ -0,0 +1,124 @@ +// (C) Copyright John Maddock 2011. +// (C) Copyright Cray, Inc. 2013 +// 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 "Cray C version " BOOST_STRINGIZE(_RELEASE) + +#if _RELEASE_MAJOR < 8 +# error "Boost is not configured for Cray compilers prior to version 8, please try the configure script." +#endif + +// +// Check this is a recent EDG based compiler, otherwise we don't support it here: +// +#ifndef __EDG_VERSION__ +# error "Unsupported Cray compiler, please try running the configure script." +#endif + +#if _RELEASE_MINOR < 5 || __cplusplus < 201100 +#include + +// +// +#define BOOST_NO_CXX11_STATIC_ASSERT +#define BOOST_NO_CXX11_AUTO_DECLARATIONS +#define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +#define BOOST_HAS_NRVO +#define BOOST_NO_CXX11_VARIADIC_MACROS +#define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#define BOOST_NO_CXX11_UNICODE_LITERALS +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_HAS_NRVO +#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_NOEXCEPT +#define BOOST_NO_CXX11_LAMBDAS +#define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +#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_N3276 +#define BOOST_NO_CXX11_DECLTYPE +#define BOOST_NO_CXX11_CONSTEXPR +#define BOOST_NO_CXX11_USER_DEFINED_LITERALS +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#define BOOST_NO_CXX11_CHAR32_T +#define BOOST_NO_CXX11_CHAR16_T +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + + +//#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, at least when -hgnu is asserted on the command line. + +#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 + +#else /* _RELEASE_MINOR */ + +#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 < 201400 +#define BOOST_NO_CXX11_DECLTYPE_N3276 +#endif /* __cpluspus */ + +#endif /* _RELEASE_MINOR */ + + + diff --git a/boost/config/compiler/diab.hpp b/boost/config/compiler/diab.hpp new file mode 100644 index 00000000..943db83f --- /dev/null +++ b/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/boost/config/compiler/digitalmars.hpp b/boost/config/compiler/digitalmars.hpp new file mode 100644 index 00000000..e4c5afdd --- /dev/null +++ b/boost/config/compiler/digitalmars.hpp @@ -0,0 +1,137 @@ +// 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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 (__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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/boost/config/compiler/gcc.hpp b/boost/config/compiler/gcc.hpp new file mode 100644 index 00000000..4fe968a0 --- /dev/null +++ b/boost/config/compiler/gcc.hpp @@ -0,0 +1,356 @@ +// (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 +#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_CONSTEXPR +#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) +# 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 +#endif + +// C++0x features in 4.8.n and later +// +#if (BOOST_GCC_VERSION < 40800) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_ALIGNAS +# 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++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 __GNUC__ >= 7 +# define BOOST_FALLTHROUGH __attribute__((fallthrough)) +#endif + +#ifdef __MINGW32__ +// Currently (June 2017) thread_local is broken on mingw for all current compiler releases, see +// https://sourceforge.net/p/mingw-w64/bugs/527/ +// 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__)) + +// +// __builtin_unreachable: +#if BOOST_GCC_VERSION >= 40800 +#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); +#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 7.1: +#if (BOOST_GCC_VERSION > 70100) +# 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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + diff --git a/boost/config/compiler/gcc_xml.hpp b/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 00000000..2b47585a --- /dev/null +++ b/boost/config/compiler/gcc_xml.hpp @@ -0,0 +1,108 @@ +// (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_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 + +#define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ + + diff --git a/boost/config/compiler/greenhills.hpp b/boost/config/compiler/greenhills.hpp new file mode 100644 index 00000000..a76a07cf --- /dev/null +++ b/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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/boost/config/compiler/hp_acc.hpp b/boost/config/compiler/hp_acc.hpp new file mode 100644 index 00000000..9df18eaf --- /dev/null +++ b/boost/config/compiler/hp_acc.hpp @@ -0,0 +1,147 @@ +// (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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_THREAD_LOCAL + +/* + 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 + +#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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/boost/config/compiler/intel.hpp b/boost/config/compiler/intel.hpp new file mode 100644 index 00000000..0eea05b9 --- /dev/null +++ b/boost/config/compiler/intel.hpp @@ -0,0 +1,564 @@ +// (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 + +// 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 + +#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 +#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 +#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 +#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("Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + diff --git a/boost/config/compiler/kai.hpp b/boost/config/compiler/kai.hpp new file mode 100644 index 00000000..960d501c --- /dev/null +++ b/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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + diff --git a/boost/config/compiler/metrowerks.hpp b/boost/config/compiler/metrowerks.hpp new file mode 100644 index 00000000..99ff0f5e --- /dev/null +++ b/boost/config/compiler/metrowerks.hpp @@ -0,0 +1,192 @@ +// (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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 + +#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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + + + + diff --git a/boost/config/compiler/mpw.hpp b/boost/config/compiler/mpw.hpp new file mode 100644 index 00000000..d9544345 --- /dev/null +++ b/boost/config/compiler/mpw.hpp @@ -0,0 +1,134 @@ +// (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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 + +// +// 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 "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/boost/config/compiler/nvcc.hpp b/boost/config/compiler/nvcc.hpp new file mode 100644 index 00000000..f21b9b54 --- /dev/null +++ b/boost/config/compiler/nvcc.hpp @@ -0,0 +1,58 @@ +// (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__ + +// 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 +// Most recent CUDA (8.0) has no constexpr support in msvc mode: +#if defined(_MSC_VER) +# define BOOST_NO_CXX11_CONSTEXPR +#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 + +#endif + diff --git a/boost/config/compiler/pathscale.hpp b/boost/config/compiler/pathscale.hpp new file mode 100644 index 00000000..94b3f91d --- /dev/null +++ b/boost/config/compiler/pathscale.hpp @@ -0,0 +1,132 @@ +// (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_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 +#endif diff --git a/boost/config/compiler/pgi.hpp b/boost/config/compiler/pgi.hpp new file mode 100644 index 00000000..4e909d8a --- /dev/null +++ b/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/boost/config/compiler/sgi_mipspro.hpp b/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 00000000..54433c99 --- /dev/null +++ b/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/boost/config/compiler/sunpro_cc.hpp b/boost/config/compiler/sunpro_cc.hpp new file mode 100644 index 00000000..54ad77a3 --- /dev/null +++ b/boost/config/compiler/sunpro_cc.hpp @@ -0,0 +1,210 @@ +// (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 + +#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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_FINAL +#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 + +// 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/boost/config/compiler/vacpp.hpp b/boost/config/compiler/vacpp.hpp new file mode 100644 index 00000000..c8400a34 --- /dev/null +++ b/boost/config/compiler/vacpp.hpp @@ -0,0 +1,180 @@ +// (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 "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_TRAILING_RESULT_TYPES +#define BOOST_NO_CXX11_INLINE_NAMESPACES +#define BOOST_NO_CXX11_REF_QUALIFIERS +#define BOOST_NO_CXX11_FINAL +#define BOOST_NO_CXX11_THREAD_LOCAL + +// 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 diff --git a/boost/config/compiler/visualc.hpp b/boost/config/compiler/visualc.hpp new file mode 100644 index 00000000..c533c50d --- /dev/null +++ b/boost/config/compiler/visualc.hpp @@ -0,0 +1,354 @@ +// (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 + +#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 + +// +// 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 +#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_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 +#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 +#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: +// +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +#if (_MSC_VER < 1912) || (_MSVC_LANG < 201402) +// Supported from msvc-15.5 onwards: +#define BOOST_NO_CXX11_SFINAE_EXPR +#endif +// C++ 14: +// Still gives internal compiler error for msvc-15.5: +# define BOOST_NO_CXX14_CONSTEXPR +// C++ 17: +#if (_MSC_VER < 1912) || (_MSVC_LANG < 201703) +#define BOOST_NO_CXX17_INLINE_VARIABLES +#define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#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 +#ifndef BOOST_NO_SFINAE_EXPR +# 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 + +#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 "Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("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 "Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# endif +# else +# if _MSC_VER < 1200 + // Note: Versions up to 7.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 +# 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.12.25830.2 (VC++ 2017.3): +#if (_MSC_VER > 1912) +# 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/boost/config/compiler/xlcpp.hpp b/boost/config/compiler/xlcpp.hpp new file mode 100644 index 00000000..a4c66e40 --- /dev/null +++ b/boost/config/compiler/xlcpp.hpp @@ -0,0 +1,281 @@ +// (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_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 +#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 + +// 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 !__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 + + +// 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 + diff --git a/boost/config/compiler/xlcpp_zos.hpp b/boost/config/compiler/xlcpp_zos.hpp new file mode 100644 index 00000000..bc785b8a --- /dev/null +++ b/boost/config/compiler/xlcpp_zos.hpp @@ -0,0 +1,169 @@ +// 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_ALIGNAS +#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 + +// ------------------------------------- + +#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/boost/config/detail/posix_features.hpp b/boost/config/detail/posix_features.hpp new file mode 100644 index 00000000..d1295479 --- /dev/null +++ b/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/boost/config/detail/select_compiler_config.hpp b/boost/config/detail/select_compiler_config.hpp new file mode 100644 index 00000000..ced8443d --- /dev/null +++ b/boost/config/detail/select_compiler_config.hpp @@ -0,0 +1,158 @@ +// 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(__CUDACC__) && !defined(__ibmxl__) +// when using clang and cuda at same time, you want to appear as gcc +// 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/boost/config/detail/select_platform_config.hpp b/boost/config/detail/select_platform_config.hpp new file mode 100644 index 00000000..b36eca57 --- /dev/null +++ b/boost/config/detail/select_platform_config.hpp @@ -0,0 +1,142 @@ +// 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" +#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/boost/config/detail/select_stdlib_config.hpp b/boost/config/detail/select_stdlib_config.hpp new file mode 100644 index 00000000..8db778c8 --- /dev/null +++ b/boost/config/detail/select_stdlib_config.hpp @@ -0,0 +1,110 @@ +// 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 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.) +#ifdef __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/boost/config/detail/suffix.hpp b/boost/config/detail/suffix.hpp new file mode 100644 index 00000000..22d31f68 --- /dev/null +++ b/boost/config/detail/suffix.hpp @@ -0,0 +1,1036 @@ +// 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 symplifying 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 + +// +// 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(__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 + +// 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: +#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) +#include +namespace std{ using ::type_info; } +#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)) +# 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__) +# 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 + +// 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 + +// 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 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 + +// +// Unused variable/typedef workarounds: +// +#ifndef BOOST_ATTRIBUTE_UNUSED +# define BOOST_ATTRIBUTE_UNUSED +#endif + +#define BOOST_STATIC_CONSTEXPR static BOOST_CONSTEXPR_OR_CONST + +// +// 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 + +// +// 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/boost/config/header_deprecated.hpp b/boost/config/header_deprecated.hpp new file mode 100644 index 00000000..864554f2 --- /dev/null +++ b/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) +# 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/boost/config/helper_macros.hpp b/boost/config/helper_macros.hpp new file mode 100644 index 00000000..3e79526d --- /dev/null +++ b/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/boost/config/no_tr1/cmath.hpp b/boost/config/no_tr1/cmath.hpp new file mode 100644 index 00000000..d8268d84 --- /dev/null +++ b/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/boost/config/no_tr1/complex.hpp b/boost/config/no_tr1/complex.hpp new file mode 100644 index 00000000..ca200922 --- /dev/null +++ b/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/boost/config/no_tr1/functional.hpp b/boost/config/no_tr1/functional.hpp new file mode 100644 index 00000000..e395efc1 --- /dev/null +++ b/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/boost/config/no_tr1/memory.hpp b/boost/config/no_tr1/memory.hpp new file mode 100644 index 00000000..2b5d2080 --- /dev/null +++ b/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/boost/config/no_tr1/utility.hpp b/boost/config/no_tr1/utility.hpp new file mode 100644 index 00000000..dea8f115 --- /dev/null +++ b/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/boost/config/platform/aix.hpp b/boost/config/platform/aix.hpp new file mode 100644 index 00000000..a48e2320 --- /dev/null +++ b/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/boost/config/platform/amigaos.hpp b/boost/config/platform/amigaos.hpp new file mode 100644 index 00000000..34bcf412 --- /dev/null +++ b/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/boost/config/platform/beos.hpp b/boost/config/platform/beos.hpp new file mode 100644 index 00000000..6158c1c2 --- /dev/null +++ b/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/boost/config/platform/bsd.hpp b/boost/config/platform/bsd.hpp new file mode 100644 index 00000000..79e74a08 --- /dev/null +++ b/boost/config/platform/bsd.hpp @@ -0,0 +1,86 @@ +// (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(__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(__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 + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + + + + diff --git a/boost/config/platform/cloudabi.hpp b/boost/config/platform/cloudabi.hpp new file mode 100644 index 00000000..bed7b631 --- /dev/null +++ b/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/boost/config/platform/cray.hpp b/boost/config/platform/cray.hpp new file mode 100644 index 00000000..103e9c06 --- /dev/null +++ b/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/boost/config/platform/cygwin.hpp b/boost/config/platform/cygwin.hpp new file mode 100644 index 00000000..6dd7e57c --- /dev/null +++ b/boost/config/platform/cygwin.hpp @@ -0,0 +1,68 @@ +// (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 + +/// Cygwin has no fenv.h +#define BOOST_NO_FENV_H + +// 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/boost/config/platform/haiku.hpp b/boost/config/platform/haiku.hpp new file mode 100644 index 00000000..04244c56 --- /dev/null +++ b/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/boost/config/platform/hpux.hpp b/boost/config/platform/hpux.hpp new file mode 100644 index 00000000..222622e7 --- /dev/null +++ b/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/boost/config/platform/irix.hpp b/boost/config/platform/irix.hpp new file mode 100644 index 00000000..0acb6515 --- /dev/null +++ b/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/boost/config/platform/linux.hpp b/boost/config/platform/linux.hpp new file mode 100644 index 00000000..c4eef8f8 --- /dev/null +++ b/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/boost/config/platform/macos.hpp b/boost/config/platform/macos.hpp new file mode 100644 index 00000000..ed7dc15f --- /dev/null +++ b/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/boost/config/platform/qnxnto.hpp b/boost/config/platform/qnxnto.hpp new file mode 100644 index 00000000..d0298cb4 --- /dev/null +++ b/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/boost/config/platform/solaris.hpp b/boost/config/platform/solaris.hpp new file mode 100644 index 00000000..51ffe67f --- /dev/null +++ b/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/boost/config/platform/symbian.hpp b/boost/config/platform/symbian.hpp new file mode 100644 index 00000000..f814d00b --- /dev/null +++ b/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/boost/config/platform/vms.hpp b/boost/config/platform/vms.hpp new file mode 100644 index 00000000..f70efcfb --- /dev/null +++ b/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/boost/config/platform/vxworks.hpp b/boost/config/platform/vxworks.hpp new file mode 100644 index 00000000..a91e4ab4 --- /dev/null +++ b/boost/config/platform/vxworks.hpp @@ -0,0 +1,433 @@ +// (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! +// +// Equally, this file has been tested for RTPs (Real Time Processes) +// only, not for DKMs (Downloadable Kernel Modules). These two types +// of executables differ largely in the available functionality of +// the C-library, STL, and so on. A DKM uses a C89 library with no +// wide character support and no guarantee of ANSI C. 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. +// ==================================================================== +// +// Additional Configuration +// ------------------------------------------------------------------- +// +// Because of the ordering of include files and other issues the following +// additional definitions worked better outside this file. +// +// When building the log library add the following to the b2 invocation +// define=BOOST_LOG_WITHOUT_IPC +// and +// -DBOOST_LOG_WITHOUT_DEFAULT_FACTORIES +// to your compile options. +// +// When building the test library add +// -DBOOST_TEST_LIMITED_SIGNAL_DETAILS +// to your compile options +// +// When building containers library add +// -DHAVE_MORECORE=0 +// to your c compile options so dlmalloc heap library is compiled +// without brk() calls +// +// ==================================================================== +// +// 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" + +// Special behaviour for DKMs: +#ifdef _WRS_KERNEL + // DKMs 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 + +// 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... +#define BOOST_LOCALE_WITH_ICU + +// 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 +#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 + +// 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 + +// 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) +#ifndef _WRS_CONFIG_LANG_LIB_CPLUS_CPLUS_USER_2011 +# 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 + +// 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/boost/config/platform/win32.hpp b/boost/config/platform/win32.hpp new file mode 100644 index 00000000..450158fb --- /dev/null +++ b/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/boost/config/platform/zos.hpp b/boost/config/platform/zos.hpp new file mode 100644 index 00000000..fa77999e --- /dev/null +++ b/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/boost/config/pragma_message.hpp b/boost/config/pragma_message.hpp new file mode 100644 index 00000000..b2c5ff2e --- /dev/null +++ b/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/boost/config/requires_threads.hpp b/boost/config/requires_threads.hpp new file mode 100644 index 00000000..cfaff230 --- /dev/null +++ b/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 __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/boost/config/stdlib/dinkumware.hpp b/boost/config/stdlib/dinkumware.hpp new file mode 100644 index 00000000..641c2ae2 --- /dev/null +++ b/boost/config/stdlib/dinkumware.hpp @@ -0,0 +1,258 @@ +// (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(__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(__BORLANDC__) +# define BOOST_STD_EXTENSION_NAMESPACE stdext +#endif + + +#if (defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(__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 + +// 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 && ((defined(BOOST_MSVC) && BOOST_MSVC >= 1400) || (defined(__clang__) && defined(_MSC_VER))) +#include +#endif +#include +#if ( (!_HAS_EXCEPTIONS && !defined(__ghs__)) || (!_HAS_NAMESPACE && defined(__ghs__)) ) && !defined(__TI_COMPILER_VERSION__) && !defined(__VISUALDSPVERSION__) \ + && !defined(__VXWORKS__) +# 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 +#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(_HAS_CXX17) || (_HAS_CXX17 == 0) +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_ITERATOR_TRAITS +#endif +#if !defined(_CPPLIB_VER) || (_CPPLIB_VER < 650) +# define BOOST_NO_CXX17_STD_INVOKE +#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) +# 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 +# endif +#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 + +#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/boost/config/stdlib/libcomo.hpp b/boost/config/stdlib/libcomo.hpp new file mode 100644 index 00000000..75ac2bb7 --- /dev/null +++ b/boost/config/stdlib/libcomo.hpp @@ -0,0 +1,92 @@ +// (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_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/boost/config/stdlib/libcpp.hpp b/boost/config/stdlib/libcpp.hpp new file mode 100644 index 00000000..1e77dca3 --- /dev/null +++ b/boost/config/stdlib/libcpp.hpp @@ -0,0 +1,133 @@ +// (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_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 < 3700) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_INVOKE +#endif +#if (_LIBCPP_VERSION < 4000) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_APPLY +#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 + +#define BOOST_NO_CXX17_ITERATOR_TRAITS + +#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__) && !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`. +# 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 + +// --- end --- diff --git a/boost/config/stdlib/libstdcpp3.hpp b/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 00000000..e99fe316 --- /dev/null +++ b/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,349 @@ +// (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 + +// +// 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__ + +#if __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 + +#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 !_GLIBCXX_USE_DEPRECATED +# define BOOST_NO_AUTO_PTR +# 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 +#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 + +#if defined(__clang_major__) && ((__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 7))) +// As of clang-3.6, libstdc++ header throws up errors with clang: +# define BOOST_NO_CXX11_HDR_ATOMIC +#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 6.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 60100) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_INVOKE +#endif +#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_APPLY +#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 || (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#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) +// Timed mutexes are not always available: +# define BOOST_NO_CXX11_HDR_MUTEX +#endif + +// --- end --- diff --git a/boost/config/stdlib/modena.hpp b/boost/config/stdlib/modena.hpp new file mode 100644 index 00000000..81919e01 --- /dev/null +++ b/boost/config/stdlib/modena.hpp @@ -0,0 +1,78 @@ +// (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 + +#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/boost/config/stdlib/msl.hpp b/boost/config/stdlib/msl.hpp new file mode 100644 index 00000000..0e2e2afe --- /dev/null +++ b/boost/config/stdlib/msl.hpp @@ -0,0 +1,97 @@ +// (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 + +#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/boost/config/stdlib/roguewave.hpp b/boost/config/stdlib/roguewave.hpp new file mode 100644 index 00000000..df602155 --- /dev/null +++ b/boost/config/stdlib/roguewave.hpp @@ -0,0 +1,207 @@ +// (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 __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 + +#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/boost/config/stdlib/sgi.hpp b/boost/config/stdlib/sgi.hpp new file mode 100644 index 00000000..0c8ab2e4 --- /dev/null +++ b/boost/config/stdlib/sgi.hpp @@ -0,0 +1,167 @@ +// (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 + +#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/boost/config/stdlib/stlport.hpp b/boost/config/stdlib/stlport.hpp new file mode 100644 index 00000000..2e304e2b --- /dev/null +++ b/boost/config/stdlib/stlport.hpp @@ -0,0 +1,257 @@ +// (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(__BORLANDC__) +# define BOOST_NO_STD_LOCALE +# endif +#else +# if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__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(__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(__BORLANDC__) && __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(__BORLANDC__) && (__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 + +#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/boost/config/stdlib/vacpp.hpp b/boost/config/stdlib/vacpp.hpp new file mode 100644 index 00000000..c4e1fb18 --- /dev/null +++ b/boost/config/stdlib/vacpp.hpp @@ -0,0 +1,73 @@ +// (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 + +#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/boost/config/stdlib/xlcpp_zos.hpp b/boost/config/stdlib/xlcpp_zos.hpp new file mode 100644 index 00000000..4d5beb18 --- /dev/null +++ b/boost/config/stdlib/xlcpp_zos.hpp @@ -0,0 +1,60 @@ +// 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_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/boost/config/user.hpp b/boost/config/user.hpp new file mode 100644 index 00000000..28e7476a --- /dev/null +++ b/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/boost/config/warning_disable.hpp b/boost/config/warning_disable.hpp new file mode 100644 index 00000000..fea8e829 --- /dev/null +++ b/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/boost/config/workaround.hpp b/boost/config/workaround.hpp new file mode 100644 index 00000000..fca8f3ab --- /dev/null +++ b/boost/config/workaround.hpp @@ -0,0 +1,279 @@ +// 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 _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 _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 +// 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/boost/container/allocator_traits.hpp b/boost/container/allocator_traits.hpp new file mode 100644 index 00000000..af32f182 --- /dev/null +++ b/boost/container/allocator_traits.hpp @@ -0,0 +1,477 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Pablo Halpern 2009. 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) +// +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2011-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP +#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +#include +#include //is_empty +#include +#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP +#include +#endif +// intrusive +#include +#include +// move +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +// other boost +#include + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2 +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2 +#include + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1 +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1 +#include + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1 +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9 +#include + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +template +class small_vector_allocator; + +namespace allocator_traits_detail { + +BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size) +BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction) + +} //namespace allocator_traits_detail { + +namespace dtl { + +//workaround needed for C++03 compilers with no construct() +//supporting rvalue references +template +struct is_std_allocator +{ static const bool value = false; }; + +template +struct is_std_allocator< std::allocator > +{ static const bool value = true; }; + +template +struct is_std_allocator< small_vector_allocator< std::allocator > > +{ static const bool value = true; }; + +template +struct is_not_std_allocator +{ static const bool value = !is_std_allocator::value; }; + +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_always_equal) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_partially_propagable) + +} //namespace dtl { + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! The class template allocator_traits supplies a uniform interface to all allocator types. +//! This class is a C++03-compatible implementation of std::allocator_traits +template +struct allocator_traits +{ + //allocator_type + typedef Allocator allocator_type; + //value_type + typedef typename allocator_type::value_type value_type; + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Allocator::pointer if such a type exists; otherwise, value_type* + //! + typedef unspecified pointer; + //! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits::rebind::rebind. + //! + typedef see_documentation void_pointer; + //! Allocator::const_void_pointer if such a type exists ; otherwis e, pointer_traits::rebind::difference_type. + //! + typedef see_documentation difference_type; + //! Allocator::size_type if such a type exists ; otherwise, make_unsigned::type + //! + typedef see_documentation size_type; + //! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false. + typedef see_documentation propagate_on_container_copy_assignment; + //! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false. + typedef see_documentation propagate_on_container_move_assignment; + //! Allocator::propagate_on_container_swap if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false. + typedef see_documentation propagate_on_container_swap; + //! Allocator::is_always_equal if such a type exists, otherwise a type + //! with an internal constant static boolean member value == is_empty::value + typedef see_documentation is_always_equal; + //! Allocator::is_partially_propagable if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false + //! Note: Non-standard extension used to implement `small_vector_allocator`. + typedef see_documentation is_partially_propagable; + //! Defines an allocator: Allocator::rebind::other if such a type exists; otherwise, Allocator + //! if Allocator is a class template instantiation of the form Allocator, where Args is zero or + //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed. + //! + //! In C++03 compilers rebind_alloc is a struct derived from an allocator + //! deduced by previously detailed rules. + template using rebind_alloc = see_documentation; + + //! In C++03 compilers rebind_traits is a struct derived from + //! allocator_traits, where OtherAlloc is + //! the allocator deduced by rules explained in rebind_alloc. + template using rebind_traits = allocator_traits >; + + //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. + //! type is an allocator related to Allocator deduced deduced by rules explained in rebind_alloc. + template + struct portable_rebind_alloc + { typedef see_documentation type; }; + #else + //pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + pointer, value_type*) + pointer; + //const_pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, + const_pointer, typename boost::intrusive::pointer_traits::template + rebind_pointer) + const_pointer; + //reference + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + reference, typename dtl::unvoid_ref::type) + reference; + //const_reference + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + const_reference, typename dtl::unvoid_ref::type) + const_reference; + //void_pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, + void_pointer, typename boost::intrusive::pointer_traits::template + rebind_pointer) + void_pointer; + //const_void_pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, + const_void_pointer, typename boost::intrusive::pointer_traits::template + rebind_pointer) + const_void_pointer; + //difference_type + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + difference_type, std::ptrdiff_t) + difference_type; + //size_type + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + size_type, std::size_t) + size_type; + //propagate_on_container_copy_assignment + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + propagate_on_container_copy_assignment, dtl::false_type) + propagate_on_container_copy_assignment; + //propagate_on_container_move_assignment + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + propagate_on_container_move_assignment, dtl::false_type) + propagate_on_container_move_assignment; + //propagate_on_container_swap + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + propagate_on_container_swap, dtl::false_type) + propagate_on_container_swap; + //is_always_equal + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + is_always_equal, dtl::is_empty) + is_always_equal; + //is_partially_propagable + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + is_partially_propagable, dtl::false_type) + is_partially_propagable; + + //rebind_alloc & rebind_traits + #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + //C++11 + template using rebind_alloc = typename boost::intrusive::pointer_rebind::type; + template using rebind_traits = allocator_traits< rebind_alloc >; + #else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + //Some workaround for C++03 or C++11 compilers with no template aliases + template + struct rebind_alloc : boost::intrusive::pointer_rebind::type + { + typedef typename boost::intrusive::pointer_rebind::type Base; + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward(args)...) {} + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ + explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC + #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + }; + + template + struct rebind_traits + : allocator_traits::type> + {}; + #endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + + //portable_rebind_alloc + template + struct portable_rebind_alloc + { typedef typename boost::intrusive::pointer_rebind::type type; }; + #endif //BOOST_CONTAINER_DOXYGEN_INVOKED + + //! Returns: a.allocate(n) + //! + BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n) + { return a.allocate(n); } + + //! Returns: a.deallocate(p, n) + //! + //! Throws: Nothing + BOOST_CONTAINER_FORCEINLINE static void deallocate(Allocator &a, pointer p, size_type n) + { a.deallocate(p, n); } + + //! Effects: calls a.allocate(n, p) if that call is well-formed; + //! otherwise, invokes a.allocate(n) + BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n, const_void_pointer p) + { + const bool value = boost::container::dtl:: + has_member_function_callable_with_allocate + ::value; + dtl::bool_ flag; + return allocator_traits::priv_allocate(flag, a, n, p); + } + + //! Effects: calls a.destroy(p) if that call is well-formed; + //! otherwise, invokes p->~T(). + template + BOOST_CONTAINER_FORCEINLINE static void destroy(Allocator &a, T*p) BOOST_NOEXCEPT_OR_NOTHROW + { + typedef T* destroy_pointer; + const bool value = boost::container::dtl:: + has_member_function_callable_with_destroy + ::value; + dtl::bool_ flag; + allocator_traits::priv_destroy(flag, a, p); + } + + //! Returns: a.max_size() if that expression is well-formed; otherwise, + //! numeric_limits::max(). + BOOST_CONTAINER_FORCEINLINE static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW + { + const bool value = allocator_traits_detail::has_max_size::value; + dtl::bool_ flag; + return allocator_traits::priv_max_size(flag, a); + } + + //! Returns: a.select_on_container_copy_construction() if that expression is well-formed; + //! otherwise, a. + BOOST_CONTAINER_FORCEINLINE static BOOST_CONTAINER_DOC1ST(Allocator, + typename dtl::if_c + < allocator_traits_detail::has_select_on_container_copy_construction::value + BOOST_MOVE_I Allocator BOOST_MOVE_I const Allocator & >::type) + select_on_container_copy_construction(const Allocator &a) + { + const bool value = allocator_traits_detail::has_select_on_container_copy_construction + ::value; + dtl::bool_ flag; + return allocator_traits::priv_select_on_container_copy_construction(flag, a); + } + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; + //! otherwise, invokes `placement new` (static_cast(p)) T(std::forward(args)...) + template + BOOST_CONTAINER_FORCEINLINE static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args) + { + static const bool value = ::boost::move_detail::and_ + < dtl::is_not_std_allocator + , boost::container::dtl::has_member_function_callable_with_construct + < Allocator, T*, Args... > + >::value; + dtl::bool_ flag; + allocator_traits::priv_construct(flag, a, p, ::boost::forward(args)...); + } + #endif + + //! Returns: a.storage_is_unpropagable(p) if is_partially_propagable::value is true; otherwise, + //! false. + BOOST_CONTAINER_FORCEINLINE static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW + { + dtl::bool_ flag; + return allocator_traits::priv_storage_is_unpropagable(flag, a, p); + } + + //! Returns: true if is_always_equal::value == true, otherwise, + //! a == b. + BOOST_CONTAINER_FORCEINLINE static bool equal(const Allocator &a, const Allocator &b) BOOST_NOEXCEPT_OR_NOTHROW + { + dtl::bool_ flag; + return allocator_traits::priv_equal(flag, a, b); + } + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + private: + BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::true_type, Allocator &a, size_type n, const_void_pointer p) + { return a.allocate(n, p); } + + BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::false_type, Allocator &a, size_type n, const_void_pointer) + { return a.allocate(n); } + + template + BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::true_type, Allocator &a, T* p) BOOST_NOEXCEPT_OR_NOTHROW + { a.destroy(p); } + + template + BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::false_type, Allocator &, T* p) BOOST_NOEXCEPT_OR_NOTHROW + { p->~T(); (void)p; } + + BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::true_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW + { return a.max_size(); } + + BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::false_type, const Allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return size_type(-1)/sizeof(value_type); } + + BOOST_CONTAINER_FORCEINLINE static Allocator priv_select_on_container_copy_construction(dtl::true_type, const Allocator &a) + { return a.select_on_container_copy_construction(); } + + BOOST_CONTAINER_FORCEINLINE static const Allocator &priv_select_on_container_copy_construction(dtl::false_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW + { return a; } + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) + { a.construct( p, ::boost::forward(args)...); } + + template + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args) + { ::new((void*)p, boost_container_new_t()) T(::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + public: + + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \ + template\ + BOOST_CONTAINER_FORCEINLINE static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + static const bool value = ::boost::move_detail::and_ \ + < dtl::is_not_std_allocator \ + , boost::container::dtl::has_member_function_callable_with_construct \ + < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N > \ + >::value; \ + dtl::bool_ flag;\ + (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL + + private: + ///////////////////////////////// + // priv_construct + ///////////////////////////////// + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \ + template\ + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\ + \ + template\ + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL + + #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, const ::boost::container::default_init_t&) + { ::new((void*)p, boost_container_new_t()) T; } + + BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::true_type, const Allocator &a, pointer p) + { return a.storage_is_unpropagable(p); } + + BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::false_type, const Allocator &, pointer) + { return false; } + + BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::true_type, const Allocator &, const Allocator &) + { return true; } + + BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::false_type, const Allocator &a, const Allocator &b) + { return a == b; } + + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) +}; + +} //namespace container { +} //namespace boost { + +#include + +#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP) diff --git a/boost/container/container_fwd.hpp b/boost/container/container_fwd.hpp new file mode 100644 index 00000000..e4fe6f85 --- /dev/null +++ b/boost/container/container_fwd.hpp @@ -0,0 +1,296 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP +#define BOOST_CONTAINER_CONTAINER_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//! \file +//! This header file forward declares the following containers: +//! - boost::container::vector +//! - boost::container::stable_vector +//! - boost::container::static_vector +//! - boost::container::small_vector +//! - boost::container::slist +//! - boost::container::list +//! - boost::container::set +//! - boost::container::multiset +//! - boost::container::map +//! - boost::container::multimap +//! - boost::container::flat_set +//! - boost::container::flat_multiset +//! - boost::container::flat_map +//! - boost::container::flat_multimap +//! - boost::container::basic_string +//! - boost::container::string +//! - boost::container::wstring +//! +//! Forward declares the following allocators: +//! - boost::container::allocator +//! - boost::container::node_allocator +//! - boost::container::adaptive_pool +//! +//! Forward declares the following polymorphic resource classes: +//! - boost::container::pmr::memory_resource +//! - boost::container::pmr::polymorphic_allocator +//! - boost::container::pmr::monotonic_buffer_resource +//! - boost::container::pmr::pool_options +//! - boost::container::pmr::unsynchronized_pool_resource +//! - boost::container::pmr::synchronized_pool_resource +//! +//! And finally it defines the following types + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//Std forward declarations +#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP + #include +#endif + +namespace boost{ +namespace intrusive{ +namespace detail{ + //Create namespace to avoid compilation errors +}}} + +namespace boost{ namespace container{ namespace dtl{ + namespace bi = boost::intrusive; + namespace bid = boost::intrusive::detail; +}}} + +namespace boost{ namespace container{ namespace pmr{ + namespace bi = boost::intrusive; + namespace bid = boost::intrusive::detail; +}}} + +#include + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +////////////////////////////////////////////////////////////////////////////// +// Containers +////////////////////////////////////////////////////////////////////////////// + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +template +class new_allocator; + +template + ,class Options = void> +class vector; + +template > +class stable_vector; + +template +class static_vector; + +template < class T, std::size_t N + , class Allocator= new_allocator > +class small_vector; + +template > +class deque; + +template > +class list; + +template > +class slist; + +template + ,class Allocator = new_allocator + ,class Options = void> +class set; + +template + ,class Allocator = new_allocator + ,class Options = void > +class multiset; + +template + ,class Allocator = new_allocator > + ,class Options = void > +class map; + +template + ,class Allocator = new_allocator > + ,class Options = void > +class multimap; + +template + ,class Allocator = new_allocator > +class flat_set; + +template + ,class Allocator = new_allocator > +class flat_multiset; + +template + ,class Allocator = new_allocator > > +class flat_map; + +template + ,class Allocator = new_allocator > > +class flat_multimap; + +template + ,class Allocator = new_allocator > +class basic_string; + +typedef basic_string + + ,new_allocator > +string; + +typedef basic_string + + ,new_allocator > +wstring; + +static const std::size_t ADP_nodes_per_block = 256u; +static const std::size_t ADP_max_free_blocks = 2u; +static const std::size_t ADP_overhead_percent = 1u; +static const std::size_t ADP_only_alignment = 0u; + +template < class T + , std::size_t NodesPerBlock = ADP_nodes_per_block + , std::size_t MaxFreeBlocks = ADP_max_free_blocks + , std::size_t OverheadPercent = ADP_overhead_percent + , unsigned Version = 2 + > +class adaptive_pool; + +template < class T + , unsigned Version = 2 + , unsigned int AllocationDisableMask = 0> +class allocator; + +static const std::size_t NodeAlloc_nodes_per_block = 256u; + +template + < class T + , std::size_t NodesPerBlock = NodeAlloc_nodes_per_block + , std::size_t Version = 2> +class node_allocator; + +namespace pmr { + +class memory_resource; + +template +class polymorphic_allocator; + +class monotonic_buffer_resource; + +struct pool_options; + +template +class resource_adaptor_imp; + +class unsynchronized_pool_resource; + +class synchronized_pool_resource; + +} //namespace pmr { + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! Type used to tag that the input range is +//! guaranteed to be ordered +struct ordered_range_t +{}; + +//! Value used to tag that the input range is +//! guaranteed to be ordered +static const ordered_range_t ordered_range = ordered_range_t(); + +//! Type used to tag that the input range is +//! guaranteed to be ordered and unique +struct ordered_unique_range_t + : public ordered_range_t +{}; + +//! Value used to tag that the input range is +//! guaranteed to be ordered and unique +static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t(); + +//! Type used to tag that the inserted values +//! should be default initialized +struct default_init_t +{}; + +//! Value used to tag that the inserted values +//! should be default initialized +static const default_init_t default_init = default_init_t(); +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! Type used to tag that the inserted values +//! should be value initialized +struct value_init_t +{}; + +//! Value used to tag that the inserted values +//! should be value initialized +static const value_init_t value_init = value_init_t(); + +namespace container_detail_really_deep_namespace { + +//Otherwise, gcc issues a warning of previously defined +//anonymous_instance and unique_instance +struct dummy +{ + dummy() + { + (void)ordered_range; + (void)ordered_unique_range; + (void)default_init; + } +}; + +} //detail_really_deep_namespace { + + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +}} //namespace boost { namespace container { + +#endif //#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP diff --git a/boost/container/detail/addressof.hpp b/boost/container/detail/addressof.hpp new file mode 100644 index 00000000..b3b8a4dd --- /dev/null +++ b/boost/container/detail/addressof.hpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP +#define BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace container { +namespace dtl { + +template +BOOST_CONTAINER_FORCEINLINE T* addressof(T& obj) +{ + return static_cast( + static_cast( + const_cast( + &reinterpret_cast(obj) + ))); +} + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP diff --git a/boost/container/detail/advanced_insert_int.hpp b/boost/container/detail/advanced_insert_int.hpp new file mode 100644 index 00000000..d9cba485 --- /dev/null +++ b/boost/container/detail/advanced_insert_int.hpp @@ -0,0 +1,477 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP +#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +// container/detail +#include +#include +#include +#include +#include +#include +#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +// move +#include +// other +#include +#include + +namespace boost { namespace container { namespace dtl { + +template +struct move_insert_range_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + explicit move_insert_range_proxy(FwdIt first) + : first_(first) + {} + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + { + this->first_ = ::boost::container::uninitialized_move_alloc_n_source + (a, this->first_, n, p); + } + + void copy_n_and_update(Allocator &, Iterator p, size_type n) + { + this->first_ = ::boost::container::move_n_source(this->first_, n, p); + } + + FwdIt first_; +}; + + +template +struct insert_range_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + explicit insert_range_proxy(FwdIt first) + : first_(first) + {} + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + { + this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); + } + + void copy_n_and_update(Allocator &, Iterator p, size_type n) + { + this->first_ = ::boost::container::copy_n_source(this->first_, n, p); + } + + FwdIt first_; +}; + + +template +struct insert_n_copies_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + explicit insert_n_copies_proxy(const value_type &v) + : v_(v) + {} + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } + + void copy_n_and_update(Allocator &, Iterator p, size_type n) const + { + for (; 0 < n; --n, ++p){ + *p = v_; + } + } + + const value_type &v_; +}; + +template +struct insert_value_initialized_n_proxy +{ + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { boost::container::uninitialized_value_init_alloc_n(a, n, p); } + + void copy_n_and_update(Allocator &, Iterator, size_type) const + { BOOST_ASSERT(false); } +}; + +template +struct insert_default_initialized_n_proxy +{ + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { boost::container::uninitialized_default_init_alloc_n(a, n, p); } + + void copy_n_and_update(Allocator &, Iterator, size_type) const + { BOOST_ASSERT(false); } +}; + +template +struct insert_copy_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + explicit insert_copy_proxy(const value_type &v) + : v_(v) + {} + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_); + } + + void copy_n_and_update(Allocator &, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + *p = v_; + } + + const value_type &v_; +}; + + +template +struct insert_move_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + explicit insert_move_proxy(value_type &v) + : v_(v) + {} + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) ); + } + + void copy_n_and_update(Allocator &, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + *p = ::boost::move(v_); + } + + value_type &v_; +}; + +template +insert_move_proxy get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits::value_type) v) +{ + return insert_move_proxy(v); +} + +template +insert_copy_proxy get_insert_value_proxy(const typename boost::container::iterator_traits::value_type &v) +{ + return insert_copy_proxy(v); +} + +}}} //namespace boost { namespace container { namespace dtl { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +template +struct insert_nonmovable_emplace_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + typedef typename build_number_seq::type index_tuple_t; + + explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args) + : args_(args...) + {} + + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); } + + private: + template + void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple&, Iterator p, size_type n) + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward(get(this->args_))... ); + } + + protected: + tuple args_; +}; + +template +struct insert_emplace_proxy + : public insert_nonmovable_emplace_proxy +{ + typedef insert_nonmovable_emplace_proxy base_t; + typedef boost::container::allocator_traits alloc_traits; + typedef typename base_t::value_type value_type; + typedef typename base_t::size_type size_type; + typedef typename base_t::index_tuple_t index_tuple_t; + + explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args) + : base_t(::boost::forward(args)...) + {} + + void copy_n_and_update(Allocator &a, Iterator p, size_type n) + { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } + + private: + + template + void priv_copy_some_and_update(Allocator &a, const index_tuple&, Iterator p, size_type n) + { + BOOST_ASSERT(n ==1); (void)n; + typename aligned_storage::value>::type v; + value_type *vp = static_cast(static_cast(v.data)); + alloc_traits::construct(a, vp, + ::boost::forward(get(this->args_))...); + BOOST_TRY{ + *p = ::boost::move(*vp); + } + BOOST_CATCH(...){ + alloc_traits::destroy(a, vp); + BOOST_RETHROW + } + BOOST_CATCH_END + alloc_traits::destroy(a, vp); + } +}; + +//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type +template +struct insert_emplace_proxy::value_type> + : public insert_move_proxy +{ + explicit insert_emplace_proxy(typename boost::container::allocator_traits::value_type &&v) + : insert_move_proxy(v) + {} +}; + +//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking +//compiler error C2752 ("more than one partial specialization matches"). +//Any problem is solvable with an extra layer of indirection? ;-) +template +struct insert_emplace_proxy::value_type>::type + > + : public insert_copy_proxy +{ + explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy::value_type &> + : public insert_copy_proxy +{ + explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy::value_type>::type & + > + : public insert_copy_proxy +{ + explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +}}} //namespace boost { namespace container { namespace dtl { + +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include + +namespace boost { +namespace container { +namespace dtl { + +#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \ +template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +struct insert_nonmovable_emplace_proxy##N\ +{\ + typedef boost::container::allocator_traits alloc_traits;\ + typedef typename alloc_traits::size_type size_type;\ + typedef typename alloc_traits::value_type value_type;\ + \ + explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\ + BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\ + \ + void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + {\ + BOOST_ASSERT(n == 1); (void)n;\ + alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + }\ + \ + void copy_n_and_update(Allocator &, Iterator, size_type)\ + { BOOST_ASSERT(false); }\ + \ + protected:\ + BOOST_MOVE_MREF##N\ +};\ +\ +template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +struct insert_emplace_proxy_arg##N\ + : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\ +{\ + typedef insert_nonmovable_emplace_proxy##N\ + < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\ + typedef typename base_t::value_type value_type;\ + typedef typename base_t::size_type size_type;\ + typedef boost::container::allocator_traits alloc_traits;\ + \ + explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\ + : base_t(BOOST_MOVE_FWD##N){}\ + \ + void copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + {\ + BOOST_ASSERT(n == 1); (void)n;\ + typename aligned_storage::value>::type v;\ + BOOST_ASSERT((((size_type)(&v)) % alignment_of::value) == 0);\ + value_type *vp = static_cast(static_cast(v.data));\ + alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + BOOST_TRY{\ + *p = ::boost::move(*vp);\ + }\ + BOOST_CATCH(...){\ + alloc_traits::destroy(a, vp);\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ + alloc_traits::destroy(a, vp);\ + }\ +};\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE) +#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type +template +struct insert_emplace_proxy_arg1::value_type> > + : public insert_move_proxy +{ + explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &v) + : insert_move_proxy(v) + {} +}; + +template +struct insert_emplace_proxy_arg1::value_type> + : public insert_copy_proxy +{ + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +#else //e.g. MSVC10 & MSVC11 + +//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type +template +struct insert_emplace_proxy_arg1::value_type> + : public insert_move_proxy +{ + explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &&v) + : insert_move_proxy(v) + {} +}; + +//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking +//compiler error C2752 ("more than one partial specialization matches"). +//Any problem is solvable with an extra layer of indirection? ;-) +template +struct insert_emplace_proxy_arg1::value_type>::type + > + : public insert_copy_proxy +{ + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy_arg1::value_type &> + : public insert_copy_proxy +{ + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy_arg1::value_type>::type & + > + : public insert_copy_proxy +{ + explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +#endif + +}}} //namespace boost { namespace container { namespace dtl { + +#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include + +#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP diff --git a/boost/container/detail/algorithm.hpp b/boost/container/detail/algorithm.hpp new file mode 100644 index 00000000..11844220 --- /dev/null +++ b/boost/container/detail/algorithm.hpp @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP +#define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace container { + +using boost::intrusive::algo_equal; +using boost::intrusive::algo_lexicographical_compare; + +template +class binder1st +{ + public: + typedef typename Func::second_argument_type argument_type; + typedef typename Func::result_type result_type; + + binder1st(const Func& func, const typename Func::first_argument_type& arg) + : op(func), value(arg) + {} + + result_type operator()(const argument_type& arg) const + { return op(value, arg); } + + result_type operator()(argument_type& arg) const + { return op(value, arg); } + + private: + Func op; + typename Func::first_argument_type value; +}; + +template +inline binder1st bind1st(const Func& func, const T& arg) +{ return boost::container::binder1st(func, arg); } + +template +class binder2nd +{ + public: + typedef typename Func::first_argument_type argument_type; + typedef typename Func::result_type result_type; + + binder2nd(const Func& func, const typename Func::second_argument_type& arg) + : op(func), value(arg) + {} + + result_type operator()(const argument_type& arg) const + { return op(arg, value); } + + result_type operator()(argument_type& arg) const + { return op(arg, value); } + + private: + Func op; + typename Func::second_argument_type value; +}; + +template +inline binder2nd bind2nd(const Func& func, const T& arg) +{ + return (boost::container::binder2nd(func, arg)); +} + +template +class unary_negate +{ + public: + typedef typename Func::argument_type argument_type; + typedef typename Func::result_type result_type; + + explicit unary_negate(const Func& func) + : m_func(func) + {} + + bool operator()(const typename Func::argument_type& arg) const + { return !m_func(arg); } + + private: + Func m_func; +}; + +template inline +unary_negate not1(const Func& func) +{ + return boost::container::unary_negate(func); +} + +template +InputIt find_if(InputIt first, InputIt last, UnaryPredicate p) +{ + for (; first != last; ++first) { + if (p(*first)) { + return first; + } + } + return last; +} + +template +InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p) +{ + for (; first1 != last1; ++first1) { + for (ForwardIt it = first2; it != last2; ++it) { + if (p(*first1, *it)) { + return first1; + } + } + } + return last1; +} + +template +ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1, + ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p) +{ + for (; ; ++first1) { + ForwardIt1 it = first1; + for (ForwardIt2 it2 = first2; ; ++it, ++it2) { + if (it2 == last2) { + return first1; + } + if (it == last1) { + return last1; + } + if (!p(*it, *it2)) { + break; + } + } + } +} + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP diff --git a/boost/container/detail/alloc_helpers.hpp b/boost/container/detail/alloc_helpers.hpp new file mode 100644 index 00000000..57c59e46 --- /dev/null +++ b/boost/container/detail/alloc_helpers.hpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP +#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// move +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +template +inline void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type) + BOOST_NOEXCEPT_OR_NOTHROW +{} + +template +inline void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) +{ boost::adl_move_swap(l, r); } + +template +inline void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type) + BOOST_NOEXCEPT_OR_NOTHROW +{} + +template +inline void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type) +{ l = r; } + +template +inline void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type) + BOOST_NOEXCEPT_OR_NOTHROW +{} + +template +inline void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) +{ l = ::boost::move(r); } + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP diff --git a/boost/container/detail/allocation_type.hpp b/boost/container/detail/allocation_type.hpp new file mode 100644 index 00000000..1e8aa673 --- /dev/null +++ b/boost/container/detail/allocation_type.hpp @@ -0,0 +1,58 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP +#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +enum allocation_type_v +{ + // constants for allocation commands + allocate_new_v = 0x01, + expand_fwd_v = 0x02, + expand_bwd_v = 0x04, +// expand_both = expand_fwd | expand_bwd, +// expand_or_new = allocate_new | expand_both, + shrink_in_place_v = 0x08, + nothrow_allocation_v = 0x10, + zero_memory_v = 0x20, + try_shrink_in_place_v = 0x40 +}; + +typedef unsigned int allocation_type; +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +static const allocation_type allocate_new = (allocation_type)allocate_new_v; +static const allocation_type expand_fwd = (allocation_type)expand_fwd_v; +static const allocation_type expand_bwd = (allocation_type)expand_bwd_v; +static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v; +static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v; +static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v; +static const allocation_type zero_memory = (allocation_type)zero_memory_v; + +} //namespace container { +} //namespace boost { + +#include + +#endif //BOOST_CONTAINER_ALLOCATION_TYPE_HPP diff --git a/boost/container/detail/config_begin.hpp b/boost/container/detail/config_begin.hpp new file mode 100644 index 00000000..4df9e35d --- /dev/null +++ b/boost/container/detail/config_begin.hpp @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED +#define BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#endif //BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED + +#ifdef BOOST_MSVC + #pragma warning (push) + #pragma warning (disable : 4127) // conditional expression is constant + #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning (disable : 4197) // top-level volatile in cast is ignored + #pragma warning (disable : 4244) // possible loss of data + #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" + #pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data + #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) + #pragma warning (disable : 4324) // structure was padded due to __declspec(align( + #pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized + #pragma warning (disable : 4355) // "this" : used in base member initializer list + #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated + #pragma warning (disable : 4510) // default constructor could not be generated + #pragma warning (disable : 4511) // copy constructor could not be generated + #pragma warning (disable : 4512) // assignment operator could not be generated + #pragma warning (disable : 4514) // unreferenced inline removed + #pragma warning (disable : 4521) // Disable "multiple copy constructors specified" + #pragma warning (disable : 4522) // "class" : multiple assignment operators specified + #pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result + #pragma warning (disable : 4584) // X is already a base-class of Y + #pragma warning (disable : 4610) // struct can never be instantiated - user defined constructor required + #pragma warning (disable : 4671) // the copy constructor is inaccessible + #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site + #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter + #pragma warning (disable : 4702) // unreachable code + #pragma warning (disable : 4706) // assignment within conditional expression + #pragma warning (disable : 4710) // function not inlined + #pragma warning (disable : 4714) // "function": marked as __forceinline not inlined + #pragma warning (disable : 4711) // function selected for automatic inline expansion + #pragma warning (disable : 4786) // identifier truncated in debug info + #pragma warning (disable : 4996) // "function": was declared deprecated + +#endif //BOOST_MSVC diff --git a/boost/container/detail/config_end.hpp b/boost/container/detail/config_end.hpp new file mode 100644 index 00000000..f93c8f6f --- /dev/null +++ b/boost/container/detail/config_end.hpp @@ -0,0 +1,13 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#if defined BOOST_MSVC + #pragma warning (pop) +#endif + diff --git a/boost/container/detail/construct_in_place.hpp b/boost/container/detail/construct_in_place.hpp new file mode 100644 index 00000000..b131f06a --- /dev/null +++ b/boost/container/detail/construct_in_place.hpp @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP +#define BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace container { + +//In place construction + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source) +{ boost::container::allocator_traits::construct(a, dest, *source); } + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator) +{ + boost::container::allocator_traits::construct(a, dest); +} + +template +class default_init_construct_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator) +{ + boost::container::allocator_traits::construct(a, dest, default_init); +} + +template +class emplace_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator ei) +{ + ei.construct_in_place(a, dest); +} + +//Assignment + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source) +{ *dest = *source; } + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator) +{ + dtl::value_init val; + *dest = boost::move(val.get()); +} + +template +class default_init_construct_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator) +{ + U u; + *dest = boost::move(u); +} + +template +class emplace_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator ei) +{ + ei.assign_in_place(dest); +} + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP diff --git a/boost/container/detail/copy_move_algo.hpp b/boost/container/detail/copy_move_algo.hpp new file mode 100644 index 00000000..cc87e4ab --- /dev/null +++ b/boost/container/detail/copy_move_algo.hpp @@ -0,0 +1,1144 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP +#define BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// container +#include +// container/detail +#include +#include +#include +#include +#include + +// move +#include +#include +#include +// other +#include +// std +#include //for emmove/memcpy + +namespace boost { +namespace container { +namespace dtl { + +template +struct are_elements_contiguous +{ + static const bool value = false; +}; + +///////////////////////// +// raw pointers +///////////////////////// + +template +struct are_elements_contiguous +{ + static const bool value = true; +}; + +///////////////////////// +// move iterators +///////////////////////// + +template +struct are_elements_contiguous< ::boost::move_iterator > + : are_elements_contiguous +{}; + +} //namespace dtl { + +///////////////////////// +// predeclarations +///////////////////////// + +template +class vec_iterator; + +} //namespace container { + +namespace interprocess { + +template +class offset_ptr; + +} //namespace interprocess { + +namespace container { + +namespace dtl { + +///////////////////////// +//vector_[const_]iterator +///////////////////////// + +template +struct are_elements_contiguous > +{ + static const bool value = true; +}; + +///////////////////////// +// offset_ptr +///////////////////////// + +template +struct are_elements_contiguous< ::boost::interprocess::offset_ptr > +{ + static const bool value = true; +}; + +template +struct are_contiguous_and_same + : boost::move_detail::and_ + < are_elements_contiguous + , are_elements_contiguous + , is_same< typename remove_const< typename ::boost::container::iterator_traits::value_type >::type + , typename ::boost::container::iterator_traits::value_type + > + > +{}; + +template +struct is_memtransfer_copy_assignable + : boost::move_detail::and_ + < are_contiguous_and_same + , dtl::is_trivially_copy_assignable< typename ::boost::container::iterator_traits::value_type > + > +{}; + +template +struct is_memtransfer_copy_constructible + : boost::move_detail::and_ + < are_contiguous_and_same + , dtl::is_trivially_copy_constructible< typename ::boost::container::iterator_traits::value_type > + > +{}; + +template +struct enable_if_memtransfer_copy_constructible + : enable_if, R> +{}; + +template +struct disable_if_memtransfer_copy_constructible + : disable_if, R> +{}; + +template +struct enable_if_memtransfer_copy_assignable + : enable_if, R> +{}; + +template +struct disable_if_memtransfer_copy_assignable + : disable_if, R> +{}; + +template + // F models ForwardIterator +inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + typename boost::container::iterator_traits::difference_type n = boost::container::iterator_distance(f, l); + if(n){ + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); + boost::container::iterator_advance(r, n); + } + return r; +} + +template + // F models ForwardIterator +F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + if(n){ + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); + boost::container::iterator_advance(r, n); + } + return r; +} + +template + // F models ForwardIterator +I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + if(n){ + typedef typename boost::container::iterator_traits::value_type value_type; + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); + boost::container::iterator_advance(f, n); + } + return f; +} + +template + // F models ForwardIterator +I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + if(n){ + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); + boost::container::iterator_advance(f, n); + boost::container::iterator_advance(r, n); + } + return f; +} + +template +struct is_memzero_initializable +{ + typedef typename ::boost::container::iterator_traits::value_type value_type; + static const bool value = are_elements_contiguous::value && + ( dtl::is_integral::value || dtl::is_enum::value + #if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL) + || dtl::is_pointer::value + #endif + #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) + || dtl::is_floating_point::value + #endif + #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL) + || dtl::is_pod::value + #endif + ); +}; + +template +struct enable_if_memzero_initializable + : enable_if_c::value, R> +{}; + +template +struct disable_if_memzero_initializable + : enable_if_c::value, R> +{}; + +template +struct enable_if_trivially_destructible + : enable_if_c < dtl::is_trivially_destructible + ::value_type>::value + , R> +{}; + +template +struct disable_if_trivially_destructible + : enable_if_c ::value_type>::value + , R> +{}; + +} //namespace dtl { + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move_alloc +// +////////////////////////////////////////////////////////////////////////////// + + +//! Effects: +//! \code +//! for (; f != l; ++r, ++f) +//! allocator_traits::construct(a, &*r, boost::move(*f)); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc(Allocator &a, I f, I l, F r) +{ + F back = r; + BOOST_TRY{ + while (f != l) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, boost::move(*f)); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move_alloc_n_source +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, boost::move(*f)); +//! \endcode +//! +//! Returns: f (after incremented) +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return f; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_alloc +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; f != l; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc(Allocator &a, I f, I l, F r) +{ + F back = r; + BOOST_TRY{ + while (f != l) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_alloc_n_source +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: f (after incremented) +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return f; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_value_init_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memzero_initializable::type + uninitialized_value_init_alloc_n(Allocator &a, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r)); + ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memzero_initializable::type + uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits::size_type n, F r) +{ + typedef typename boost::container::iterator_traits::value_type value_type; + std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n); + boost::container::iterator_advance(r, n); + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_default_init_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init); + ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_fill_alloc +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; f != l; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: r +template + +inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t) +{ + F back = f; + BOOST_TRY{ + while (f != l) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(f), t); + ++f; + } + } + BOOST_CATCH(...){ + for (; back != l; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END +} + + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_fill_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, v); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n--) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), v); + ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// copy +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy(I f, I l, F r) +{ + while (f != l) { + *r = *f; + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + copy(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// copy_n +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy_n(I f, U n, F r) +{ + while (n--) { + *r = *f; + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + copy_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// copy_n_source +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy_n_source(I f, U n, F r) +{ + while (n--) { + boost::container::assign_in_place(r, f); + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + copy_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// copy_n_source_dest +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy_n_source_dest(I f, U n, F &r) +{ + while (n--) { + *r = *f; + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + copy_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source_dest(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// move +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move(I f, I l, F r) +{ + while (f != l) { + *r = ::boost::move(*f); + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + move(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// move_n +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_n(I f, U n, F r) +{ + while (n--) { + *r = ::boost::move(*f); + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + move_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + + +////////////////////////////////////////////////////////////////////////////// +// +// move_backward +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_backward(I f, I l, F r) +{ + while (f != l) { + --l; --r; + *r = ::boost::move(*l); + } + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + const typename boost::container::iterator_traits::difference_type n = boost::container::iterator_distance(f, l); + r -= n; + std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n); + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// move_n_source_dest +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_n_source_dest(I f, U n, F &r) +{ + while (n--) { + *r = ::boost::move(*f); + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + move_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source_dest(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// move_n_source +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_n_source(I f, U n, F r) +{ + while (n--) { + *r = ::boost::move(*f); + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + move_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// destroy_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + // U models unsigned integral constant +inline typename dtl::disable_if_trivially_destructible::type + destroy_alloc_n(Allocator &a, I f, U n) +{ + while(n){ + --n; + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(f)); + ++f; + } +} + +template + // U models unsigned integral constant +inline typename dtl::enable_if_trivially_destructible::type + destroy_alloc_n(Allocator &, I, U) +{} + +////////////////////////////////////////////////////////////////////////////// +// +// deep_swap_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + +inline typename dtl::disable_if_memtransfer_copy_assignable::type + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) +{ + typename allocator_traits::size_type n = 0; + for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){ + boost::adl_move_swap(*short_range_f, *large_range_f); + } + boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); +} + +static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes + +template + +inline typename dtl::enable_if_c + < dtl::is_memtransfer_copy_assignable::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false + , void>::type + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) +{ + typedef typename allocator_traits::value_type value_type; + typedef typename dtl::aligned_storage + ::value>::type storage_type; + storage_type storage; + + const std::size_t n_i_bytes = sizeof(value_type)*n_i; + void *const large_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(large_range_f)); + void *const short_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(short_range_f)); + void *const stora_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(storage.data)); + std::memcpy(stora_ptr, large_ptr, n_i_bytes); + std::memcpy(large_ptr, short_ptr, n_i_bytes); + std::memcpy(short_ptr, stora_ptr, n_i_bytes); + boost::container::iterator_advance(large_range_f, n_i); + boost::container::iterator_advance(short_range_f, n_i); + boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); +} + +template + +inline typename dtl::enable_if_c + < dtl::is_memtransfer_copy_assignable::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage) + , void>::type + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) +{ + typedef typename allocator_traits::value_type value_type; + typedef typename dtl::aligned_storage + ::value>::type storage_type; + storage_type storage; + const std::size_t sizeof_storage = sizeof(storage); + + std::size_t n_i_bytes = sizeof(value_type)*n_i; + char *large_ptr = static_cast(static_cast(boost::movelib::iterator_to_raw_pointer(large_range_f))); + char *short_ptr = static_cast(static_cast(boost::movelib::iterator_to_raw_pointer(short_range_f))); + char *stora_ptr = static_cast(static_cast(storage.data)); + + std::size_t szt_times = n_i_bytes/sizeof_storage; + const std::size_t szt_rem = n_i_bytes%sizeof_storage; + + //Loop unrolling using Duff's device, as it seems it helps on some architectures + const std::size_t Unroll = 4; + std::size_t n = (szt_times + (Unroll-1))/Unroll; + const std::size_t branch_number = (!szt_times)*Unroll + (szt_times % Unroll); + switch(branch_number){ + case 4: + break; + case 0: do{ + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + BOOST_FALLTHROUGH; + case 3: + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + BOOST_FALLTHROUGH; + case 2: + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + BOOST_FALLTHROUGH; + case 1: + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + } while(--n); + } + std::memcpy(stora_ptr, large_ptr, szt_rem); + std::memcpy(large_ptr, short_ptr, szt_rem); + std::memcpy(short_ptr, stora_ptr, szt_rem); + boost::container::iterator_advance(large_range_f, n_i); + boost::container::iterator_advance(short_range_f, n_i); + boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); +} + + +////////////////////////////////////////////////////////////////////////////// +// +// copy_assign_range_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + +void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits::size_type n_i + , O out_start, typename allocator_traits::size_type n_o ) +{ + if (n_o < n_i){ + inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw + boost::container::uninitialized_copy_alloc_n(a, inp_start, n_i - n_o, out_start);// may throw + } + else{ + out_start = boost::container::copy_n(inp_start, n_i, out_start); // may throw + boost::container::destroy_alloc_n(a, out_start, n_o - n_i); + } +} + +////////////////////////////////////////////////////////////////////////////// +// +// move_assign_range_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + +void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits::size_type n_i + , O out_start, typename allocator_traits::size_type n_o ) +{ + if (n_o < n_i){ + inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw + boost::container::uninitialized_move_alloc_n(a, inp_start, n_i - n_o, out_start); // may throw + } + else{ + out_start = boost::container::move_n(inp_start, n_i, out_start); // may throw + boost::container::destroy_alloc_n(a, out_start, n_o - n_i); + } +} + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP diff --git a/boost/container/detail/destroyers.hpp b/boost/container/detail/destroyers.hpp new file mode 100644 index 00000000..9b0be44e --- /dev/null +++ b/boost/container/detail/destroyers.hpp @@ -0,0 +1,378 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DESTROYERS_HPP +#define BOOST_CONTAINER_DESTROYERS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +//!A deleter for scoped_ptr that deallocates the memory +//!allocated for an object using a STL allocator. +template +struct scoped_deallocator +{ + typedef allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::pointer pointer; + typedef dtl::integral_constant::value> alloc_version; + + private: + void priv_deallocate(version_1) + { m_alloc.deallocate(m_ptr, 1); } + + void priv_deallocate(version_2) + { m_alloc.deallocate_one(m_ptr); } + + BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator) + + public: + + pointer m_ptr; + Allocator& m_alloc; + + scoped_deallocator(pointer p, Allocator& a) + : m_ptr(p), m_alloc(a) + {} + + ~scoped_deallocator() + { if (m_ptr)priv_deallocate(alloc_version()); } + + scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o) + : m_ptr(o.m_ptr), m_alloc(o.m_alloc) + { o.release(); } + + pointer get() const + { return m_ptr; } + + void set(const pointer &p) + { m_ptr = p; } + + void release() + { m_ptr = 0; } +}; + +template +struct null_scoped_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + null_scoped_deallocator(pointer, Allocator&, size_type) + {} + + void release() + {} + + pointer get() const + { return pointer(); } + + void set(const pointer &) + {} +}; + +//!A deleter for scoped_ptr that deallocates the memory +//!allocated for an array of objects using a STL allocator. +template +struct scoped_array_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + scoped_array_deallocator(pointer p, Allocator& a, size_type length) + : m_ptr(p), m_alloc(a), m_length(length) {} + + ~scoped_array_deallocator() + { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); } + + void release() + { m_ptr = 0; } + + private: + pointer m_ptr; + Allocator& m_alloc; + size_type m_length; +}; + +template +struct null_scoped_array_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + null_scoped_array_deallocator(pointer, Allocator&, size_type) + {} + + void release() + {} +}; + +template +struct scoped_destroy_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + typedef dtl::integral_constant::value> alloc_version; + + scoped_destroy_deallocator(pointer p, Allocator& a) + : m_ptr(p), m_alloc(a) {} + + ~scoped_destroy_deallocator() + { + if(m_ptr){ + AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr)); + priv_deallocate(m_ptr, alloc_version()); + } + } + + void release() + { m_ptr = 0; } + + private: + + void priv_deallocate(const pointer &p, version_1) + { AllocTraits::deallocate(m_alloc, p, 1); } + + void priv_deallocate(const pointer &p, version_2) + { m_alloc.deallocate_one(p); } + + pointer m_ptr; + Allocator& m_alloc; +}; + + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct scoped_destructor_n +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::value_type value_type; + typedef typename AllocTraits::size_type size_type; + + scoped_destructor_n(pointer p, Allocator& a, size_type n) + : m_p(p), m_a(a), m_n(n) + {} + + void release() + { m_p = 0; } + + void increment_size(size_type inc) + { m_n += inc; } + + void increment_size_backwards(size_type inc) + { m_n += inc; m_p -= inc; } + + void shrink_forward(size_type inc) + { m_n -= inc; m_p += inc; } + + ~scoped_destructor_n() + { + if(!m_p) return; + value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); + while(m_n--){ + AllocTraits::destroy(m_a, raw_ptr++); + } + } + + private: + pointer m_p; + Allocator & m_a; + size_type m_n; +}; + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct null_scoped_destructor_n +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + null_scoped_destructor_n(pointer, Allocator&, size_type) + {} + + void increment_size(size_type) + {} + + void increment_size_backwards(size_type) + {} + + void shrink_forward(size_type) + {} + + void release() + {} +}; + +template +class scoped_destructor +{ + typedef boost::container::allocator_traits AllocTraits; + public: + typedef typename Allocator::value_type value_type; + scoped_destructor(Allocator &a, value_type *pv) + : pv_(pv), a_(a) + {} + + ~scoped_destructor() + { + if(pv_){ + AllocTraits::destroy(a_, pv_); + } + } + + void release() + { pv_ = 0; } + + + void set(value_type *ptr) { pv_ = ptr; } + + value_type *get() const { return pv_; } + + private: + value_type *pv_; + Allocator &a_; +}; + + +template +class value_destructor +{ + typedef boost::container::allocator_traits AllocTraits; + public: + typedef Value value_type; + value_destructor(Allocator &a, value_type &rv) + : rv_(rv), a_(a) + {} + + ~value_destructor() + { + AllocTraits::destroy(a_, &rv_); + } + + private: + value_type &rv_; + Allocator &a_; +}; + +template +class allocator_destroyer +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::value_type value_type; + typedef typename AllocTraits::pointer pointer; + typedef dtl::integral_constant::value> alloc_version; + + private: + Allocator & a_; + + private: + void priv_deallocate(const pointer &p, version_1) + { AllocTraits::deallocate(a_,p, 1); } + + void priv_deallocate(const pointer &p, version_2) + { a_.deallocate_one(p); } + + public: + explicit allocator_destroyer(Allocator &a) + : a_(a) + {} + + void operator()(const pointer &p) + { + AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p)); + this->priv_deallocate(p, alloc_version()); + } +}; + +template +class allocator_destroyer_and_chain_builder +{ + typedef allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::value_type value_type; + typedef typename Allocator::multiallocation_chain multiallocation_chain; + + Allocator & a_; + multiallocation_chain &c_; + + public: + allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c) + : a_(a), c_(c) + {} + + void operator()(const typename Allocator::pointer &p) + { + allocator_traits::destroy(a_, boost::movelib::to_raw_pointer(p)); + c_.push_back(p); + } +}; + +template +class allocator_multialloc_chain_node_deallocator +{ + typedef allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::value_type value_type; + typedef typename Allocator::multiallocation_chain multiallocation_chain; + typedef allocator_destroyer_and_chain_builder chain_builder; + + Allocator & a_; + multiallocation_chain c_; + + public: + allocator_multialloc_chain_node_deallocator(Allocator &a) + : a_(a), c_() + {} + + chain_builder get_chain_builder() + { return chain_builder(a_, c_); } + + ~allocator_multialloc_chain_node_deallocator() + { + a_.deallocate_individual(c_); + } +}; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP diff --git a/boost/container/detail/dispatch_uses_allocator.hpp b/boost/container/detail/dispatch_uses_allocator.hpp new file mode 100644 index 00000000..0b8cfea6 --- /dev/null +++ b/boost/container/detail/dispatch_uses_allocator.hpp @@ -0,0 +1,461 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP +#define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP + +#if defined (_MSC_VER) +# pragma once +#endif + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include + +#include + +namespace boost { namespace container { + +namespace dtl { + + +// Check if we can detect is_convertible using advanced SFINAE expressions +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + //! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list + //! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html + //! Thanks Mathias! + + //With variadic templates, we need a single class to implement the trait + template + struct is_constructible + { + typedef char yes_type; + struct no_type + { char padding[2]; }; + + template + struct dummy; + + template + static decltype(X(boost::move_detail::declval()...), true_type()) test(int); + + template + static no_type test(...); + + static const bool value = sizeof(test(0)) == sizeof(yes_type); + }; + + template + struct is_constructible_with_allocator_prefix + : is_constructible + {}; + +#else // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + //Without advanced SFINAE expressions, we can't use is_constructible + //so backup to constructible_with_allocator_xxx + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template + struct is_constructible_with_allocator_prefix + : constructible_with_allocator_prefix + {}; + + template + struct is_constructible_with_allocator_suffix + : constructible_with_allocator_suffix + {}; + + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template + struct is_constructible_with_allocator_prefix + : constructible_with_allocator_prefix + {}; + + template + struct is_constructible_with_allocator_suffix + : constructible_with_allocator_suffix + {}; + + #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#endif // #if !defined(BOOST_NO_SFINAE_EXPR) + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template < typename ConstructAlloc + , typename ArgAlloc + , typename T + , class ...Args + > +inline typename dtl::enable_if_and + < void + , dtl::is_not_pair + , dtl::not_< uses_allocator > + >::type dispatch_uses_allocator + ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args) +{ + (void)arg_alloc; + allocator_traits::construct(construct_alloc, p, ::boost::forward(args)...); +} + +// allocator_arg_t +template < typename ConstructAlloc + , typename ArgAlloc + , typename T + , class ...Args + > +inline typename dtl::enable_if_and + < void + , dtl::is_not_pair + , uses_allocator + , is_constructible_with_allocator_prefix + >::type dispatch_uses_allocator + ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args) ...args) +{ + allocator_traits::construct + ( construct_alloc, p, allocator_arg + , ::boost::forward(arg_alloc), ::boost::forward(args)...); +} + +// allocator suffix +template < typename ConstructAlloc + , typename ArgAlloc + , typename T + , class ...Args + > +inline typename dtl::enable_if_and + < void + , dtl::is_not_pair + , uses_allocator + , dtl::not_ > + >::type dispatch_uses_allocator + ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args) +{ + allocator_traits::construct + (construct_alloc, p, ::boost::forward(args)..., ::boost::forward(arg_alloc)); +} + +#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ + template \ + inline typename dtl::enable_if_and\ + < void\ + , dtl::is_not_pair\ + , dtl::not_ >\ + >::type\ + dispatch_uses_allocator\ + (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + (void)arg_alloc;\ + allocator_traits::construct(construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE + +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ + template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ + inline typename dtl::enable_if_and\ + < void\ + , dtl::is_not_pair\ + , uses_allocator\ + , is_constructible_with_allocator_prefix\ + >::type\ + dispatch_uses_allocator\ + (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + allocator_traits::construct\ + (construct_alloc, p, allocator_arg, ::boost::forward(arg_alloc) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE + +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \ + template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ + inline typename dtl::enable_if_and\ + < void\ + , dtl::is_not_pair\ + , uses_allocator\ + , dtl::not_ >\ + >::type\ + dispatch_uses_allocator\ + (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + allocator_traits::construct\ + (construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, ::boost::forward(arg_alloc));\ + }\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE + +#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template < typename ConstructAlloc + , typename ArgAlloc + , typename Pair + > inline +BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if >::type) + dispatch_uses_allocator + ( ConstructAlloc & construct_alloc + , BOOST_FWD_REF(ArgAlloc) arg_alloc + , Pair* p) +{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first)); + BOOST_TRY{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second)); + } + BOOST_CATCH(...) { + allocator_traits::destroy(construct_alloc, dtl::addressof(p->first)); + BOOST_RETHROW + } + BOOST_CATCH_END +} + + +template < typename ConstructAlloc + , typename ArgAlloc + , class Pair, class U, class V> +BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if >::type) + dispatch_uses_allocator + ( ConstructAlloc & construct_alloc + , BOOST_FWD_REF(ArgAlloc) arg_alloc + , Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y) +{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward(x)); + BOOST_TRY{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward(y)); + } + BOOST_CATCH(...){ + allocator_traits::destroy(construct_alloc, dtl::addressof(p->first)); + BOOST_RETHROW + } + BOOST_CATCH_END +} + +template < typename ConstructAlloc + , typename ArgAlloc + , class Pair, class Pair2> +BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if< dtl::is_pair >::type) + dispatch_uses_allocator + (ConstructAlloc & construct_alloc + , BOOST_FWD_REF(ArgAlloc) arg_alloc + , Pair* p, Pair2& x) +{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, x.first, x.second); } + +template < typename ConstructAlloc + , typename ArgAlloc + , class Pair, class Pair2> +typename dtl::enable_if_and + < void + , dtl::is_pair + , dtl::not_ > >::type //This is needed for MSVC10 and ambiguous overloads + dispatch_uses_allocator + (ConstructAlloc & construct_alloc + , BOOST_FWD_REF(ArgAlloc) arg_alloc + , Pair* p, BOOST_RV_REF_BEG Pair2 BOOST_RV_REF_END x) +{ (dispatch_uses_allocator)(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second)); } + + +//piecewise construction from boost::tuple +#define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\ +template< typename ConstructAlloc, typename ArgAlloc, class Pair \ + , template class BoostTuple \ + BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ +typename dtl::enable_if< dtl::is_pair >::type\ + dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ + , BoostTuple p\ + , BoostTuple q)\ +{\ + (void)p; (void)q;\ + (dispatch_uses_allocator)\ + (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_TMPL_GET##N);\ + BOOST_TRY{\ + (dispatch_uses_allocator)\ + (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_TMPL_GETQ##M);\ + }\ + BOOST_CATCH(...) {\ + allocator_traits::destroy(construct_alloc, dtl::addressof(pair->first));\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ +}\ +// +BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE) +#undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE + +//piecewise construction from Std Tuple +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template< typename ConstructAlloc, typename ArgAlloc, class Pair + , template class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2> + void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair + , Tuple& t1, Tuple& t2, index_tuple, index_tuple) + { + (void)t1; (void)t2; + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->first), ::boost::forward(get(t1))...); + BOOST_TRY{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(pair->second), ::boost::forward(get(t2))...); + } + BOOST_CATCH(...){ + allocator_traits::destroy(construct_alloc, dtl::addressof(pair->first)); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + template< typename ConstructAlloc, typename ArgAlloc, class Pair + , template class Tuple, class... Args1, class... Args2> + typename dtl::enable_if< dtl::is_pair >::type + dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t + , Tuple t1, Tuple t2) + { + (dispatch_uses_allocator_index)( construct_alloc, arg_alloc, pair, t1, t2 + , typename build_number_seq::type() + , typename build_number_seq::type()); + } + +#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520) + + //MSVC 2010 tuple implementation + #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\ + template< typename ConstructAlloc, typename ArgAlloc, class Pair\ + , template class StdTuple\ + BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ + typename dtl::enable_if< dtl::is_pair >::type\ + dispatch_uses_allocator(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ + , StdTuple p\ + , StdTuple q)\ + {\ + (void)p; (void)q;\ + (dispatch_uses_allocator)\ + (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\ + BOOST_TRY{\ + (dispatch_uses_allocator)\ + (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\ + }\ + BOOST_CATCH(...) {\ + allocator_traits::destroy(construct_alloc, dtl::addressof(pair->first));\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ + }\ + // + BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE) + #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE + +#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540) + #if _VARIADIC_MAX >= 9 + #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9 + #else + #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1) + #endif + + //MSVC 2012 tuple implementation + #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\ + template< typename ConstructAlloc, typename ArgAlloc, class Pair\ + , template class StdTuple \ + BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ + typename dtl::enable_if< dtl::is_pair >::type\ + dispatch_uses_allocator\ + ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ + , StdTuple p\ + , StdTuple q)\ + {\ + (void)p; (void)q;\ + (dispatch_uses_allocator)\ + (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\ + BOOST_TRY{\ + (dispatch_uses_allocator)\ + (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\ + }\ + BOOST_CATCH(...) {\ + allocator_traits::destroy(construct_alloc, dtl::addressof(pair->first));\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ + }\ + // + BOOST_MOVE_ITER2D_0TOMAX(BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE) + #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE + #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT + +#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template < typename ConstructAlloc + , typename ArgAlloc + , class Pair, class KeyType, class ... Args> +typename dtl::enable_if< dtl::is_pair, void >::type + dispatch_uses_allocator + (ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args) +{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward(k)); + BOOST_TRY{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward(args)...); + } + BOOST_CATCH(...) { + allocator_traits::destroy(construct_alloc, dtl::addressof(p->first)); + BOOST_RETHROW + } + BOOST_CATCH_END +} + +#else + +#define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE(N) \ + template \ + inline typename dtl::enable_if\ + < dtl::is_pair, void >::type\ + dispatch_uses_allocator\ + (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, \ + BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward(k));\ + BOOST_TRY{\ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ + BOOST_CATCH(...) {\ + allocator_traits::destroy(construct_alloc, dtl::addressof(p->first));\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ + }\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE) +#undef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE + +#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +} //namespace dtl + +}} // namespace boost { namespace container { + +#include + +#endif // BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP diff --git a/boost/container/detail/iterator.hpp b/boost/container/detail/iterator.hpp new file mode 100644 index 00000000..2ceaf260 --- /dev/null +++ b/boost/container/detail/iterator.hpp @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_HPP +#define BOOST_CONTAINER_DETAIL_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace container { + +using ::boost::intrusive::iterator_traits; +using ::boost::intrusive::iterator_distance; +using ::boost::intrusive::iterator_advance; +using ::boost::intrusive::iterator; +using ::boost::intrusive::iterator_enable_if_tag; +using ::boost::intrusive::iterator_disable_if_tag; +using ::boost::intrusive::iterator_arrow_result; + +template +class back_emplacer +{ + private: + Container& container; + + public: + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + back_emplacer(Container& x) + : container(x) + {} + + template + back_emplacer& operator=(BOOST_FWD_REF(U) value) + { + container.emplace_back(boost::forward(value)); + return *this; + } + back_emplacer& operator*() { return *this; } + back_emplacer& operator++() { return *this; } + back_emplacer& operator++(int){ return *this; } +}; + + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP diff --git a/boost/container/detail/iterators.hpp b/boost/container/detail/iterators.hpp new file mode 100644 index 00000000..7ccdac91 --- /dev/null +++ b/boost/container/detail/iterators.hpp @@ -0,0 +1,875 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP +#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#else +#include +#endif +#include + +namespace boost { +namespace container { + +template +class constant_iterator + : public ::boost::container::iterator + +{ + typedef constant_iterator this_type; + + public: + explicit constant_iterator(const T &ref, Difference range_size) + : m_ptr(&ref), m_num(range_size){} + + //Constructors + constant_iterator() + : m_ptr(0), m_num(0){} + + constant_iterator& operator++() + { increment(); return *this; } + + constant_iterator operator++(int) + { + constant_iterator result (*this); + increment(); + return result; + } + + constant_iterator& operator--() + { decrement(); return *this; } + + constant_iterator operator--(int) + { + constant_iterator result (*this); + decrement(); + return result; + } + + friend bool operator== (const constant_iterator& i, const constant_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) + { return !(i == i2); } + + friend bool operator< (const constant_iterator& i, const constant_iterator& i2) + { return i.less(i2); } + + friend bool operator> (const constant_iterator& i, const constant_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) + { return !(i < i2); } + + friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + constant_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + constant_iterator operator+(Difference off) const + { + constant_iterator other(*this); + other.advance(off); + return other; + } + + friend constant_iterator operator+(Difference off, const constant_iterator& right) + { return right + off; } + + constant_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + constant_iterator operator-(Difference off) const + { return *this + (-off); } + + const T& operator*() const + { return dereference(); } + + const T& operator[] (Difference ) const + { return dereference(); } + + const T* operator->() const + { return &(dereference()); } + + private: + const T * m_ptr; + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + const T & dereference() const + { return *m_ptr; } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class value_init_construct_iterator + : public ::boost::container::iterator + +{ + typedef value_init_construct_iterator this_type; + + public: + explicit value_init_construct_iterator(Difference range_size) + : m_num(range_size){} + + //Constructors + value_init_construct_iterator() + : m_num(0){} + + value_init_construct_iterator& operator++() + { increment(); return *this; } + + value_init_construct_iterator operator++(int) + { + value_init_construct_iterator result (*this); + increment(); + return result; + } + + value_init_construct_iterator& operator--() + { decrement(); return *this; } + + value_init_construct_iterator operator--(int) + { + value_init_construct_iterator result (*this); + decrement(); + return result; + } + + friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return !(i == i2); } + + friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i.less(i2); } + + friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return !(i < i2); } + + friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + value_init_construct_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + value_init_construct_iterator operator+(Difference off) const + { + value_init_construct_iterator other(*this); + other.advance(off); + return other; + } + + friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right) + { return right + off; } + + value_init_construct_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + value_init_construct_iterator operator-(Difference off) const + { return *this + (-off); } + + //This pseudo-iterator's dereference operations have no sense since value is not + //constructed until ::boost::container::construct_in_place is called. + //So comment them to catch bad uses + //const T& operator*() const; + //const T& operator[](difference_type) const; + //const T* operator->() const; + + private: + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + const T & dereference() const + { + static T dummy; + return dummy; + } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class default_init_construct_iterator + : public ::boost::container::iterator + +{ + typedef default_init_construct_iterator this_type; + + public: + explicit default_init_construct_iterator(Difference range_size) + : m_num(range_size){} + + //Constructors + default_init_construct_iterator() + : m_num(0){} + + default_init_construct_iterator& operator++() + { increment(); return *this; } + + default_init_construct_iterator operator++(int) + { + default_init_construct_iterator result (*this); + increment(); + return result; + } + + default_init_construct_iterator& operator--() + { decrement(); return *this; } + + default_init_construct_iterator operator--(int) + { + default_init_construct_iterator result (*this); + decrement(); + return result; + } + + friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i == i2); } + + friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i.less(i2); } + + friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i < i2); } + + friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + default_init_construct_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + default_init_construct_iterator operator+(Difference off) const + { + default_init_construct_iterator other(*this); + other.advance(off); + return other; + } + + friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right) + { return right + off; } + + default_init_construct_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + default_init_construct_iterator operator-(Difference off) const + { return *this + (-off); } + + //This pseudo-iterator's dereference operations have no sense since value is not + //constructed until ::boost::container::construct_in_place is called. + //So comment them to catch bad uses + //const T& operator*() const; + //const T& operator[](difference_type) const; + //const T* operator->() const; + + private: + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + const T & dereference() const + { + static T dummy; + return dummy; + } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + + +template +class repeat_iterator + : public ::boost::container::iterator + +{ + typedef repeat_iterator this_type; + public: + explicit repeat_iterator(T &ref, Difference range_size) + : m_ptr(&ref), m_num(range_size){} + + //Constructors + repeat_iterator() + : m_ptr(0), m_num(0){} + + this_type& operator++() + { increment(); return *this; } + + this_type operator++(int) + { + this_type result (*this); + increment(); + return result; + } + + this_type& operator--() + { increment(); return *this; } + + this_type operator--(int) + { + this_type result (*this); + increment(); + return result; + } + + friend bool operator== (const this_type& i, const this_type& i2) + { return i.equal(i2); } + + friend bool operator!= (const this_type& i, const this_type& i2) + { return !(i == i2); } + + friend bool operator< (const this_type& i, const this_type& i2) + { return i.less(i2); } + + friend bool operator> (const this_type& i, const this_type& i2) + { return i2 < i; } + + friend bool operator<= (const this_type& i, const this_type& i2) + { return !(i > i2); } + + friend bool operator>= (const this_type& i, const this_type& i2) + { return !(i < i2); } + + friend Difference operator- (const this_type& i, const this_type& i2) + { return i2.distance_to(i); } + + //Arithmetic + this_type& operator+=(Difference off) + { this->advance(off); return *this; } + + this_type operator+(Difference off) const + { + this_type other(*this); + other.advance(off); + return other; + } + + friend this_type operator+(Difference off, const this_type& right) + { return right + off; } + + this_type& operator-=(Difference off) + { this->advance(-off); return *this; } + + this_type operator-(Difference off) const + { return *this + (-off); } + + T& operator*() const + { return dereference(); } + + T& operator[] (Difference ) const + { return dereference(); } + + T *operator->() const + { return &(dereference()); } + + private: + T * m_ptr; + Difference m_num; + + void increment() + { --m_num; } + + void decrement() + { ++m_num; } + + bool equal(const this_type &other) const + { return m_num == other.m_num; } + + bool less(const this_type &other) const + { return other.m_num < m_num; } + + T & dereference() const + { return *m_ptr; } + + void advance(Difference n) + { m_num -= n; } + + Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class emplace_iterator + : public ::boost::container::iterator + +{ + typedef emplace_iterator this_type; + + public: + typedef Difference difference_type; + BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e) + : m_num(1), m_pe(&e){} + + BOOST_CONTAINER_FORCEINLINE emplace_iterator() + : m_num(0), m_pe(0){} + + BOOST_CONTAINER_FORCEINLINE this_type& operator++() + { increment(); return *this; } + + this_type operator++(int) + { + this_type result (*this); + increment(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE this_type& operator--() + { decrement(); return *this; } + + this_type operator--(int) + { + this_type result (*this); + decrement(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2) + { return i.equal(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2) + { return !(i == i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2) + { return i.less(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2) + { return i2 < i; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2) + { return !(i > i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2) + { return !(i < i2); } + + BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2) + { return i2.distance_to(i); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off) + { this->advance(off); return *this; } + + this_type operator+(difference_type off) const + { + this_type other(*this); + other.advance(off); + return other; + } + + BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right) + { return right + off; } + + BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off) + { this->advance(-off); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const + { return *this + (-off); } + + private: + //This pseudo-iterator's dereference operations have no sense since value is not + //constructed until ::boost::container::construct_in_place is called. + //So comment them to catch bad uses + const T& operator*() const; + const T& operator[](difference_type) const; + const T* operator->() const; + + public: + template + void construct_in_place(Allocator &a, T* ptr) + { (*m_pe)(a, ptr); } + + template + void assign_in_place(DestIt dest) + { (*m_pe)(dest); } + + private: + difference_type m_num; + EmplaceFunctor * m_pe; + + BOOST_CONTAINER_FORCEINLINE void increment() + { --m_num; } + + BOOST_CONTAINER_FORCEINLINE void decrement() + { ++m_num; } + + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const + { return m_num == other.m_num; } + + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const + { return other.m_num < m_num; } + + BOOST_CONTAINER_FORCEINLINE const T & dereference() const + { + static T dummy; + return dummy; + } + + BOOST_CONTAINER_FORCEINLINE void advance(difference_type n) + { m_num -= n; } + + BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const + { return difference_type(m_num - other.m_num); } +}; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template +struct emplace_functor +{ + typedef typename dtl::build_number_seq::type index_tuple_t; + + emplace_functor(BOOST_FWD_REF(Args)... args) + : args_(args...) + {} + + template + BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr) + { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); } + + template + BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest) + { emplace_functor::inplace_impl(dest, index_tuple_t()); } + + private: + template + BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const dtl::index_tuple&) + { + allocator_traits::construct + (a, ptr, ::boost::forward(dtl::get(args_))...); + } + + template + BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const dtl::index_tuple&) + { + typedef typename boost::container::iterator_traits::value_type value_type; + value_type && tmp= value_type(::boost::forward(dtl::get(args_))...); + *dest = ::boost::move(tmp); + } + + dtl::tuple args_; +}; + +template +struct emplace_functor_type +{ + typedef emplace_functor type; +}; + +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +//Partial specializations cannot match argument list for primary template, so add an extra argument +template +struct emplace_functor_type; + +#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \ +BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ +struct emplace_functor##N\ +{\ + explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ + BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ + \ + template\ + void operator()(Allocator &a, T *ptr)\ + { allocator_traits::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\ + \ + template\ + void operator()(DestIt dest)\ + {\ + typedef typename boost::container::iterator_traits::value_type value_type;\ + BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), dtl::value_init tmp) ;\ + *dest = ::boost::move(const_cast(BOOST_MOVE_IF(N, tmp, tmp.get())));\ + }\ + \ + BOOST_MOVE_MREF##N\ +};\ +\ +template \ +struct emplace_functor_type\ +{\ + typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\ +};\ +// + +BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE) + +#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE + +#endif + +namespace dtl { + +template +struct has_iterator_category +{ + struct two { char _[2]; }; + + template + static char test(int, typename X::iterator_category*); + + template + static two test(int, ...); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + + +template::value > +struct is_input_iterator +{ + static const bool value = is_same::value; +}; + +template +struct is_input_iterator +{ + static const bool value = false; +}; + +template +struct is_not_input_iterator +{ + static const bool value = !is_input_iterator::value; +}; + +template::value > +struct is_forward_iterator +{ + static const bool value = is_same::value; +}; + +template +struct is_forward_iterator +{ + static const bool value = false; +}; + +template::value > +struct is_bidirectional_iterator +{ + static const bool value = is_same::value; +}; + +template +struct is_bidirectional_iterator +{ + static const bool value = false; +}; + +template +struct iiterator_node_value_type { + typedef typename IINodeType::value_type type; +}; + +template +struct iiterator_types +{ + typedef typename IIterator::value_type it_value_type; + typedef typename iiterator_node_value_type::type value_type; + typedef typename boost::container::iterator_traits::pointer it_pointer; + typedef typename boost::container::iterator_traits::difference_type difference_type; + typedef typename ::boost::intrusive::pointer_traits:: + template rebind_pointer::type pointer; + typedef typename ::boost::intrusive::pointer_traits:: + template rebind_pointer::type const_pointer; + typedef typename ::boost::intrusive:: + pointer_traits::reference reference; + typedef typename ::boost::intrusive:: + pointer_traits::reference const_reference; + typedef typename IIterator::iterator_category iterator_category; +}; + +template +struct iterator_types +{ + typedef typename ::boost::container::iterator + < typename iiterator_types::iterator_category + , typename iiterator_types::value_type + , typename iiterator_types::difference_type + , typename iiterator_types::const_pointer + , typename iiterator_types::const_reference> type; +}; + +template +struct iterator_types +{ + typedef typename ::boost::container::iterator + < typename iiterator_types::iterator_category + , typename iiterator_types::value_type + , typename iiterator_types::difference_type + , typename iiterator_types::pointer + , typename iiterator_types::reference> type; +}; + +template +class iterator_from_iiterator +{ + typedef typename iterator_types::type types_t; + + public: + typedef typename types_t::pointer pointer; + typedef typename types_t::reference reference; + typedef typename types_t::difference_type difference_type; + typedef typename types_t::iterator_category iterator_category; + typedef typename types_t::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator() + : m_iit() + {} + + BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW + : m_iit(iit) + {} + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(iterator_from_iiterator const& other) BOOST_NOEXCEPT_OR_NOTHROW + : m_iit(other.get()) + {} + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW + { ++this->m_iit; return *this; } + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW + { + iterator_from_iiterator result (*this); + ++this->m_iit; + return result; + } + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW + { + //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist + BOOST_STATIC_ASSERT((is_bidirectional_iterator::value)); + --this->m_iit; return *this; + } + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW + { + iterator_from_iiterator result (*this); + --this->m_iit; + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_iit == r.m_iit; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return !(l == r); } + + BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_iit->get_data(); } + + BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW + { return ::boost::intrusive::pointer_traits::pointer_to(this->operator*()); } + + BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_iit; } + + private: + IIterator m_iit; +}; + +} //namespace dtl { + +using ::boost::intrusive::reverse_iterator; + +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP diff --git a/boost/container/detail/min_max.hpp b/boost/container/detail/min_max.hpp new file mode 100644 index 00000000..35cf0661 --- /dev/null +++ b/boost/container/detail/min_max.hpp @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP +#define BOOST_CONTAINER_DETAIL_MIN_MAX_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace container { +namespace dtl { + +template +const T &max_value(const T &a, const T &b) +{ return a > b ? a : b; } + +template +const T &min_value(const T &a, const T &b) +{ return a < b ? a : b; } + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP diff --git a/boost/container/detail/mpl.hpp b/boost/container/detail/mpl.hpp new file mode 100644 index 00000000..4bb3cc7d --- /dev/null +++ b/boost/container/detail/mpl.hpp @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP +#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +#include + +namespace boost { +namespace container { +namespace dtl { + +using boost::move_detail::integral_constant; +using boost::move_detail::true_type; +using boost::move_detail::false_type; +using boost::move_detail::enable_if_c; +using boost::move_detail::enable_if; +using boost::move_detail::enable_if_convertible; +using boost::move_detail::disable_if_c; +using boost::move_detail::disable_if; +using boost::move_detail::disable_if_convertible; +using boost::move_detail::is_convertible; +using boost::move_detail::if_c; +using boost::move_detail::if_; +using boost::move_detail::identity; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::yes_type; +using boost::move_detail::no_type; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::unvoid_ref; +using boost::move_detail::and_; +using boost::move_detail::or_; +using boost::move_detail::not_; +using boost::move_detail::enable_if_and; +using boost::move_detail::disable_if_and; +using boost::move_detail::enable_if_or; +using boost::move_detail::disable_if_or; + +template +struct select1st +{ + typedef FirstType type; + + template + const type& operator()(const T& x) const + { return x.first; } + + template + type& operator()(T& x) + { return const_cast(x.first); } +}; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP + diff --git a/boost/container/detail/next_capacity.hpp b/boost/container/detail/next_capacity.hpp new file mode 100644 index 00000000..7e6554de --- /dev/null +++ b/boost/container/detail/next_capacity.hpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP +#define BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// container +#include +// container/detail +#include + +#include + +namespace boost { +namespace container { +namespace dtl { + +template +struct grow_factor_ratio +{ + BOOST_STATIC_ASSERT(Numerator > Denominator); + BOOST_STATIC_ASSERT(Numerator < 100); + BOOST_STATIC_ASSERT(Denominator < 100); + BOOST_STATIC_ASSERT(Denominator == 1 || (0 != Numerator % Denominator)); + + template + SizeType operator()(const SizeType cur_cap, const SizeType add_min_cap, const SizeType max_cap) const + { + const SizeType overflow_limit = ((SizeType)-1) / Numerator; + + SizeType new_cap = 0; + + if(cur_cap <= overflow_limit){ + new_cap = cur_cap * Numerator / Denominator; + } + else if(Denominator == 1 || (SizeType(new_cap = cur_cap) / Denominator) > overflow_limit){ + new_cap = (SizeType)-1; + } + else{ + new_cap *= Numerator; + } + return max_value(SizeType(Minimum), max_value(cur_cap+add_min_cap, min_value(max_cap, new_cap))); + } +}; + +} //namespace dtl { + +struct growth_factor_50 + : dtl::grow_factor_ratio<0, 3, 2> +{}; + +struct growth_factor_60 + : dtl::grow_factor_ratio<0, 8, 5> +{}; + +struct growth_factor_100 + : dtl::grow_factor_ratio<0, 2, 1> +{}; + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP diff --git a/boost/container/detail/pair.hpp b/boost/container/detail/pair.hpp new file mode 100644 index 00000000..6b00db14 --- /dev/null +++ b/boost/container/detail/pair.hpp @@ -0,0 +1,559 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP +#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# include +#endif +#include //swap + +#include //pair +#include +#include + +namespace boost { +namespace tuples { + +struct null_type; + +template < + class T0, class T1, class T2, + class T3, class T4, class T5, + class T6, class T7, class T8, + class T9> +class tuple; + +} //namespace tuples { +} //namespace boost { + +namespace boost { +namespace container { +namespace pair_impl { + +template +struct is_boost_tuple +{ + static const bool value = false; +}; + +template < + class T0, class T1, class T2, + class T3, class T4, class T5, + class T6, class T7, class T8, + class T9> +struct is_boost_tuple< boost::tuples::tuple > +{ + static const bool value = true; +}; + +template +struct disable_if_boost_tuple + : boost::container::dtl::disable_if< is_boost_tuple > +{}; + +template +struct is_tuple_null +{ + static const bool value = false; +}; + +template<> +struct is_tuple_null +{ + static const bool value = true; +}; + +}}} + +#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520) +//MSVC 2010 tuple marker +namespace std { namespace tr1 { struct _Nil; }} +#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540) +//MSVC 2012 tuple marker +namespace std { struct _Nil; } +#endif + + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + template + struct std_piecewise_construct_holder + { + static ::std::piecewise_construct_t *dummy; + }; + + template + ::std::piecewise_construct_t *std_piecewise_construct_holder::dummy = + reinterpret_cast< ::std::piecewise_construct_t *>(0x01234); //Avoid sanitizer errors on references to null pointers + +typedef const std::piecewise_construct_t & piecewise_construct_t; + +struct try_emplace_t{}; + +#else + +//! The piecewise_construct_t struct is an empty structure type used as a unique type to +//! disambiguate used to disambiguate between different functions that take two tuple arguments. +typedef unspecified piecewise_construct_t; + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! A instance of type +//! piecewise_construct_t +static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy); + +///@cond + +namespace dtl { + +struct piecewise_construct_use +{ + //Avoid warnings of unused "piecewise_construct" + piecewise_construct_use() + { (void)&::boost::container::piecewise_construct; } +}; + +template +struct pair; + +template +struct is_pair +{ + static const bool value = false; +}; + +template +struct is_pair< pair > +{ + static const bool value = true; +}; + +template +struct is_pair< std::pair > +{ + static const bool value = true; +}; + +template +struct is_not_pair +{ + static const bool value = !is_pair::value; +}; + +template +struct is_std_pair +{ + static const bool value = false; +}; + +template +struct is_std_pair< std::pair > +{ + static const bool value = true; +}; + +struct pair_nat; + +template +void get(T); //to enable ADL + +///@endcond + +template +struct pair +{ + private: + BOOST_COPYABLE_AND_MOVABLE(pair) + + public: + typedef T1 first_type; + typedef T2 second_type; + + T1 first; + T2 second; + + //Default constructor + pair() + : first(), second() + {} + + //pair copy assignment + pair(const pair& x) + : first(x.first), second(x.second) + {} + + //pair move constructor + pair(BOOST_RV_REF(pair) p) + : first(::boost::move(p.first)), second(::boost::move(p.second)) + {} + + template + pair(const pair &p) + : first(p.first), second(p.second) + {} + + template + pair(BOOST_RV_REF_BEG pair BOOST_RV_REF_END p) + : first(::boost::move(p.first)), second(::boost::move(p.second)) + {} + + //pair from two values + pair(const T1 &t1, const T2 &t2) + : first(t1) + , second(t2) + {} + + template + pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v) + : first(::boost::forward(u)) + , second(::boost::forward(v)) + {} + + //And now compatibility with std::pair + pair(const std::pair& x) + : first(x.first), second(x.second) + {} + + template + pair(const std::pair& p) + : first(p.first), second(p.second) + {} + + pair(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) + : first(::boost::move(p.first)), second(::boost::move(p.second)) + {} + + template + pair(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) + : first(::boost::move(p.first)), second(::boost::move(p.second)) + {} + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template< class KeyType, class ...Args> + pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args) + : first(boost::forward(k)), second(::boost::forward(args)...)\ + {} + #else + + //piecewise construction from boost::tuple + #define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(N)\ + template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ + pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\ + : first(boost::forward(k)), second(BOOST_MOVE_FWD##N)\ + {}\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE) + #undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE + + #endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES + + //piecewise construction from boost::tuple + #define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\ + template< template class BoostTuple \ + BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ + pair( piecewise_construct_t\ + , BoostTuple p\ + , BoostTuple q\ + , typename dtl::enable_if_c\ + < pair_impl::is_boost_tuple< BoostTuple >::value &&\ + !(pair_impl::is_tuple_null::value || pair_impl::is_tuple_null::value) \ + >::type* = 0\ + )\ + : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\ + { (void)p; (void)q; }\ + // + BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE) + #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE + + //piecewise construction from variadic tuple (with delegating constructors) + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + # if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS) + private: + template class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2> + pair(Tuple& t1, Tuple& t2, index_tuple, index_tuple) + : first (::boost::forward(get(t1))...) + , second(::boost::forward(get(t2))...) + { (void) t1; (void)t2; } + + public: + template< template class Tuple, class... Args1, class... Args2 + , class = typename pair_impl::disable_if_boost_tuple< Tuple >::type> + pair(piecewise_construct_t, Tuple t1, Tuple t2) + : pair(t1, t2, typename build_number_seq::type(), typename build_number_seq::type()) + {} + # else + //piecewise construction from variadic tuple (suboptimal, without delegating constructors) + private: + template class Tuple, typename... Args> + static T build_from_args(Tuple&& t) + { return do_build_from_args(::boost::move(t), typename build_number_seq::type()); } + + template class Tuple, typename... Args, std::size_t... Indexes> + static T do_build_from_args(Tuple && t, const index_tuple&) + { (void)t; return T(::boost::forward(get(t))...); } + + public: + template< template class Tuple, class... Args1, class... Args2 + , class = typename pair_impl::disable_if_boost_tuple< Tuple >::type> + pair(piecewise_construct_t, Tuple t1, Tuple t2) + : first (build_from_args (::boost::move(t1))) + , second (build_from_args(::boost::move(t2))) + {} + # endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES + #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520) + //MSVC 2010 tuple implementation + #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\ + template< template class StdTuple \ + BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ + pair( piecewise_construct_t\ + , StdTuple p\ + , StdTuple q)\ + : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ + { (void)p; (void)q; }\ + // + BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE) + #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE + #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540) + #if _VARIADIC_MAX >= 9 + #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9 + #else + #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1) + #endif + + //MSVC 2012 tuple implementation + #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\ + template< template class StdTuple \ + BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ + pair( piecewise_construct_t\ + , StdTuple p\ + , StdTuple q)\ + : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ + { (void)p; (void)q; }\ + // + BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE) + #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE + #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT + #endif + + //pair copy assignment + pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p) + { + first = p.first; + second = p.second; + return *this; + } + + //pair move assignment + pair& operator=(BOOST_RV_REF(pair) p) + { + first = ::boost::move(p.first); + second = ::boost::move(p.second); + return *this; + } + + template + typename ::boost::container::dtl::disable_if_or + < pair & + , ::boost::container::dtl::is_same + , ::boost::container::dtl::is_same + >::type + operator=(const pair&p) + { + first = p.first; + second = p.second; + return *this; + } + + template + typename ::boost::container::dtl::disable_if_or + < pair & + , ::boost::container::dtl::is_same + , ::boost::container::dtl::is_same + >::type + operator=(BOOST_RV_REF_BEG pair BOOST_RV_REF_END p) + { + first = ::boost::move(p.first); + second = ::boost::move(p.second); + return *this; + } +//std::pair copy assignment + pair& operator=(const std::pair &p) + { + first = p.first; + second = p.second; + return *this; + } + + template + pair& operator=(const std::pair &p) + { + first = ::boost::move(p.first); + second = ::boost::move(p.second); + return *this; + } + + //std::pair move assignment + pair& operator=(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) + { + first = ::boost::move(p.first); + second = ::boost::move(p.second); + return *this; + } + + template + pair& operator=(BOOST_RV_REF_BEG std::pair BOOST_RV_REF_END p) + { + first = ::boost::move(p.first); + second = ::boost::move(p.second); + return *this; + } + + //swap + void swap(pair& p) + { + ::boost::adl_move_swap(this->first, p.first); + ::boost::adl_move_swap(this->second, p.second); + } +}; + +template +inline bool operator==(const pair& x, const pair& y) +{ return static_cast(x.first == y.first && x.second == y.second); } + +template +inline bool operator< (const pair& x, const pair& y) +{ return static_cast(x.first < y.first || + (!(y.first < x.first) && x.second < y.second)); } + +template +inline bool operator!=(const pair& x, const pair& y) +{ return static_cast(!(x == y)); } + +template +inline bool operator> (const pair& x, const pair& y) +{ return y < x; } + +template +inline bool operator>=(const pair& x, const pair& y) +{ return static_cast(!(x < y)); } + +template +inline bool operator<=(const pair& x, const pair& y) +{ return static_cast(!(y < x)); } + +template +inline pair make_pair(T1 x, T2 y) +{ return pair(x, y); } + +template +inline void swap(pair& x, pair& y) +{ x.swap(y); } + +} //namespace dtl { +} //namespace container { + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +struct has_move_emulation_enabled< ::boost::container::dtl::pair > +{ + static const bool value = true; +}; + +#endif + +namespace move_detail{ + +template +struct is_class_or_union; + +template +struct is_class_or_union< ::boost::container::dtl::pair > +//This specialization is needed to avoid instantiation of pair in +//is_class, and allow recursive maps. +{ + static const bool value = true; +}; + +template +struct is_class_or_union< std::pair > +//This specialization is needed to avoid instantiation of pair in +//is_class, and allow recursive maps. +{ + static const bool value = true; +}; + +template +struct is_union; + +template +struct is_union< ::boost::container::dtl::pair > +//This specialization is needed to avoid instantiation of pair in +//is_class, and allow recursive maps. +{ + static const bool value = false; +}; + +template +struct is_union< std::pair > +//This specialization is needed to avoid instantiation of pair in +//is_class, and allow recursive maps. +{ + static const bool value = false; +}; + +template +struct is_class; + +template +struct is_class< ::boost::container::dtl::pair > +//This specialization is needed to avoid instantiation of pair in +//is_class, and allow recursive maps. +{ + static const bool value = true; +}; + +template +struct is_class< std::pair > +//This specialization is needed to avoid instantiation of pair in +//is_class, and allow recursive maps. +{ + static const bool value = true; +}; + +} //namespace move_detail{ + +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP diff --git a/boost/container/detail/placement_new.hpp b/boost/container/detail/placement_new.hpp new file mode 100644 index 00000000..c50981f6 --- /dev/null +++ b/boost/container/detail/placement_new.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP +#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/container for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +struct boost_container_new_t{}; + +//avoid including +inline void *operator new(std::size_t, void *p, boost_container_new_t) +{ return p; } + +inline void operator delete(void *, void *, boost_container_new_t) +{} + +#endif //BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP diff --git a/boost/container/detail/std_fwd.hpp b/boost/container/detail/std_fwd.hpp new file mode 100644 index 00000000..09678123 --- /dev/null +++ b/boost/container/detail/std_fwd.hpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP +#define BOOST_CONTAINER_DETAIL_STD_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +////////////////////////////////////////////////////////////////////////////// +// Standard predeclarations +////////////////////////////////////////////////////////////////////////////// + +#include +BOOST_MOVE_STD_NS_BEG + +template +class allocator; + +template +struct less; + +template +struct pair; + +template +struct char_traits; + +struct input_iterator_tag; +struct forward_iterator_tag; +struct bidirectional_iterator_tag; +struct random_access_iterator_tag; + +template +class insert_iterator; + +struct allocator_arg_t; + +struct piecewise_construct_t; + +BOOST_MOVE_STD_NS_END +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP diff --git a/boost/container/detail/type_traits.hpp b/boost/container/detail/type_traits.hpp new file mode 100644 index 00000000..686cc409 --- /dev/null +++ b/boost/container/detail/type_traits.hpp @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////////// +// (C) Copyright John Maddock 2000. +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +// The alignment and Type traits implementation comes from +// John Maddock's TypeTraits library. +// +// Some other tricks come from Howard Hinnant's papers and StackOverflow replies +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP +#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace container { +namespace dtl { + +using ::boost::move_detail::enable_if; +using ::boost::move_detail::enable_if_and; +using ::boost::move_detail::is_same; +using ::boost::move_detail::is_different; +using ::boost::move_detail::is_pointer; +using ::boost::move_detail::add_reference; +using ::boost::move_detail::add_const; +using ::boost::move_detail::add_const_reference; +using ::boost::move_detail::remove_const; +using ::boost::move_detail::remove_reference; +using ::boost::move_detail::make_unsigned; +using ::boost::move_detail::is_floating_point; +using ::boost::move_detail::is_integral; +using ::boost::move_detail::is_enum; +using ::boost::move_detail::is_pod; +using ::boost::move_detail::is_empty; +using ::boost::move_detail::is_trivially_destructible; +using ::boost::move_detail::is_trivially_default_constructible; +using ::boost::move_detail::is_trivially_copy_constructible; +using ::boost::move_detail::is_trivially_move_constructible; +using ::boost::move_detail::is_trivially_copy_assignable; +using ::boost::move_detail::is_trivially_move_assignable; +using ::boost::move_detail::is_nothrow_default_constructible; +using ::boost::move_detail::is_nothrow_copy_constructible; +using ::boost::move_detail::is_nothrow_move_constructible; +using ::boost::move_detail::is_nothrow_copy_assignable; +using ::boost::move_detail::is_nothrow_move_assignable; +using ::boost::move_detail::is_nothrow_swappable; +using ::boost::move_detail::alignment_of; +using ::boost::move_detail::aligned_storage; +using ::boost::move_detail::nat; +using ::boost::move_detail::max_align_t; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP diff --git a/boost/container/detail/value_functors.hpp b/boost/container/detail/value_functors.hpp new file mode 100644 index 00000000..a2c494c5 --- /dev/null +++ b/boost/container/detail/value_functors.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP +#define BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-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) +// +// See http://www.boost.org/libs/container for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//Functors for member algorithm defaults +template +struct value_less +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a < b; } +}; + +template +struct value_equal +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a == b; } +}; + +#endif //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP diff --git a/boost/container/detail/value_init.hpp b/boost/container/detail/value_init.hpp new file mode 100644 index 00000000..35b0aa11 --- /dev/null +++ b/boost/container/detail/value_init.hpp @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP +#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +template +struct value_init +{ + value_init() + : m_t() + {} + + operator T &() { return m_t; } + + T &get() { return m_t; } + + T m_t; +}; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP diff --git a/boost/container/detail/variadic_templates_tools.hpp b/boost/container/detail/variadic_templates_tools.hpp new file mode 100644 index 00000000..1e6f3df7 --- /dev/null +++ b/boost/container/detail/variadic_templates_tools.hpp @@ -0,0 +1,163 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP +#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +#include +#include //std::size_t + +namespace boost { +namespace container { +namespace dtl { + +template +class tuple; + +template<> class tuple<> +{}; + +template +class tuple + : private tuple +{ + typedef tuple inherited; + + public: + tuple() + : inherited(), m_head() + {} + + template + tuple(U &&u, Args && ...args) + : inherited(::boost::forward(args)...), m_head(::boost::forward(u)) + {} + + // Construct tuple from another tuple. + template + tuple(const tuple& other) + : inherited(other.tail()), m_head(other.head()) + {} + + template + tuple& operator=(const tuple& other) + { + m_head = other.head(); + tail() = other.tail(); + return this; + } + + typename add_reference::type head() { return m_head; } + typename add_reference::type head() const { return m_head; } + + inherited& tail() { return *this; } + const inherited& tail() const { return *this; } + + protected: + Head m_head; +}; + + +template +tuple forward_as_tuple(Values&&... values) +{ return tuple(::boost::forward(values)...); } + +template +struct tuple_element; + +template +struct tuple_element > +{ + typedef typename tuple_element >::type type; +}; + +template +struct tuple_element<0, tuple > +{ + typedef Head type; +}; + +template +class get_impl; + +template +class get_impl > +{ + typedef typename tuple_element >::type Element; + typedef get_impl > Next; + + public: + typedef typename add_reference::type type; + typedef typename add_const_reference::type const_type; + static type get(tuple& t) { return Next::get(t.tail()); } + static const_type get(const tuple& t) { return Next::get(t.tail()); } +}; + +template +class get_impl<0, tuple > +{ + public: + typedef typename add_reference::type type; + typedef typename add_const_reference::type const_type; + static type get(tuple& t) { return t.head(); } + static const_type get(const tuple& t){ return t.head(); } +}; + +template +typename get_impl >::type get(tuple& t) +{ return get_impl >::get(t); } + +template +typename get_impl >::const_type get(const tuple& t) +{ return get_impl >::get(t); } + +//////////////////////////////////////////////////// +// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will +// be used to "unpack" into comma-separated values +// in a function call. +//////////////////////////////////////////////////// + +template struct index_tuple{ typedef index_tuple type; }; + +template struct concat_index_tuple; + +template +struct concat_index_tuple, index_tuple> + : index_tuple{}; + +template struct build_number_seq; + +template +struct build_number_seq + : concat_index_tuple::type + ,typename build_number_seq::type + >::type +{}; + +template<> struct build_number_seq<0> : index_tuple<>{}; +template<> struct build_number_seq<1> : index_tuple<0>{}; + +}}} //namespace boost { namespace container { namespace dtl { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP diff --git a/boost/container/detail/version_type.hpp b/boost/container/detail/version_type.hpp new file mode 100644 index 00000000..c2531ccc --- /dev/null +++ b/boost/container/detail/version_type.hpp @@ -0,0 +1,110 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This code comes from N1953 document by Howard E. Hinnant +// +////////////////////////////////////////////////////////////////////////////// + + +#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP +#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include +#include + +namespace boost{ +namespace container { +namespace dtl { + +template +struct version_type + : public dtl::integral_constant +{ + typedef T type; + + version_type(const version_type&); +}; + +namespace impl{ + +template , typename T::version>::value> +struct extract_version +{ + static const unsigned value = 1; +}; + +template +struct extract_version +{ + static const unsigned value = T::version::value; +}; + +template +struct has_version +{ + private: + struct two {char _[2];}; + template static two test(...); + template static char test(const typename U::version*); + public: + static const bool value = sizeof(test(0)) == 1; + void dummy(){} +}; + +template ::value> +struct version +{ + static const unsigned value = 1; +}; + +template +struct version +{ + static const unsigned value = extract_version::value; +}; + +} //namespace impl + +template +struct version + : public dtl::integral_constant::value> +{}; + +template +struct is_version +{ + static const bool value = + is_same< typename version::type, integral_constant >::value; +}; + +} //namespace dtl { + +typedef dtl::integral_constant version_0; +typedef dtl::integral_constant version_1; +typedef dtl::integral_constant version_2; + +} //namespace container { +} //namespace boost{ + +#include + +#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP diff --git a/boost/container/detail/workaround.hpp b/boost/container/detail/workaround.hpp new file mode 100644 index 00000000..736326b7 --- /dev/null +++ b/boost/container/detail/workaround.hpp @@ -0,0 +1,111 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP +#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\ + && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL) + #define BOOST_CONTAINER_PERFECT_FORWARDING +#endif + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\ + && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700) + #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST +#endif + +#if defined(BOOST_GCC_VERSION) +# if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11) +# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS +# endif +#elif defined(BOOST_MSVC) +# if _MSC_FULL_VER < 180020827 +# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS +# endif +#elif defined(BOOST_CLANG) +# if !__has_feature(cxx_delegating_constructors) +# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS +# endif +#endif + +#if defined(BOOST_MSVC) && (_MSC_VER < 1400) + #define BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600)) +#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE +#endif + +//Macros for documentation purposes. For code, expands to the argument +#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE +#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE + +//Macros for memset optimization. In most platforms +//memsetting pointers and floatings is safe and faster. +// +//If your platform does not offer these guarantees +//define these to value zero. +#ifndef BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO +#define BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO 1 +#endif + +#ifndef BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_NULL +#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL +#endif + +#define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2 +#define BOOST_CONTAINER_I , +#define BOOST_CONTAINER_DOCIGN(T) T +#define BOOST_CONTAINER_DOCONLY(T) + +/* + we need to import/export our code only if the user has specifically + asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost + libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK + if they want just this one to be dynamically liked: +*/ +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK) + + /* export if this is our own source, otherwise import: */ + #ifdef BOOST_CONTAINER_SOURCE + # define BOOST_CONTAINER_DECL BOOST_SYMBOL_EXPORT + #else + # define BOOST_CONTAINER_DECL BOOST_SYMBOL_IMPORT + + #endif /* BOOST_CONTAINER_SOURCE */ +#else + #define BOOST_CONTAINER_DECL +#endif /* DYN_LINK */ + +//#define BOOST_CONTAINER_DISABLE_FORCEINLINE + +#if defined(BOOST_CONTAINER_DISABLE_FORCEINLINE) + #define BOOST_CONTAINER_FORCEINLINE inline +#elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE) + #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE +#elif defined(BOOST_MSVC) && defined(_DEBUG) + //"__forceinline" and MSVC seems to have some bugs in debug mode + #define BOOST_CONTAINER_FORCEINLINE inline +#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) + //Older GCCs have problems with forceinline + #define BOOST_CONTAINER_FORCEINLINE inline +#else + #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE +#endif + +#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP diff --git a/boost/container/new_allocator.hpp b/boost/container/new_allocator.hpp new file mode 100644 index 00000000..51065efa --- /dev/null +++ b/boost/container/new_allocator.hpp @@ -0,0 +1,179 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_NEW_ALLOCATOR_HPP +#define BOOST_CONTAINER_NEW_ALLOCATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +//!\file + +namespace boost { +namespace container { + +/// @cond + +template +struct new_allocator_bool +{ static const bool value = Value; }; + +template +class new_allocator; + +/// @endcond + +//! Specialization of new_allocator for void types +template<> +class new_allocator +{ + public: + typedef void value_type; + typedef void * pointer; + typedef const void* const_pointer; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) propagate_on_container_move_assignment; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) is_always_equal; + // reference-to-void members are impossible + + //!Obtains an new_allocator that allocates + //!objects of type T2 + template + struct rebind + { + typedef new_allocator< T2> other; + }; + + //!Default constructor + //!Never throws + new_allocator() BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Constructor from other new_allocator. + //!Never throws + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Constructor from related new_allocator. + //!Never throws + template + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Swaps two allocators, does nothing + //!because this new_allocator is stateless + friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!An new_allocator always compares to true, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return true; } + + //!An new_allocator always compares to false, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return false; } +}; + + +//! This class is a reduced STL-compatible allocator that allocates memory using operator new +template +class new_allocator +{ + public: + typedef T value_type; + typedef T * pointer; + typedef const T * const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) propagate_on_container_move_assignment; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) is_always_equal; + + //!Obtains an new_allocator that allocates + //!objects of type T2 + template + struct rebind + { + typedef new_allocator other; + }; + + //!Default constructor + //!Never throws + new_allocator() BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Constructor from other new_allocator. + //!Never throws + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Constructor from related new_allocator. + //!Never throws + template + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Allocates memory for an array of count elements. + //!Throws std::bad_alloc if there is no enough memory + pointer allocate(size_type count) + { + if(BOOST_UNLIKELY(count > this->max_size())) + throw_bad_alloc(); + return static_cast(::operator new(count*sizeof(T))); + } + + //!Deallocates previously allocated memory. + //!Never throws + void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW + { ::operator delete((void*)ptr); } + + //!Returns the maximum number of elements that could be allocated. + //!Never throws + size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + { return size_type(-1)/sizeof(T); } + + //!Swaps two allocators, does nothing + //!because this new_allocator is stateless + friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!An new_allocator always compares to true, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return true; } + + //!An new_allocator always compares to false, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return false; } +}; + +} //namespace container { +} //namespace boost { + +#include + +#endif //BOOST_CONTAINER_NEW_ALLOCATOR_HPP diff --git a/boost/container/options.hpp b/boost/container/options.hpp new file mode 100644 index 00000000..2ac7783e --- /dev/null +++ b/boost/container/options.hpp @@ -0,0 +1,245 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-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) +// +// See http://www.boost.org/libs/container for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_OPTIONS_HPP +#define BOOST_CONTAINER_OPTIONS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace container { + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR ASSOCIATIVE TREE-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +//! Enumeration used to configure ordered associative containers +//! with a concrete tree implementation. +enum tree_type_enum +{ + red_black_tree, + avl_tree, + scapegoat_tree, + splay_tree +}; + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct tree_opt +{ + static const boost::container::tree_type_enum tree_type = TreeType; + static const bool optimize_size = OptimizeSize; +}; + +typedef tree_opt tree_assoc_defaults; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This option setter specifies the underlying tree type +//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers +BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type) + +//!This option setter specifies if node size is optimized +//!storing rebalancing data masked into pointers for ordered associative containers +BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::set, \c boost::container::multiset +//! \c boost::container::map and \c boost::container::multimap. +//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct tree_assoc_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < tree_assoc_defaults, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef tree_opt implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by tree-based associative containers +template +using tree_assoc_options_t = typename boost::container::tree_assoc_options::type; + +#endif + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR VECTOR-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct get_stored_size_type_with_alloctraits +{ + typedef StoredSizeType type; +}; + +template +struct get_stored_size_type_with_alloctraits +{ + typedef typename AllocTraits::size_type type; +}; + +template +struct vector_opt +{ + typedef GrowthType growth_factor_type; + typedef StoredSizeType stored_size_type; + + template + struct get_stored_size_type + : get_stored_size_type_with_alloctraits + {}; +}; + +class default_next_capacity; + +typedef vector_opt vector_null_opt; + +#else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This growth factor argument specifies that the container should increase it's +//!capacity a 50% when existing capacity is exhausted. +struct growth_factor_50{}; + +//!This growth factor argument specifies that the container should increase it's +//!capacity a 60% when existing capacity is exhausted. +struct growth_factor_60{}; + +//!This growth factor argument specifies that the container should increase it's +//!capacity a 100% (doubling its capacity) when existing capacity is exhausted. +struct growth_factor_100{}; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This option setter specifies the growth factor strategy of the underlying vector. +//! +//!\tparam GrowthFactor A function object that has the following signature:

+//!`template`
+//!`SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;`.

+//!`cur_cap` is the current capacity, `add_min_cap` is the minimum additional capacity +//!we want to achieve and `max_cap` is the maximum capacity that the allocator or other +//!factors allow. The implementation should return a value between `cur_cap` + `add_min_cap` +//!and `max_cap`. `cur_cap` + `add_min_cap` is guaranteed not to overflow/wraparound, +//! but the implementation should handle wraparound produced by the growth factor. +//! +//!Predefined growth factors that can be passed as arguments to this option are: +//!\c boost::container::growth_factor_50 +//!\c boost::container::growth_factor_60 +//!\c boost::container::growth_factor_100 +//! +//!If this option is not specified, a default will be used by the container. +BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type) + +//!This option specifies the unsigned integer type that a user wants the container +//!to use to hold size-related information inside a container (e.g. current size, current capacity). +//! +//!\tparam StoredSizeType A unsigned integer type. It shall be smaller than than the size +//! of the size_type deduced from `allocator_traits
::size_type` or the same type. +//! +//!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit +//!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some +//!memory can be saved for empty vectors. This could potentially performance benefits due to better +//!cache usage. +//! +//!Note that alignment requirements can disallow theoritical space savings. Example: +//!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine +//!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes) +//!will not save space when comparing two 16-bit size types because usually +//!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit +//!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type. +//!Measure the size of the resulting container and do not assume a smaller \c stored_size +//!will always lead to a smaller sizeof(container). +//! +//!If a user tries to insert more elements than representable by \c stored_size, vector +//!will throw a length_error. +//! +//!If this option is not specified, `allocator_traits::size_type` (usually std::size_t) will +//!be used to store size-related information inside the container. +BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct vector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < vector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef vector_opt< typename packed_options::growth_factor_type + , typename packed_options::stored_size_type> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template +using vector_options_t = typename boost::container::vector_options::type; + +#endif + + +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP diff --git a/boost/container/scoped_allocator.hpp b/boost/container/scoped_allocator.hpp new file mode 100644 index 00000000..6cd69fe4 --- /dev/null +++ b/boost/container/scoped_allocator.hpp @@ -0,0 +1,907 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Pablo Halpern 2009. 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) +// +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2011-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP +#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP + +#if defined (_MSC_VER) +# pragma once +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include + +#include + +namespace boost { namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace dtl { + +template +struct is_scoped_allocator_imp +{ + typedef char yes_type; + struct no_type{ char dummy[2]; }; + + template + static yes_type test(typename T::outer_allocator_type*); + + template + static int test(...); + + static const bool value = (sizeof(yes_type) == sizeof(test(0))); +}; + +template::value > +struct outermost_allocator_type_impl +{ + typedef typename MaybeScopedAlloc::outer_allocator_type outer_type; + typedef typename outermost_allocator_type_impl::type type; +}; + +template +struct outermost_allocator_type_impl +{ + typedef MaybeScopedAlloc type; +}; + +template::value > +struct outermost_allocator_imp +{ + typedef MaybeScopedAlloc type; + + static type &get(MaybeScopedAlloc &a) + { return a; } + + static const type &get(const MaybeScopedAlloc &a) + { return a; } +}; + +template +struct outermost_allocator_imp +{ + typedef typename MaybeScopedAlloc::outer_allocator_type outer_type; + typedef typename outermost_allocator_type_impl::type type; + + static type &get(MaybeScopedAlloc &a) + { return outermost_allocator_imp::get(a.outer_allocator()); } + + static const type &get(const MaybeScopedAlloc &a) + { return outermost_allocator_imp::get(a.outer_allocator()); } +}; + +} //namespace dtl { + +template +struct is_scoped_allocator + : dtl::is_scoped_allocator_imp +{}; + +template +struct outermost_allocator + : dtl::outermost_allocator_imp +{}; + +template +typename outermost_allocator::type & + get_outermost_allocator(Allocator &a) +{ return outermost_allocator::get(a); } + +template +const typename outermost_allocator::type & + get_outermost_allocator(const Allocator &a) +{ return outermost_allocator::get(a); } + +namespace dtl { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template +class scoped_allocator_adaptor_base + : public OuterAlloc +{ + typedef allocator_traits outer_traits_type; + BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) + + public: + template + struct rebind_base + { + typedef scoped_allocator_adaptor_base other; + }; + + typedef OuterAlloc outer_allocator_type; + typedef scoped_allocator_adaptor inner_allocator_type; + typedef allocator_traits inner_traits_type; + typedef scoped_allocator_adaptor + scoped_allocator_type; + typedef dtl::bool_< + outer_traits_type::propagate_on_container_copy_assignment::value || + inner_allocator_type::propagate_on_container_copy_assignment::value + > propagate_on_container_copy_assignment; + typedef dtl::bool_< + outer_traits_type::propagate_on_container_move_assignment::value || + inner_allocator_type::propagate_on_container_move_assignment::value + > propagate_on_container_move_assignment; + typedef dtl::bool_< + outer_traits_type::propagate_on_container_swap::value || + inner_allocator_type::propagate_on_container_swap::value + > propagate_on_container_swap; + typedef dtl::bool_< + outer_traits_type::is_always_equal::value && + inner_allocator_type::is_always_equal::value + > is_always_equal; + + scoped_allocator_adaptor_base() + {} + + template + scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args) + : outer_allocator_type(::boost::forward(outerAlloc)) + , m_inner(args...) + {} + + scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) + : outer_allocator_type(other.outer_allocator()) + , m_inner(other.inner_allocator()) + {} + + scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + : outer_allocator_type(::boost::move(other.outer_allocator())) + , m_inner(::boost::move(other.inner_allocator())) + {} + + template + scoped_allocator_adaptor_base + (const scoped_allocator_adaptor_base& other) + : outer_allocator_type(other.outer_allocator()) + , m_inner(other.inner_allocator()) + {} + + template + scoped_allocator_adaptor_base + (BOOST_RV_REF_BEG scoped_allocator_adaptor_base + BOOST_RV_REF_END other) + : outer_allocator_type(other.outer_allocator()) + , m_inner(other.inner_allocator()) + {} + + public: + struct internal_type_t{}; + + template + scoped_allocator_adaptor_base + ( internal_type_t + , BOOST_FWD_REF(OuterA2) outerAlloc + , const inner_allocator_type &inner) + : outer_allocator_type(::boost::forward(outerAlloc)) + , m_inner(inner) + {} + + public: + + scoped_allocator_adaptor_base &operator= + (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) + { + outer_allocator_type::operator=(other.outer_allocator()); + m_inner = other.inner_allocator(); + return *this; + } + + scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + { + outer_allocator_type::operator=(boost::move(other.outer_allocator())); + m_inner = ::boost::move(other.inner_allocator()); + return *this; + } + + void swap(scoped_allocator_adaptor_base &r) + { + boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); + boost::adl_move_swap(this->m_inner, r.inner_allocator()); + } + + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) + { l.swap(r); } + + inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW + { return m_inner; } + + inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_inner; } + + outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW + { return static_cast(*this); } + + const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + { return static_cast(*this); } + + scoped_allocator_type select_on_container_copy_construction() const + { + return scoped_allocator_type + (internal_type_t() + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) + ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) + ); + } + + private: + inner_allocator_type m_inner; +}; + +#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +//Let's add a dummy first template parameter to allow creating +//specializations up to maximum InnerAlloc count +template +class scoped_allocator_adaptor_base; + +//Specializations for the adaptor with InnerAlloc allocators + +#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\ +template \ +class scoped_allocator_adaptor_base\ + : public OuterAlloc\ +{\ + typedef allocator_traits outer_traits_type;\ + BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\ + \ + public:\ + template \ + struct rebind_base\ + {\ + typedef scoped_allocator_adaptor_base other;\ + };\ + \ + typedef OuterAlloc outer_allocator_type;\ + typedef scoped_allocator_adaptor inner_allocator_type;\ + typedef scoped_allocator_adaptor scoped_allocator_type;\ + typedef allocator_traits inner_traits_type;\ + typedef dtl::bool_<\ + outer_traits_type::propagate_on_container_copy_assignment::value ||\ + inner_allocator_type::propagate_on_container_copy_assignment::value\ + > propagate_on_container_copy_assignment;\ + typedef dtl::bool_<\ + outer_traits_type::propagate_on_container_move_assignment::value ||\ + inner_allocator_type::propagate_on_container_move_assignment::value\ + > propagate_on_container_move_assignment;\ + typedef dtl::bool_<\ + outer_traits_type::propagate_on_container_swap::value ||\ + inner_allocator_type::propagate_on_container_swap::value\ + > propagate_on_container_swap;\ + \ + typedef dtl::bool_<\ + outer_traits_type::is_always_equal::value &&\ + inner_allocator_type::is_always_equal::value\ + > is_always_equal;\ + \ + scoped_allocator_adaptor_base(){}\ + \ + template \ + scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\ + : outer_allocator_type(::boost::forward(outerAlloc))\ + , m_inner(BOOST_MOVE_ARG##N)\ + {}\ + \ + scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + : outer_allocator_type(::boost::move(other.outer_allocator()))\ + , m_inner(::boost::move(other.inner_allocator()))\ + {}\ + \ + template \ + scoped_allocator_adaptor_base\ + (const scoped_allocator_adaptor_base& other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + template \ + scoped_allocator_adaptor_base\ + (BOOST_RV_REF_BEG scoped_allocator_adaptor_base BOOST_RV_REF_END other)\ + : outer_allocator_type(other.outer_allocator())\ + , m_inner(other.inner_allocator())\ + {}\ + \ + public:\ + struct internal_type_t{};\ + \ + template \ + scoped_allocator_adaptor_base\ + ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\ + : outer_allocator_type(::boost::forward(outerAlloc))\ + , m_inner(inner)\ + {}\ + \ + public:\ + scoped_allocator_adaptor_base &operator=\ + (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\ + {\ + outer_allocator_type::operator=(other.outer_allocator());\ + m_inner = other.inner_allocator();\ + return *this;\ + }\ + \ + scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\ + {\ + outer_allocator_type::operator=(boost::move(other.outer_allocator()));\ + m_inner = ::boost::move(other.inner_allocator());\ + return *this;\ + }\ + \ + void swap(scoped_allocator_adaptor_base &r)\ + {\ + boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\ + boost::adl_move_swap(this->m_inner, r.inner_allocator());\ + }\ + \ + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\ + { l.swap(r); }\ + \ + inner_allocator_type& inner_allocator()\ + { return m_inner; }\ + \ + inner_allocator_type const& inner_allocator() const\ + { return m_inner; }\ + \ + outer_allocator_type & outer_allocator()\ + { return static_cast(*this); }\ + \ + const outer_allocator_type &outer_allocator() const\ + { return static_cast(*this); }\ + \ + scoped_allocator_type select_on_container_copy_construction() const\ + {\ + return scoped_allocator_type\ + (internal_type_t()\ + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\ + ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\ + );\ + }\ + private:\ + inner_allocator_type m_inner;\ +};\ +//! +BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE) +#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE + +#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9 + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9 +#else + #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs... + #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs +#endif + +//Specialization for adaptor without any InnerAlloc +template +class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> + : public OuterAlloc +{ + BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) + public: + + template + struct rebind_base + { + typedef scoped_allocator_adaptor_base + ::template portable_rebind_alloc::type + BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other; + }; + + typedef OuterAlloc outer_allocator_type; + typedef allocator_traits outer_traits_type; + typedef scoped_allocator_adaptor inner_allocator_type; + typedef inner_allocator_type scoped_allocator_type; + typedef allocator_traits inner_traits_type; + typedef typename outer_traits_type:: + propagate_on_container_copy_assignment propagate_on_container_copy_assignment; + typedef typename outer_traits_type:: + propagate_on_container_move_assignment propagate_on_container_move_assignment; + typedef typename outer_traits_type:: + propagate_on_container_swap propagate_on_container_swap; + typedef typename outer_traits_type:: + is_always_equal is_always_equal; + + scoped_allocator_adaptor_base() + {} + + template + scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc) + : outer_allocator_type(::boost::forward(outerAlloc)) + {} + + scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) + : outer_allocator_type(other.outer_allocator()) + {} + + scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + : outer_allocator_type(::boost::move(other.outer_allocator())) + {} + + template + scoped_allocator_adaptor_base + (const scoped_allocator_adaptor_base& other) + : outer_allocator_type(other.outer_allocator()) + {} + + template + scoped_allocator_adaptor_base + (BOOST_RV_REF_BEG scoped_allocator_adaptor_base BOOST_RV_REF_END other) + : outer_allocator_type(other.outer_allocator()) + {} + + public: + struct internal_type_t{}; + + template + scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &) + : outer_allocator_type(::boost::forward(outerAlloc)) + {} + + public: + scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) + { + outer_allocator_type::operator=(other.outer_allocator()); + return *this; + } + + scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) + { + outer_allocator_type::operator=(boost::move(other.outer_allocator())); + return *this; + } + + void swap(scoped_allocator_adaptor_base &r) + { + boost::adl_move_swap(this->outer_allocator(), r.outer_allocator()); + } + + friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) + { l.swap(r); } + + inner_allocator_type& inner_allocator() + { return static_cast(*this); } + + inner_allocator_type const& inner_allocator() const + { return static_cast(*this); } + + outer_allocator_type & outer_allocator() + { return static_cast(*this); } + + const outer_allocator_type &outer_allocator() const + { return static_cast(*this); } + + scoped_allocator_type select_on_container_copy_construction() const + { + return scoped_allocator_type + (internal_type_t() + ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) + //Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) + //as inner_allocator() is equal to *this and that would trigger an infinite loop + , this->inner_allocator() + ); + } +}; + +} //namespace dtl { + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//Scoped allocator +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) + +//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor. +//! The class template scoped_allocator_adaptor is an allocator template that specifies +//! the memory resource (the outer allocator) to be used by a container (as any other +//! allocator does) and also specifies an inner allocator resource to be passed to +//! the constructor of every element within the container. +//! +//! This adaptor is +//! instantiated with one outer and zero or more inner allocator types. If +//! instantiated with only one allocator type, the inner allocator becomes the +//! scoped_allocator_adaptor itself, thus using the same allocator resource for the +//! container and every element within the container and, if the elements themselves +//! are containers, each of their elements recursively. If instantiated with more than +//! one allocator, the first allocator is the outer allocator for use by the container, +//! the second allocator is passed to the constructors of the container's elements, +//! and, if the elements themselves are containers, the third allocator is passed to +//! the elements' elements, and so on. If containers are nested to a depth greater +//! than the number of allocators, the last allocator is used repeatedly, as in the +//! single-allocator case, for any remaining recursions. +//! +//! [Note: The +//! scoped_allocator_adaptor is derived from the outer allocator type so it can be +//! substituted for the outer allocator type in most expressions. -end note] +//! +//! In the construct member functions, OUTERMOST(x) is x if x does not have +//! an outer_allocator() member function and +//! OUTERMOST(x.outer_allocator()) otherwise; OUTERMOST_ALLOC_TRAITS(x) is +//! allocator_traits. +//! +//! [Note: OUTERMOST(x) and +//! OUTERMOST_ALLOC_TRAITS(x) are recursive operations. It is incumbent upon +//! the definition of outer_allocator() to ensure that the recursion terminates. +//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note] +template +class scoped_allocator_adaptor + +#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) + +template +class scoped_allocator_adaptor + +#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) + +#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +class scoped_allocator_adaptor +#endif + + : public dtl::scoped_allocator_adaptor_base + +{ + BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor) + + public: + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + typedef dtl::scoped_allocator_adaptor_base + base_type; + typedef typename base_type::internal_type_t internal_type_t; + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + typedef OuterAlloc outer_allocator_type; + //! Type: For exposition only + //! + typedef allocator_traits outer_traits_type; + //! Type: scoped_allocator_adaptor if sizeof...(InnerAllocs) is zero; otherwise, + //! scoped_allocator_adaptor. + typedef typename base_type::inner_allocator_type inner_allocator_type; + typedef allocator_traits inner_traits_type; + typedef typename outer_traits_type::value_type value_type; + typedef typename outer_traits_type::size_type size_type; + typedef typename outer_traits_type::difference_type difference_type; + typedef typename outer_traits_type::pointer pointer; + typedef typename outer_traits_type::const_pointer const_pointer; + typedef typename outer_traits_type::void_pointer void_pointer; + typedef typename outer_traits_type::const_void_pointer const_void_pointer; + //! Type: A type with a constant boolean value == true if + //!`allocator_traits:: propagate_on_container_copy_assignment::value` is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. + typedef typename base_type:: + propagate_on_container_copy_assignment propagate_on_container_copy_assignment; + //! Type: A type with a constant boolean value == true if + //!`allocator_traits:: propagate_on_container_move_assignment::value` is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. + typedef typename base_type:: + propagate_on_container_move_assignment propagate_on_container_move_assignment; + + //! Type: A type with a constant boolean value == true if + //! `allocator_traits:: propagate_on_container_swap::value` is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. + typedef typename base_type:: + propagate_on_container_swap propagate_on_container_swap; + + //! Type: A type with a constant boolean value == true if + //!`allocator_traits:: is_always_equal::value` is + //! true for all Allocator in the set of OuterAlloc and InnerAllocs..., false otherwise. + typedef typename base_type:: + is_always_equal is_always_equal; + + //! Type: Rebinds scoped allocator to + //! typedef scoped_allocator_adaptor + //! < typename outer_traits_type::template portable_rebind_alloc::type + //! , InnerAllocs... > + template + struct rebind + { + typedef scoped_allocator_adaptor + < typename outer_traits_type::template portable_rebind_alloc::type + , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other; + }; + + //! Effects: value-initializes the OuterAlloc base class + //! and the inner allocator object. + scoped_allocator_adaptor() + {} + + ~scoped_allocator_adaptor() + {} + + //! Effects: initializes each allocator within the adaptor with + //! the corresponding allocator from other. + scoped_allocator_adaptor(const scoped_allocator_adaptor& other) + : base_type(other.base()) + {} + + //! Effects: move constructs each allocator within the adaptor with + //! the corresponding allocator from other. + scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other) + : base_type(::boost::move(other.base())) + {} + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Requires: OuterAlloc shall be constructible from OuterA2. + //! + //! Effects: initializes the OuterAlloc base class with boost::forward(outerAlloc) and inner + //! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the + //! corresponding allocator from the argument list). + template + scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs) + : base_type(::boost::forward(outerAlloc), innerAllocs...) + {} + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\ + template \ + scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\ + : base_type(::boost::forward(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\ + {}\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE) + #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE + + #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Requires: OuterAlloc shall be constructible from OuterA2. + //! + //! Effects: initializes each allocator within the adaptor with the corresponding allocator from other. + template + scoped_allocator_adaptor(const scoped_allocator_adaptor &other) + : base_type(other.base()) + {} + + //! Requires: OuterAlloc shall be constructible from OuterA2. + //! + //! Effects: initializes each allocator within the adaptor with the corresponding allocator + //! rvalue from other. + template + scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor + BOOST_RV_REF_END other) + : base_type(::boost::move(other.base())) + {} + + scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other) + { return static_cast(base_type::operator=(static_cast(other))); } + + scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) + { return static_cast(base_type::operator=(boost::move(other.base()))); } + + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Effects: swaps *this with r. + //! + void swap(scoped_allocator_adaptor &r); + + //! Effects: swaps *this with r. + //! + friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r); + + //! Returns: + //! static_cast(*this). + outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW; + + //! Returns: + //! static_cast(*this). + const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; + + //! Returns: + //! *this if sizeof...(InnerAllocs) is zero; otherwise, inner. + inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW; + + //! Returns: + //! *this if sizeof...(InnerAllocs) is zero; otherwise, inner. + inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW; + + #endif //BOOST_CONTAINER_DOXYGEN_INVOKED + + //! Returns: + //! allocator_traits:: max_size(outer_allocator()). + size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + { return outer_traits_type::max_size(this->outer_allocator()); } + + //! Effects: + //! calls OUTERMOST_ALLOC_TRAITS(*this):: destroy(OUTERMOST(*this), p). + template + void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW + { + allocator_traits::type> + ::destroy(get_outermost_allocator(this->outer_allocator()), p); + } + + //! Returns: + //! allocator_traits::allocate(outer_allocator(), n). + pointer allocate(size_type n) + { return outer_traits_type::allocate(this->outer_allocator(), n); } + + //! Returns: + //! allocator_traits::allocate(outer_allocator(), n, hint). + pointer allocate(size_type n, const_void_pointer hint) + { return outer_traits_type::allocate(this->outer_allocator(), n, hint); } + + //! Effects: + //! allocator_traits::deallocate(outer_allocator(), p, n). + void deallocate(pointer p, size_type n) + { outer_traits_type::deallocate(this->outer_allocator(), p, n); } + + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Returns: A new scoped_allocator_adaptor object where each allocator + //! Allocator in the adaptor is initialized from the result of calling + //! allocator_traits::select_on_container_copy_construction() on + //! the corresponding allocator in *this. + scoped_allocator_adaptor select_on_container_copy_construction() const; + #endif //BOOST_CONTAINER_DOXYGEN_INVOKED + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + base_type &base() { return *this; } + + const base_type &base() const { return *this; } + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: + //! 1) If uses_allocator::value is false calls + //! OUTERMOST_ALLOC_TRAITS(*this):: + //! construct(OUTERMOST(*this), p, std::forward(args)...). + //! + //! 2) Otherwise, if uses_allocator::value is true and + //! is_constructible:: value is true, calls + //! OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, allocator_arg, + //! inner_allocator(), std::forward(args)...). + //! + //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't + //! be implemented so that condition will be replaced by + //! constructible_with_allocator_prefix::value. -end note] + //! + //! 3) Otherwise, if uses_allocator::value is true and + //! is_constructible:: value is true, calls + //! OUTERMOST_ALLOC_TRAITS(*this):: construct(OUTERMOST(*this), p, + //! std::forward(args)..., inner_allocator()). + //! + //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't be + //! implemented so that condition will be replaced by + //! constructible_with_allocator_suffix:: value. -end note] + //! + //! 4) Otherwise, the program is ill-formed. + //! + //! [Note: An error will result if uses_allocator evaluates + //! to true but the specific constructor does not take an allocator. This definition prevents a silent + //! failure to pass an inner allocator to a contained element. -end note] + template < typename T, class ...Args> + void construct(T* p, BOOST_FWD_REF(Args)...args) + { + dtl::dispatch_uses_allocator + ( (get_outermost_allocator)(this->outer_allocator()) + , this->inner_allocator(), p, ::boost::forward(args)...); + } + + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //Disable this overload if the first argument is pair as some compilers have + //overload selection problems when the first parameter is a pair. + #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \ + template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\ + void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\ + {\ + dtl::dispatch_uses_allocator\ + ( (get_outermost_allocator)(this->outer_allocator())\ + , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE) + #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE + + #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + public: + //Internal function + template + scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner) + : base_type(internal_type_t(), ::boost::forward(outer), inner) + {} + + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +}; + +/// @cond + +template +struct scoped_allocator_operator_equal +{ + //Optimize equal outer allocator types with + //allocator_traits::equal which uses is_always_equal + template + static bool equal_outer(const IA &l, const IA &r) + { return allocator_traits::equal(l, r); } + + //Otherwise compare it normally + template + static bool equal_outer(const IA1 &l, const IA2 &r) + { return l == r; } + + //Otherwise compare it normally + template + static bool equal_inner(const IA &l, const IA &r) + { return allocator_traits::equal(l, r); } +}; + +template<> +struct scoped_allocator_operator_equal + : scoped_allocator_operator_equal +{ + //when inner allocator count is zero, + //inner_allocator_type is the same as outer_allocator_type + //so both types can be different in operator== + template + static bool equal_inner(const IA1 &, const IA2 &) + { return true; } +}; + +/// @endcond + +template +inline bool operator==(const scoped_allocator_adaptor& a + ,const scoped_allocator_adaptor& b) +{ + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + const bool has_zero_inner = sizeof...(InnerAllocs) == 0u; + #else + const bool has_zero_inner = boost::container::dtl::is_same::value; + #endif + typedef scoped_allocator_operator_equal equal_t; + return equal_t::equal_outer(a.outer_allocator(), b.outer_allocator()) && + equal_t::equal_inner(a.inner_allocator(), b.inner_allocator()); +} + +template +inline bool operator!=(const scoped_allocator_adaptor& a + ,const scoped_allocator_adaptor& b) +{ return !(a == b); } + +}} // namespace boost { namespace container { + +#include + +#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP diff --git a/boost/container/scoped_allocator_fwd.hpp b/boost/container/scoped_allocator_fwd.hpp new file mode 100644 index 00000000..cddf7fad --- /dev/null +++ b/boost/container/scoped_allocator_fwd.hpp @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP +#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP + +//! \file +//! This header file forward declares boost::container::scoped_allocator_adaptor + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif + +namespace boost { namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) + + template + class scoped_allocator_adaptor; + + #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) + + template + class scoped_allocator_adaptor; + + template + class scoped_allocator_adaptor; + + #endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST) + +#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template + class scoped_allocator_adaptor; + +#endif + + +#else //BOOST_CONTAINER_DOXYGEN_INVOKED + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +}} // namespace boost { namespace container { + +#include + +#endif // BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP diff --git a/boost/container/throw_exception.hpp b/boost/container/throw_exception.hpp new file mode 100644 index 00000000..1b6eec11 --- /dev/null +++ b/boost/container/throw_exception.hpp @@ -0,0 +1,181 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP +#define BOOST_CONTAINER_THROW_EXCEPTION_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#ifndef BOOST_NO_EXCEPTIONS + #include //for std exception types + #include //for implicit std::string conversion + #include //for std::bad_alloc +#else + #include + #include //for std::abort +#endif + +namespace boost { +namespace container { + +#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) + //The user must provide definitions for the following functions + + void throw_bad_alloc(); + + void throw_out_of_range(const char* str); + + void throw_length_error(const char* str); + + void throw_logic_error(const char* str); + + void throw_runtime_error(const char* str); + +#elif defined(BOOST_NO_EXCEPTIONS) + + inline void throw_bad_alloc() + { + const char msg[] = "boost::container bad_alloc thrown"; + (void)msg; + BOOST_ASSERT(!msg); + std::abort(); + } + + inline void throw_out_of_range(const char* str) + { + const char msg[] = "boost::container out_of_range thrown"; + (void)msg; (void)str; + BOOST_ASSERT_MSG(!msg, str); + std::abort(); + } + + inline void throw_length_error(const char* str) + { + const char msg[] = "boost::container length_error thrown"; + (void)msg; (void)str; + BOOST_ASSERT_MSG(!msg, str); + std::abort(); + } + + inline void throw_logic_error(const char* str) + { + const char msg[] = "boost::container logic_error thrown"; + (void)msg; (void)str; + BOOST_ASSERT_MSG(!msg, str); + std::abort(); + } + + inline void throw_runtime_error(const char* str) + { + const char msg[] = "boost::container runtime_error thrown"; + (void)msg; (void)str; + BOOST_ASSERT_MSG(!msg, str); + std::abort(); + } + +#else //defined(BOOST_NO_EXCEPTIONS) + + //! Exception callback called by Boost.Container when fails to allocate the requested storage space. + //!

+ inline void throw_bad_alloc() + { + throw std::bad_alloc(); + } + + //! Exception callback called by Boost.Container to signal arguments out of range. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::out_of_range(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
+ inline void throw_out_of_range(const char* str) + { + throw std::out_of_range(str); + } + + //! Exception callback called by Boost.Container to signal errors resizing. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::length_error(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container length_error thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
+ inline void throw_length_error(const char* str) + { + throw std::length_error(str); + } + + //! Exception callback called by Boost.Container to report errors in the internal logical + //! of the program, such as violation of logical preconditions or class invariants. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::logic_error(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
+ inline void throw_logic_error(const char* str) + { + throw std::logic_error(str); + } + + //! Exception callback called by Boost.Container to report errors that can only be detected during runtime. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::runtime_error(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
+ inline void throw_runtime_error(const char* str) + { + throw std::runtime_error(str); + } + +#endif + +}} //namespace boost { namespace container { + +#include + +#endif //#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP diff --git a/boost/container/uses_allocator.hpp b/boost/container/uses_allocator.hpp new file mode 100644 index 00000000..e0e35180 --- /dev/null +++ b/boost/container/uses_allocator.hpp @@ -0,0 +1,169 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2011-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_USES_ALLOCATOR_HPP +#define BOOST_CONTAINER_USES_ALLOCATOR_HPP + +#include +#include + +namespace boost { +namespace container { + +//! Remark: if a specialization constructible_with_allocator_suffix::value is true, indicates that T may be constructed +//! with an allocator as its last constructor argument. Ideally, all constructors of T (including the +//! copy and move constructors) should have a variant that accepts a final argument of +//! allocator_type. +//! +//! Requires: if a specialization constructible_with_allocator_suffix::value is true, T must have a nested type, +//! allocator_type and at least one constructor for which allocator_type is the last +//! parameter. If not all constructors of T can be called with a final allocator_type argument, +//! and if T is used in a context where a container must call such a constructor, then the program is +//! ill-formed. +//! +//! +//! template > +//! class Z { +//! public: +//! typedef Allocator allocator_type; +//! +//! // Default constructor with optional allocator suffix +//! Z(const allocator_type& a = allocator_type()); +//! +//! // Copy constructor and allocator-extended copy constructor +//! Z(const Z& zz); +//! Z(const Z& zz, const allocator_type& a); +//! }; +//! +//! // Specialize trait for class template Z +//! template > +//! struct constructible_with_allocator_suffix > +//! { static const bool value = true; }; +//! +//! +//! Note: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)" +//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as +//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments. +//! Applications aiming portability with several compilers should always define this trait. +//! +//! In conforming C++11 compilers or compilers supporting SFINAE expressions +//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used +//! to detect if a type should be constructed with suffix or prefix allocator arguments. +template +struct constructible_with_allocator_suffix +{ static const bool value = false; }; + +//! Remark: if a specialization constructible_with_allocator_prefix::value is true, indicates that T may be constructed +//! with allocator_arg and T::allocator_type as its first two constructor arguments. +//! Ideally, all constructors of T (including the copy and move constructors) should have a variant +//! that accepts these two initial arguments. +//! +//! Requires: specialization constructible_with_allocator_prefix::value is true, T must have a nested type, +//! allocator_type and at least one constructor for which allocator_arg_t is the first +//! parameter and allocator_type is the second parameter. If not all constructors of T can be +//! called with these initial arguments, and if T is used in a context where a container must call such +//! a constructor, then the program is ill-formed. +//! +//! +//! template > +//! class Y { +//! public: +//! typedef Allocator allocator_type; +//! +//! // Default constructor with and allocator-extended default constructor +//! Y(); +//! Y(allocator_arg_t, const allocator_type& a); +//! +//! // Copy constructor and allocator-extended copy constructor +//! Y(const Y& yy); +//! Y(allocator_arg_t, const allocator_type& a, const Y& yy); +//! +//! // Variadic constructor and allocator-extended variadic constructor +//! template Y(Args&& args...); +//! template +//! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args); +//! }; +//! +//! // Specialize trait for class template Y +//! template > +//! struct constructible_with_allocator_prefix > +//! { static const bool value = true; }; +//! +//! +//! +//! Note: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)" +//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as +//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments. +//! Applications aiming portability with several compilers should always define this trait. +//! +//! In conforming C++11 compilers or compilers supporting SFINAE expressions +//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used +//! to detect if a type should be constructed with suffix or prefix allocator arguments. +template +struct constructible_with_allocator_prefix +{ static const bool value = false; }; + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace dtl { + +template +struct uses_allocator_imp +{ + // Use SFINAE (Substitution Failure Is Not An Error) to detect the + // presence of an 'allocator_type' nested type convertilble from Allocator. + private: + typedef char yes_type; + struct no_type{ char dummy[2]; }; + + // Match this function if T::allocator_type exists and is + // implicitly convertible from Allocator + template + static yes_type test(typename U::allocator_type); + + // Match this function if T::allocator_type exists and it's type is `erased_type`. + template + static typename dtl::enable_if + < dtl::is_same + , yes_type + >::type test(const V&); + + // Match this function if TypeT::allocator_type does not exist or is + // not convertible from Allocator. + template + static no_type test(...); + static Allocator alloc; // Declared but not defined + + public: + static const bool value = sizeof(test(alloc)) == sizeof(yes_type); +}; + +} //namespace dtl { + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! Remark: Automatically detects whether T has a nested allocator_type that is convertible from +//! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may +//! specialize this type to define uses_allocator::value as true for a T of user-defined type if T does not +//! have a nested allocator_type but is nonetheless constructible using the specified Allocator where either: +//! the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or +//! the last argument of a constructor has type Alloc. +//! +//! Result: uses_allocator::value== true if a type T::allocator_type +//! exists and either is_convertible::value != false or T::allocator_type +//! is an alias `erased_type`. False otherwise. +template +struct uses_allocator + : dtl::uses_allocator_imp +{}; + +}} //namespace boost::container + +#endif //BOOST_CONTAINER_USES_ALLOCATOR_HPP diff --git a/boost/container/uses_allocator_fwd.hpp b/boost/container/uses_allocator_fwd.hpp new file mode 100644 index 00000000..42a5b904 --- /dev/null +++ b/boost/container/uses_allocator_fwd.hpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_USES_ALLOCATOR_FWD_HPP +#define BOOST_CONTAINER_USES_ALLOCATOR_FWD_HPP + +#include +#include + +//! \file +//! This header forward declares boost::container::constructible_with_allocator_prefix, +//! boost::container::constructible_with_allocator_suffix and +//! boost::container::uses_allocator. Also defines the following types: + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + template + struct std_allocator_arg_holder + { + static ::std::allocator_arg_t *dummy; + }; + + template //Silence null-reference compiler warnings + ::std::allocator_arg_t *std_allocator_arg_holder::dummy = reinterpret_cast< ::std::allocator_arg_t * >(0x1234); + +typedef const std::allocator_arg_t & allocator_arg_t; + +#else + +//! The allocator_arg_t struct is an empty structure type used as a unique type to +//! disambiguate constructor and function overloading. Specifically, several types +//! have constructors with allocator_arg_t as the first argument, immediately followed +//! by an argument of a type that satisfies Allocator requirements +typedef unspecified allocator_arg_t; + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! The `erased_type` struct is an empty struct that serves as a placeholder for a type +//! T in situations where the actual type T is determined at runtime. For example, +//! the nested type, `allocator_type`, is an alias for `erased_type` in classes that +//! use type-erased allocators. +struct erased_type {}; + +//! A instance of type +//! allocator_arg_t +static allocator_arg_t allocator_arg = BOOST_CONTAINER_DOC1ST(unspecified, *std_allocator_arg_holder<>::dummy); + +// @cond + +template +struct constructible_with_allocator_suffix; + +template +struct constructible_with_allocator_prefix; + +template +struct uses_allocator; + +// @endcond + +}} // namespace boost { namespace container { + +#endif //BOOST_CONTAINER_USES_ALLOCATOR_HPP diff --git a/boost/container/vector.hpp b/boost/container/vector.hpp new file mode 100644 index 00000000..89ed12e9 --- /dev/null +++ b/boost/container/vector.hpp @@ -0,0 +1,3377 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP +#define BOOST_CONTAINER_CONTAINER_VECTOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +#include +#include //new_allocator +#include +#include +// container detail +#include +#include //equal() +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// intrusive +#include +// move +#include +#include +#include +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +// move/algo +#include +#include +#include +#include +// other +#include +#include +#include + +//std +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include //for std::initializer_list +#endif + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + +template +class vec_iterator +{ + public: + typedef std::random_access_iterator_tag iterator_category; + typedef typename boost::intrusive::pointer_traits::element_type value_type; + typedef typename boost::intrusive::pointer_traits::difference_type difference_type; + typedef typename dtl::if_c + < IsConst + , typename boost::intrusive::pointer_traits::template + rebind_pointer::type + , Pointer + >::type pointer; + typedef typename boost::intrusive::pointer_traits ptr_traits; + typedef typename ptr_traits::reference reference; + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + private: + Pointer m_ptr; + + public: + BOOST_CONTAINER_FORCEINLINE const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_ptr; } + + BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW + { return m_ptr; } + + BOOST_CONTAINER_FORCEINLINE explicit vec_iterator(Pointer ptr) BOOST_NOEXCEPT_OR_NOTHROW + : m_ptr(ptr) + {} + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + public: + + //Constructors + BOOST_CONTAINER_FORCEINLINE vec_iterator() BOOST_NOEXCEPT_OR_NOTHROW + : m_ptr() //Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_CONTAINER_FORCEINLINE vec_iterator(vec_iterator const& other) BOOST_NOEXCEPT_OR_NOTHROW + : m_ptr(other.get_ptr()) + {} + + //Pointer like operators + BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW + { return *m_ptr; } + + BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW + { return ::boost::intrusive::pointer_traits::pointer_to(this->operator*()); } + + BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW + { return m_ptr[off]; } + + //Increment / Decrement + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW + { ++m_ptr; return *this; } + + BOOST_CONTAINER_FORCEINLINE vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW + { return vec_iterator(m_ptr++); } + + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW + { --m_ptr; return *this; } + + BOOST_CONTAINER_FORCEINLINE vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW + { return vec_iterator(m_ptr--); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { m_ptr += off; return *this; } + + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { m_ptr -= off; return *this; } + + BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { return vec_iterator(x.m_ptr+off); } + + BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW + { right.m_ptr += off; return right; } + + BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { left.m_ptr -= off; return left; } + + BOOST_CONTAINER_FORCEINLINE friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW + { return left.m_ptr - right.m_ptr; } + + //Comparison operators + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr == r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr != r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr < r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr <= r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr > r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr >= r.m_ptr; } +}; + +template +struct vector_insert_ordered_cursor +{ + typedef typename iterator_traits::value_type size_type; + typedef typename iterator_traits::reference reference; + + BOOST_CONTAINER_FORCEINLINE vector_insert_ordered_cursor(BiDirPosConstIt posit, BiDirValueIt valueit) + : last_position_it(posit), last_value_it(valueit) + {} + + void operator --() + { + --last_value_it; + --last_position_it; + while(this->get_pos() == size_type(-1)){ + --last_value_it; + --last_position_it; + } + } + + BOOST_CONTAINER_FORCEINLINE size_type get_pos() const + { return *last_position_it; } + + BOOST_CONTAINER_FORCEINLINE reference get_val() + { return *last_value_it; } + + BiDirPosConstIt last_position_it; + BiDirValueIt last_value_it; +}; + +struct initial_capacity_t{}; + +template +BOOST_CONTAINER_FORCEINLINE const Pointer &vector_iterator_get_ptr(const vec_iterator &it) BOOST_NOEXCEPT_OR_NOTHROW +{ return it.get_ptr(); } + +template +BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr(vec_iterator &it) BOOST_NOEXCEPT_OR_NOTHROW +{ return it.get_ptr(); } + +struct vector_uninitialized_size_t {}; +static const vector_uninitialized_size_t vector_uninitialized_size = vector_uninitialized_size_t(); + +template +struct vector_value_traits_base +{ + static const bool trivial_dctr = dtl::is_trivially_destructible::value; + static const bool trivial_dctr_after_move = has_trivial_destructor_after_move::value; + static const bool trivial_copy = dtl::is_trivially_copy_constructible::value; + static const bool nothrow_copy = dtl::is_nothrow_copy_constructible::value || trivial_copy; + static const bool trivial_assign = dtl::is_trivially_copy_assignable::value; + static const bool nothrow_assign = dtl::is_nothrow_copy_assignable::value || trivial_assign; +}; + + +template +struct vector_value_traits + : public vector_value_traits_base +{ + typedef vector_value_traits_base base_t; + //This is the anti-exception array destructor + //to deallocate values already constructed + typedef typename dtl::if_c + + ,dtl::scoped_destructor_n + >::type ArrayDestructor; + //This is the anti-exception array deallocator + typedef dtl::scoped_array_deallocator ArrayDeallocator; +}; + +//!This struct deallocates and allocated memory +template < class Allocator + , class StoredSizeType + , class AllocatorVersion = typename dtl::version::type + > +struct vector_alloc_holder + : public Allocator +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) + + public: + typedef Allocator allocator_type; + typedef StoredSizeType stored_size_type; + typedef boost::container::allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::pointer pointer; + typedef typename allocator_traits_type::size_type size_type; + typedef typename allocator_traits_type::value_type value_type; + + static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator) + { + (void)propagate_allocator; (void)p; (void)to_alloc; (void)from_alloc; + const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value || + !allocator_traits_type::storage_is_unpropagable(from_alloc, p); + return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(from_alloc, to_alloc)); + } + + static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator) + { + (void)propagate_allocator; (void)l_p; (void)r_p; (void)l_a; (void)r_a; + const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value || + !(allocator_traits_type::storage_is_unpropagable(l_a, l_p) || allocator_traits_type::storage_is_unpropagable(r_a, r_p)); + return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(l_a, r_a)); + } + + //Constructor, does not throw + vector_alloc_holder() + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : Allocator(), m_start(), m_size(), m_capacity() + {} + + //Constructor, does not throw + template + explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW + : Allocator(boost::forward(a)), m_start(), m_size(), m_capacity() + {} + + //Constructor, does not throw + template + vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) + : Allocator(boost::forward(a)) + , m_start() + //Size is initialized here so vector should only call uninitialized_xxx after this + , m_size(static_cast(initial_size)) + , m_capacity() + { + if(initial_size){ + pointer reuse = pointer(); + size_type final_cap = initial_size; + m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse); + m_capacity = static_cast(final_cap); + } + } + + //Constructor, does not throw + vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size) + : Allocator() + , m_start() + //Size is initialized here so vector should only call uninitialized_xxx after this + , m_size(static_cast(initial_size)) + , m_capacity() + { + if(initial_size){ + pointer reuse = pointer(); + size_type final_cap = initial_size; + m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse); + m_capacity = static_cast(final_cap); + } + } + + vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW + : Allocator(BOOST_MOVE_BASE(Allocator, holder)) + , m_start(holder.m_start) + , m_size(holder.m_size) + , m_capacity(holder.m_capacity) + { + holder.m_start = pointer(); + holder.m_size = holder.m_capacity = 0; + } + + vector_alloc_holder(initial_capacity_t, pointer p, size_type capacity, BOOST_RV_REF(vector_alloc_holder) holder) + : Allocator(BOOST_MOVE_BASE(Allocator, holder)) + , m_start(p) + , m_size(holder.m_size) + , m_capacity(static_cast(capacity)) + { + allocator_type &this_alloc = this->alloc(); + allocator_type &x_alloc = holder.alloc(); + if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){ + if(this->m_capacity){ + this->deallocate(this->m_start, this->m_capacity); + } + m_start = holder.m_start; + m_capacity = holder.m_capacity; + holder.m_start = pointer(); + holder.m_capacity = holder.m_size = 0; + } + else if(this->m_capacity < holder.m_size){ + size_type const n = holder.m_size; + pointer reuse = pointer(); + size_type final_cap = n; + m_start = this->allocation_command(allocate_new, n, final_cap, reuse); + m_capacity = static_cast(final_cap); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + } + } + + vector_alloc_holder(initial_capacity_t, pointer p, size_type n) + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : Allocator() + , m_start(p) + , m_size() + //n is guaranteed to fit into stored_size_type + , m_capacity(static_cast(n)) + {} + + template + vector_alloc_holder(initial_capacity_t, pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a) + : Allocator(::boost::forward(a)) + , m_start(p) + , m_size() + , m_capacity(n) + {} + + BOOST_CONTAINER_FORCEINLINE ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW + { + if(this->m_capacity){ + this->deallocate(this->m_start, this->m_capacity); + } + } + + BOOST_CONTAINER_FORCEINLINE pointer allocation_command(boost::container::allocation_type command, + size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) + { + typedef typename dtl::version::type alloc_version; + return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse); + } + + BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n) + { + const size_type max_alloc = allocator_traits_type::max_size(this->alloc()); + const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1); + if ( max < n ) + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + + return allocator_traits_type::allocate(this->alloc(), n); + } + + BOOST_CONTAINER_FORCEINLINE void deallocate(const pointer &p, size_type n) + { + allocator_traits_type::deallocate(this->alloc(), p, n); + } + + bool try_expand_fwd(size_type at_least) + { + //There is not enough memory, try to expand the old one + const size_type new_cap = this->capacity() + at_least; + size_type real_cap = new_cap; + pointer reuse = this->start(); + bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse); + //Check for forward expansion + if(success){ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->capacity(real_cap); + } + return success; + } + + template + size_type next_capacity(size_type additional_objects) const + { + BOOST_ASSERT(additional_objects > size_type(this->m_capacity - this->m_size)); + size_type max = allocator_traits_type::max_size(this->alloc()); + (clamp_by_stored_size_type)(max, stored_size_type()); + const size_type remaining_cap = max - size_type(this->m_capacity); + const size_type min_additional_cap = additional_objects - size_type(this->m_capacity - this->m_size); + + if ( remaining_cap < min_additional_cap ) + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + + return GrowthFactorType()( size_type(this->m_capacity), min_additional_cap, max); + } + + pointer m_start; + stored_size_type m_size; + stored_size_type m_capacity; + + void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW + { + boost::adl_move_swap(this->m_start, x.m_start); + boost::adl_move_swap(this->m_size, x.m_size); + boost::adl_move_swap(this->m_capacity, x.m_capacity); + } + + void steal_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW + { + this->m_start = x.m_start; + this->m_size = x.m_size; + this->m_capacity = x.m_capacity; + x.m_start = pointer(); + x.m_size = x.m_capacity = 0; + } + + BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE const pointer &start() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_start; } + BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_capacity; } + BOOST_CONTAINER_FORCEINLINE void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW + { m_start = p; } + BOOST_CONTAINER_FORCEINLINE void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT( c <= stored_size_type(-1)); m_capacity = c; } + + private: + void priv_first_allocation(size_type cap) + { + if(cap){ + pointer reuse = pointer(); + m_start = this->allocation_command(allocate_new, cap, cap, reuse); + m_capacity = cap; + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + } + } + + BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &, size_type) + {} + + template + BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &s, SomeStoredSizeType) + { + if (s >= SomeStoredSizeType(-1) ) + s = SomeStoredSizeType(-1); + } + + BOOST_CONTAINER_FORCEINLINE pointer priv_allocation_command(version_1, boost::container::allocation_type command, + size_type limit_size, + size_type &prefer_in_recvd_out_size, + pointer &reuse) + { + (void)command; + BOOST_ASSERT( (command & allocate_new)); + BOOST_ASSERT(!(command & nothrow_allocation)); + //First detect overflow on smaller stored_size_types + if (limit_size > stored_size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + pointer const p = this->allocate(prefer_in_recvd_out_size); + reuse = pointer(); + return p; + } + + pointer priv_allocation_command(version_2, boost::container::allocation_type command, + size_type limit_size, + size_type &prefer_in_recvd_out_size, + pointer &reuse) + { + //First detect overflow on smaller stored_size_types + if (limit_size > stored_size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + //Allocate memory + pointer p = this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); + //If after allocation prefer_in_recvd_out_size is not representable by stored_size_type, truncate it. + (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + return p; + } +}; + +//!This struct deallocates and allocated memory +template +struct vector_alloc_holder + : public Allocator +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) + + public: + typedef boost::container::allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::pointer pointer; + typedef typename allocator_traits_type::size_type size_type; + typedef typename allocator_traits_type::value_type value_type; + typedef StoredSizeType stored_size_type; + + template + friend struct vector_alloc_holder; + + //Constructor, does not throw + vector_alloc_holder() + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : Allocator(), m_size() + {} + + //Constructor, does not throw + template + explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW + : Allocator(boost::forward(a)), m_size() + {} + + //Constructor, does not throw + template + vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) + : Allocator(boost::forward(a)) + , m_size(initial_size) //Size is initialized here... + { + //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor + this->priv_first_allocation(initial_size); + } + + //Constructor, does not throw + vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size) + : Allocator() + , m_size(initial_size) //Size is initialized here... + { + //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor + this->priv_first_allocation(initial_size); + } + + vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) + : Allocator(BOOST_MOVE_BASE(Allocator, holder)) + , m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this + { + ::boost::container::uninitialized_move_alloc_n + (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start())); + } + + template + vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder BOOST_RV_REF_END holder) + : Allocator() + , m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort + { + //Different allocator type so we must check we have enough storage + const size_type n = holder.m_size; + this->priv_first_allocation(n); + ::boost::container::uninitialized_move_alloc_n + (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start())); + } + + BOOST_CONTAINER_FORCEINLINE void priv_first_allocation(size_type cap) + { + if(cap > Allocator::internal_capacity){ + throw_bad_alloc(); + } + } + + BOOST_CONTAINER_FORCEINLINE void deep_swap(vector_alloc_holder &x) + { + this->priv_deep_swap(x); + } + + template + void deep_swap(vector_alloc_holder &x) + { + if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){ + throw_bad_alloc(); + } + this->priv_deep_swap(x); + } + + BOOST_CONTAINER_FORCEINLINE void swap_resources(vector_alloc_holder &) BOOST_NOEXCEPT_OR_NOTHROW + { //Containers with version 0 allocators can't be moved without moving elements one by one + throw_bad_alloc(); + } + + + BOOST_CONTAINER_FORCEINLINE void steal_resources(vector_alloc_holder &) + { //Containers with version 0 allocators can't be moved without moving elements one by one + throw_bad_alloc(); + } + + BOOST_CONTAINER_FORCEINLINE Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE bool try_expand_fwd(size_type at_least) + { return !at_least; } + + BOOST_CONTAINER_FORCEINLINE pointer start() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_storage(); } + BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_capacity; } + stored_size_type m_size; + + private: + + template + void priv_deep_swap(vector_alloc_holder &x) + { + const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity; + value_type *const first_this = boost::movelib::to_raw_pointer(this->start()); + value_type *const first_x = boost::movelib::to_raw_pointer(x.start()); + + if(this->m_size < x.m_size){ + boost::container::deep_swap_alloc_n(this->alloc(), first_this, this->m_size, first_x, x.m_size); + } + else{ + boost::container::deep_swap_alloc_n(this->alloc(), first_x, x.m_size, first_this, this->m_size); + } + boost::adl_move_swap(this->m_size, x.m_size); + } +}; + +struct growth_factor_60; + +template +struct default_if_void +{ + typedef T type; +}; + +template +struct default_if_void +{ + typedef Default type; +}; + +template +struct get_vector_opt +{ + typedef vector_opt< typename default_if_void::type + , typename default_if_void::type + > type; +}; + +template +struct get_vector_opt +{ + typedef vector_opt type; +}; + + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! A vector is a sequence that supports random access to elements, constant +//! time insertion and removal of elements at the end, and linear time insertion +//! and removal of elements at the beginning or in the middle. The number of +//! elements in a vector may vary dynamically; memory management is automatic. +//! +//! \tparam T The type of object that is stored in the vector +//! \tparam Allocator The allocator used for all internal memory management +//! \tparam Options A type produced from \c boost::container::vector_options. +template ), class Options BOOST_CONTAINER_DOCONLY(= void) > +class vector +{ + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + typedef typename boost::container::allocator_traits::size_type alloc_size_type; + typedef typename get_vector_opt::type options_type; + typedef typename options_type::growth_factor_type growth_factor_type; + typedef typename options_type::stored_size_type stored_size_type; + typedef value_less value_less_t; + + //If provided the stored_size option must specify a type that is equal or a type that is smaller. + BOOST_STATIC_ASSERT( (sizeof(stored_size_type) < sizeof(alloc_size_type) || + dtl::is_same::value) ); + + typedef typename dtl::version::type alloc_version; + typedef boost::container::vector_alloc_holder alloc_holder_t; + alloc_holder_t m_holder; + typedef allocator_traits allocator_traits_type; + template + friend class vector; + + typedef typename allocator_traits_type::pointer pointer_impl; + typedef vec_iterator iterator_impl; + typedef vec_iterator const_iterator_impl; + + protected: + static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator) + { return alloc_holder_t::is_propagable_from(from_alloc, p, to_alloc, propagate_allocator); } + + static bool are_swap_propagable( const Allocator &l_a, pointer_impl l_p + , const Allocator &r_a, pointer_impl r_p, bool const propagate_allocator) + { return alloc_holder_t::are_swap_propagable(l_a, l_p, r_a, r_p, propagate_allocator); } + + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + public: + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + + typedef T value_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef Allocator allocator_type; + typedef Allocator stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; + typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + private: + BOOST_COPYABLE_AND_MOVABLE(vector) + typedef vector_value_traits value_traits; + typedef constant_iterator cvalue_iterator; + + protected: + + BOOST_CONTAINER_FORCEINLINE void steal_resources(vector &x) + { return this->m_holder.steal_resources(x.m_holder); } + + template + BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a) + : m_holder(initial_capacity_t(), initial_memory, capacity, ::boost::forward(a)) + {} + + BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity) + : m_holder(initial_capacity_t(), initial_memory, capacity) + {} + + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + public: + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// + + //! Effects: Constructs a vector taking the allocator as parameter. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : m_holder() + {} + + //! Effects: Constructs a vector taking the allocator as parameter. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + explicit vector(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW + : m_holder(a) + {} + + //! Effects: Constructs a vector and inserts n value initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's value initialization throws. + //! + //! Complexity: Linear to n. + explicit vector(size_type n) + : m_holder(vector_uninitialized_size, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_value_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n value initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's value initialization throws. + //! + //! Complexity: Linear to n. + explicit vector(size_type n, const allocator_type &a) + : m_holder(vector_uninitialized_size, a, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_value_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n default initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's default initialization throws. + //! + //! Complexity: Linear to n. + //! + //! Note: Non-standard extension + vector(size_type n, default_init_t) + : m_holder(vector_uninitialized_size, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_default_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n default initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's default initialization throws. + //! + //! Complexity: Linear to n. + //! + //! Note: Non-standard extension + vector(size_type n, default_init_t, const allocator_type &a) + : m_holder(vector_uninitialized_size, a, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_default_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector + //! and inserts n copies of value. + //! + //! Throws: If allocator_type's allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + vector(size_type n, const T& value) + : m_holder(vector_uninitialized_size, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_fill_alloc_n + (this->m_holder.alloc(), value, n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n copies of value. + //! + //! Throws: If allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + vector(size_type n, const T& value, const allocator_type& a) + : m_holder(vector_uninitialized_size, a, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_fill_alloc_n + (this->m_holder.alloc(), value, n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector + //! and inserts a copy of the range [first, last) in the vector. + //! + //! Throws: If allocator_type's allocation + //! throws or T's constructor taking a dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). + template + vector(InIt first, InIt last + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c + < dtl::is_convertible::value + BOOST_MOVE_I dtl::nat >::type * = 0) + ) + : m_holder() + { this->assign(first, last); } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts a copy of the range [first, last) in the vector. + //! + //! Throws: If allocator_type's allocation + //! throws or T's constructor taking a dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). + template + vector(InIt first, InIt last, const allocator_type& a + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c + < dtl::is_convertible::value + BOOST_MOVE_I dtl::nat >::type * = 0) + ) + : m_holder(a) + { this->assign(first, last); } + + //! Effects: Copy constructs a vector. + //! + //! Postcondition: x == *this. + //! + //! Throws: If allocator_type's allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to the elements x contains. + vector(const vector &x) + : m_holder( vector_uninitialized_size + , allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc()) + , x.size()) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += x.size() != 0; + #endif + ::boost::container::uninitialized_copy_alloc_n + ( this->m_holder.alloc(), x.priv_raw_begin() + , x.size(), this->priv_raw_begin()); + } + + //! Effects: Move constructor. Moves x's resources to *this. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + vector(BOOST_RV_REF(vector) x) BOOST_NOEXCEPT_OR_NOTHROW + : m_holder(boost::move(x.m_holder)) + { BOOST_STATIC_ASSERT((!allocator_traits_type::is_partially_propagable::value)); } + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts a copy of the range [il.begin(), il.last()) in the vector + //! + //! Throws: If T's constructor taking a dereferenced initializer_list iterator throws. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + vector(std::initializer_list il, const allocator_type& a = allocator_type()) + : m_holder(a) + { + this->assign(il.begin(), il.end()); + } + #endif + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Move constructor. Moves x's resources to *this. + //! + //! Throws: If T's move constructor or allocation throws + //! + //! Complexity: Linear. + //! + //! Note: Non-standard extension to support static_vector + template + vector(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x + , typename dtl::enable_if_c + < dtl::is_version::value>::type * = 0 + ) + : m_holder(boost::move(x.m_holder)) + {} + + #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Copy constructs a vector using the specified allocator. + //! + //! Postcondition: x == *this. + //! + //! Throws: If allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to the elements x contains. + vector(const vector &x, const allocator_type &a) + : m_holder(vector_uninitialized_size, a, x.size()) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += x.size() != 0; + #endif + ::boost::container::uninitialized_copy_alloc_n_source + ( this->m_holder.alloc(), x.priv_raw_begin() + , x.size(), this->priv_raw_begin()); + } + + //! Effects: Move constructor using the specified allocator. + //! Moves x's resources to *this if a == allocator_type(). + //! Otherwise copies values from x to *this. + //! + //! Throws: If allocation or T's copy constructor throws. + //! + //! Complexity: Constant if a == x.get_allocator(), linear otherwise. + vector(BOOST_RV_REF(vector) x, const allocator_type &a) + : m_holder( vector_uninitialized_size, a + , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size() + ) + { + if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true)){ + this->m_holder.steal_resources(x.m_holder); + } + else{ + const size_type n = x.size(); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + ::boost::container::uninitialized_move_alloc_n_source + ( this->m_holder.alloc(), x.priv_raw_begin() + , n, this->priv_raw_begin()); + } + } + + //! Effects: Destroys the vector. All stored values are destroyed + //! and used memory is deallocated. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements. + ~vector() BOOST_NOEXCEPT_OR_NOTHROW + { + boost::container::destroy_alloc_n + (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size); + //vector_alloc_holder deallocates the data + } + + //! Effects: Makes *this contain the same elements as x. + //! + //! Postcondition: this->size() == x.size(). *this contains a copy + //! of each of x's elements. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to the number of elements in x. + BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x) + { + if (&x != this){ + this->priv_copy_assign(x); + } + return *this; + } + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Make *this container contains elements from il. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + BOOST_CONTAINER_FORCEINLINE vector& operator=(std::initializer_list il) + { + this->assign(il.begin(), il.end()); + return *this; + } + #endif + + //! Effects: Move assignment. All x's values are transferred to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If allocator_traits_type::propagate_on_container_move_assignment + //! is false and (allocation throws or value_type's move constructor throws) + //! + //! Complexity: Constant if allocator_traits_type:: + //! propagate_on_container_move_assignment is true or + //! this->get>allocator() == x.get_allocator(). Linear otherwise. + BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_RV_REF(vector) x) + BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value + || allocator_traits_type::is_always_equal::value) + { + BOOST_ASSERT(&x != this); + this->priv_move_assign(boost::move(x)); + return *this; + } + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Move assignment. All x's values are transferred to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If move constructor/assignment of T throws or allocation throws + //! + //! Complexity: Linear. + //! + //! Note: Non-standard extension to support static_vector + template + BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and + < vector& + , dtl::is_version + , dtl::is_different + >::type + operator=(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x) + { + this->priv_move_assign(boost::move(x)); + return *this; + } + + //! Effects: Copy assignment. All x's values are copied to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If move constructor/assignment of T throws or allocation throws + //! + //! Complexity: Linear. + //! + //! Note: Non-standard extension to support static_vector + template + BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and + < vector& + , dtl::is_version + , dtl::is_different + >::type + operator=(const vector &x) + { + this->priv_copy_assign(x); + return *this; + } + + #endif + + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment or + //! T's constructor/assignment from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(InIt first, InIt last + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or + < void + BOOST_MOVE_I dtl::is_convertible + BOOST_MOVE_I dtl::and_ + < dtl::is_different + BOOST_MOVE_I dtl::is_not_input_iterator + > + >::type * = 0) + ) + { + //Overwrite all elements we can from [first, last) + iterator cur = this->begin(); + const iterator end_it = this->end(); + for ( ; first != last && cur != end_it; ++cur, ++first){ + *cur = *first; + } + + if (first == last){ + //There are no more elements in the sequence, erase remaining + T* const end_pos = this->priv_raw_end(); + const size_type n = static_cast(end_pos - boost::movelib::iterator_to_raw_pointer(cur)); + this->priv_destroy_last_n(n); + } + else{ + //There are more elements in the range, insert the remaining ones + this->insert(this->cend(), first, last); + } + } + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Assigns the the range [il.begin(), il.end()) to *this. + //! + //! Throws: If memory allocation throws or + //! T's constructor from dereferencing iniializer_list iterator throws. + //! + BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il) + { + this->assign(il.begin(), il.end()); + } + #endif + + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment or + //! T's constructor/assignment from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(FwdIt first, FwdIt last + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or + < void + BOOST_MOVE_I dtl::is_same + BOOST_MOVE_I dtl::is_convertible + BOOST_MOVE_I dtl::is_input_iterator + >::type * = 0) + ) + { + //For Fwd iterators the standard only requires EmplaceConstructible and assignable from *first + //so we can't do any backwards allocation + const size_type input_sz = static_cast(boost::container::iterator_distance(first, last)); + const size_type old_capacity = this->capacity(); + if(input_sz > old_capacity){ //If input range is too big, we need to reallocate + size_type real_cap = 0; + pointer reuse(this->m_holder.start()); + pointer const ret(this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, real_cap = input_sz, reuse)); + if(!reuse){ //New allocation, just emplace new values + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + pointer const old_p = this->m_holder.start(); + if(old_p){ + this->priv_destroy_all(); + this->m_holder.deallocate(old_p, old_capacity); + } + this->m_holder.start(ret); + this->m_holder.capacity(real_cap); + this->m_holder.m_size = 0; + this->priv_uninitialized_construct_at_end(first, last); + return; + } + else{ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->m_holder.capacity(real_cap); + //Forward expansion, use assignment + back deletion/construction that comes later + } + } + //Overwrite all elements we can from [first, last) + iterator cur = this->begin(); + const iterator end_it = this->end(); + for ( ; first != last && cur != end_it; ++cur, ++first){ + *cur = *first; + } + + if (first == last){ + //There are no more elements in the sequence, erase remaining + this->priv_destroy_last_n(this->size() - input_sz); + } + else{ + //Uninitialized construct at end the remaining range + this->priv_uninitialized_construct_at_end(first, last); + } + } + + //! Effects: Assigns the n copies of val to *this. + //! + //! Throws: If memory allocation throws or + //! T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to n. + BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const value_type& val) + { this->assign(cvalue_iterator(val, n), cvalue_iterator()); } + + //! Effects: Returns a copy of the internal allocator. + //! + //! Throws: If allocator's copy constructor throws. + //! + //! Complexity: Constant. + allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.alloc(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.alloc(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.alloc(); } + + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// + + //! Effects: Returns an iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW + { return iterator(this->m_holder.start()); } + + //! Effects: Returns a const_iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_iterator(this->m_holder.start()); } + + //! Effects: Returns an iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW + { return iterator(this->m_holder.start() + this->m_holder.m_size); } + + //! Effects: Returns a const_iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW + { return reverse_iterator(this->end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW + { return reverse_iterator(this->begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->crend(); } + + //! Effects: Returns a const_iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_iterator(this->m_holder.start()); } + + //! Effects: Returns a const_iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_iterator(this->m_holder.start() + this->m_holder.m_size); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_reverse_iterator(this->end());} + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_reverse_iterator(this->begin()); } + + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + + //! Effects: Returns true if the vector contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW + { return !this->m_holder.m_size; } + + //! Effects: Returns the number of the elements contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.m_size; } + + //! Effects: Returns the largest possible size of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + { return allocator_traits_type::max_size(this->m_holder.alloc()); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are value initialized. + //! + //! Throws: If memory allocation throws, or T's copy/move or value initialization throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size) + { this->priv_resize(new_size, value_init); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are default initialized. + //! + //! Throws: If memory allocation throws, or T's copy/move or default initialization throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + //! + //! Note: Non-standard extension + void resize(size_type new_size, default_init_t) + { this->priv_resize(new_size, default_init); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are copy constructed from x. + //! + //! Throws: If memory allocation throws, or T's copy/move constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type new_size, const T& x) + { this->priv_resize(new_size, x); } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy/move constructor throws. + BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_cap) + { + if (this->capacity() < new_cap){ + this->priv_reserve_no_capacity(new_cap, alloc_version()); + } + } + + //! Effects: Tries to deallocate the excess of memory created + //! with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy/move constructor throws. + //! + //! Complexity: Linear to size(). + BOOST_CONTAINER_FORCEINLINE void shrink_to_fit() + { this->priv_shrink_to_fit(alloc_version()); } + + ////////////////////////////////////////////// + // + // element access + // + ////////////////////////////////////////////// + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference front() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return *this->m_holder.start(); + } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return *this->m_holder.start(); + } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the last + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference back() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return this->m_holder.start()[this->m_holder.m_size - 1]; + } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the last + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return this->m_holder.start()[this->m_holder.m_size - 1]; + } + + //! Requires: size() > n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size > n); + return this->m_holder.start()[n]; + } + + //! Requires: size() > n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size > n); + return this->m_holder.start()[n]; + } + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size >= n); + return iterator(this->m_holder.start()+n); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns a const_iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size >= n); + return const_iterator(this->m_holder.start()+n); + } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW + { + //Range check assert done in priv_index_of + return this->priv_index_of(vector_iterator_get_ptr(p)); + } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW + { + //Range check assert done in priv_index_of + return this->priv_index_of(vector_iterator_get_ptr(p)); + } + + //! Requires: size() > n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + reference at(size_type n) + { + this->priv_throw_if_out_of_range(n); + return this->m_holder.start()[n]; + } + + //! Requires: size() > n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + const_reference at(size_type n) const + { + this->priv_throw_if_out_of_range(n); + return this->m_holder.start()[n]; + } + + ////////////////////////////////////////////// + // + // data access + // + ////////////////////////////////////////////// + + //! Returns: A pointer such that [data(),data() + size()) is a valid range. + //! For a non-empty vector, data() == &front(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + T* data() BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_raw_begin(); } + + //! Returns: A pointer such that [data(),data() + size()) is a valid range. + //! For a non-empty vector, data() == &front(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const T * data() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_raw_begin(); } + + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... in the end of the vector. + //! + //! Returns: A reference to the created object. + //! + //! Throws: If memory allocation throws or the in-place constructor throws or + //! T's copy/move constructor throws. + //! + //! Complexity: Amortized constant time. + template + BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_FWD_REF(Args)...args) + { + if (BOOST_LIKELY(this->room_enough())){ + //There is more memory, just construct a new object at the end + T* const p = this->priv_raw_end(); + allocator_traits_type::construct(this->m_holder.alloc(), p, ::boost::forward(args)...); + ++this->m_holder.m_size; + return *p; + } + else{ + typedef dtl::insert_emplace_proxy type; + return *this->priv_forward_range_insert_no_capacity + (this->back_ptr(), 1, type(::boost::forward(args)...), alloc_version()); + } + } + + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... in the end of the vector. + //! + //! Throws: If the in-place constructor throws. + //! + //! Complexity: Constant time. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_FWD_REF(Args)...args) + { + const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u)); + if (BOOST_LIKELY(is_room_enough)){ + //There is more memory, just construct a new object at the end + allocator_traits_type::construct(this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward(args)...); + ++this->m_holder.m_size; + } + return is_room_enough; + } + + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... before position + //! + //! Throws: If memory allocation throws or the in-place constructor throws or + //! T's copy/move constructor/assignment throws. + //! + //! Complexity: If position is end(), amortized constant time + //! Linear time otherwise. + template + iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args) + { + BOOST_ASSERT(this->priv_in_range_or_end(position)); + //Just call more general insert(pos, size, value) and return iterator + typedef dtl::insert_emplace_proxy type; + return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1 + , type(::boost::forward(args)...)); + } + + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + #define BOOST_CONTAINER_VECTOR_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\ + {\ + if (BOOST_LIKELY(this->room_enough())){\ + T* const p = this->priv_raw_end();\ + allocator_traits_type::construct (this->m_holder.alloc()\ + , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + ++this->m_holder.m_size;\ + return *p;\ + }\ + else{\ + typedef dtl::insert_emplace_proxy_arg##N type;\ + return *this->priv_forward_range_insert_no_capacity\ + ( this->back_ptr(), 1, type(BOOST_MOVE_FWD##N), alloc_version());\ + }\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_MOVE_UREF##N)\ + {\ + const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));\ + if (BOOST_LIKELY(is_room_enough)){\ + allocator_traits_type::construct (this->m_holder.alloc()\ + , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + ++this->m_holder.m_size;\ + }\ + return is_room_enough;\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + BOOST_ASSERT(this->priv_in_range_or_end(pos));\ + typedef dtl::insert_emplace_proxy_arg##N type;\ + return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), 1, type(BOOST_MOVE_FWD##N));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE) + #undef BOOST_CONTAINER_VECTOR_EMPLACE_CODE + + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts a copy of x at the end of the vector. + //! + //! Throws: If memory allocation throws or + //! T's copy/move constructor throws. + //! + //! Complexity: Amortized constant time. + void push_back(const T &x); + + //! Effects: Constructs a new element in the end of the vector + //! and moves the resources of x to this new element. + //! + //! Throws: If memory allocation throws or + //! T's copy/move constructor throws. + //! + //! Complexity: Amortized constant time. + void push_back(T &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a copy of x before position. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: If position is end(), amortized constant time + //! Linear time otherwise. + iterator insert(const_iterator position, const T &x); + + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a new element before position with x's resources. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: If position is end(), amortized constant time + //! Linear time otherwise. + iterator insert(const_iterator position, T &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) + #endif + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert n copies of x before pos. + //! + //! Returns: an iterator to the first inserted element or p if n is 0. + //! + //! Throws: If memory allocation throws or T's copy/move constructor throws. + //! + //! Complexity: Linear to n. + iterator insert(const_iterator p, size_type n, const T& x) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + dtl::insert_n_copies_proxy proxy(x); + return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [first, last) range before pos. + //! + //! Returns: an iterator to the first inserted element or pos if first == last. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to boost::container::iterator_distance [first, last). + template + iterator insert(const_iterator pos, InIt first, InIt last + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + , typename dtl::disable_if_or + < void + , dtl::is_convertible + , dtl::is_not_input_iterator + >::type * = 0 + #endif + ) + { + BOOST_ASSERT(this->priv_in_range_or_end(pos)); + const size_type n_pos = pos - this->cbegin(); + iterator it(vector_iterator_get_ptr(pos)); + for(;first != last; ++first){ + it = this->emplace(it, *first); + ++it; + } + return iterator(this->m_holder.start() + n_pos); + } + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + template + iterator insert(const_iterator pos, FwdIt first, FwdIt last + , typename dtl::disable_if_or + < void + , dtl::is_convertible + , dtl::is_input_iterator + >::type * = 0 + ) + { + BOOST_ASSERT(this->priv_in_range_or_end(pos)); + dtl::insert_range_proxy proxy(first); + return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy); + } + #endif + + //! Requires: p must be a valid iterator of *this. num, must + //! be equal to boost::container::iterator_distance(first, last) + //! + //! Effects: Insert a copy of the [first, last) range before pos. + //! + //! Returns: an iterator to the first inserted element or pos if first == last. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to boost::container::iterator_distance [first, last). + //! + //! Note: This function avoids a linear operation to calculate boost::container::iterator_distance[first, last) + //! for forward and bidirectional iterators, and a one by one insertion for input iterators. This is a + //! a non-standard extension. + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + template + iterator insert(const_iterator pos, size_type num, InIt first, InIt last) + { + BOOST_ASSERT(this->priv_in_range_or_end(pos)); + BOOST_ASSERT(dtl::is_input_iterator::value || + num == static_cast(boost::container::iterator_distance(first, last))); + (void)last; + dtl::insert_range_proxy proxy(first); + return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy); + } + #endif + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [il.begin(), il.end()) range before position. + //! + //! Returns: an iterator to the first inserted element or position if first == last. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + iterator insert(const_iterator position, std::initializer_list il) + { + //Assertion done in insert() + return this->insert(position, il.begin(), il.end()); + } + #endif + + //! Effects: Removes the last element from the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + void pop_back() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + //Destroy last element + this->priv_destroy_last(); + } + + //! Effects: Erases the element at position pos. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements between pos and the + //! last element. Constant if pos is the last element. + iterator erase(const_iterator position) + { + BOOST_ASSERT(this->priv_in_range(position)); + const pointer p = vector_iterator_get_ptr(position); + T *const pos_ptr = boost::movelib::to_raw_pointer(p); + T *const beg_ptr = this->priv_raw_begin(); + T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr); + //Move elements forward and destroy last + this->priv_destroy_last(pos_ptr != new_end_ptr); + return iterator(p); + } + + //! Effects: Erases the elements pointed by [first, last). + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the distance between first and last + //! plus linear to the elements between pos and the last element. + iterator erase(const_iterator first, const_iterator last) + { + BOOST_ASSERT(first == last || + (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last))); + if (first != last){ + T* const old_end_ptr = this->priv_raw_end(); + T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first)); + T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last)); + T* const ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr)); + this->priv_destroy_last_n(old_end_ptr - ptr); + } + return iterator(vector_iterator_get_ptr(first)); + } + + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE void swap(vector& x) + BOOST_NOEXCEPT_IF( ((allocator_traits_type::propagate_on_container_swap::value + || allocator_traits_type::is_always_equal::value) && + !dtl::is_version::value)) + { + this->priv_swap(x, dtl::bool_::value>()); + } + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear + //! + //! Note: Non-standard extension to support static_vector + template + BOOST_CONTAINER_FORCEINLINE void swap(vector & x + , typename dtl::enable_if_and + < void + , dtl::is_version + , dtl::is_different + >::type * = 0 + ) + { this->m_holder.deep_swap(x.m_holder); } + + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + //! Effects: Erases all the elements of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW + { this->priv_destroy_all(); } + + //! Effects: Returns true if x and y are equal + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator==(const vector& x, const vector& y) + { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } + + //! Effects: Returns true if x and y are unequal + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const vector& x, const vector& y) + { return !(x == y); } + + //! Effects: Returns true if x is less than y + //! + //! Complexity: Linear to the number of elements in the container. + friend bool operator<(const vector& x, const vector& y) + { + const_iterator first1(x.cbegin()), first2(y.cbegin()); + const const_iterator last1(x.cend()), last2(y.cend()); + for ( ; (first1 != last1) && (first2 != last2); ++first1, ++first2 ) { + if (*first1 < *first2) return true; + if (*first2 < *first1) return false; + } + return (first1 == last1) && (first2 != last2); + } + + //! Effects: Returns true if x is greater than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator>(const vector& x, const vector& y) + { return y < x; } + + //! Effects: Returns true if x is equal or less than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const vector& x, const vector& y) + { return !(y < x); } + + //! Effects: Returns true if x is equal or greater than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const vector& x, const vector& y) + { return !(x < y); } + + //! Effects: x.swap(y) + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE friend void swap(vector& x, vector& y) + { x.swap(y); } + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory + //! (memory expansion) that will not invalidate iterators. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy/move constructor throws. + //! + //! Note: Non-standard extension. + bool stable_reserve(size_type new_cap) + { + const size_type cp = this->capacity(); + return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(new_cap - cp)); + } + + //Absolutely experimental. This function might change, disappear or simply crash! + template + BOOST_CONTAINER_FORCEINLINE void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it) + { + typedef vector_insert_ordered_cursor inserter_t; + return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it)); + } + + template + BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last) + { this->merge(first, last, value_less_t()); } + + template + BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last, Compare comp) + { + size_type const s = this->size(); + size_type const c = this->capacity(); + size_type n = 0; + size_type const free_cap = c - s; + //If not input iterator and new elements don't fit in the remaining capacity, merge in new buffer + if(!dtl::is_input_iterator::value && + free_cap < (n = static_cast(boost::container::iterator_distance(first, last)))){ + this->priv_merge_in_new_buffer(first, n, comp, alloc_version()); + } + else{ + iterator pos(this->insert(this->cend(), first, last)); + T *const raw_beg = this->priv_raw_begin(); + T *const raw_end = this->priv_raw_end(); + T *const raw_pos = raw_beg + s; + boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_cap - n); + } + } + + template + BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last) + { this->merge_unique(first, last, value_less_t()); } + + template + BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last, Compare comp) + { + size_type const s = this->size(); + this->priv_set_difference_back(first, last, comp); + T *const raw_beg = this->priv_raw_begin(); + T *const raw_end = this->priv_raw_end(); + T *raw_pos = raw_beg + s; + boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size()); + } + + private: + template + void priv_insert_ordered_at(const size_type element_count, PositionValue position_value) + { + const size_type old_size_pos = this->size(); + this->reserve(old_size_pos + element_count); + T* const begin_ptr = this->priv_raw_begin(); + size_type insertions_left = element_count; + size_type prev_pos = old_size_pos; + size_type old_hole_size = element_count; + + //Exception rollback. If any copy throws before the hole is filled, values + //already inserted/copied at the end of the buffer will be destroyed. + typename value_traits::ArrayDestructor past_hole_values_destroyer + (begin_ptr + old_size_pos + element_count, this->m_holder.alloc(), size_type(0u)); + //Loop for each insertion backwards, first moving the elements after the insertion point, + //then inserting the element. + while(insertions_left){ + --position_value; + size_type const pos = position_value.get_pos(); + BOOST_ASSERT(pos != size_type(-1) && pos <= old_size_pos && pos <= prev_pos); + //If needed shift the range after the insertion point and the previous insertion point. + //Function will take care if the shift crosses the size() boundary, using copy/move + //or uninitialized copy/move if necessary. + size_type new_hole_size = (pos != prev_pos) + ? priv_insert_ordered_at_shift_range(pos, prev_pos, this->size(), insertions_left) + : old_hole_size + ; + if(new_hole_size){ + //The hole was reduced by priv_insert_ordered_at_shift_range so expand exception rollback range backwards + past_hole_values_destroyer.increment_size_backwards(prev_pos - pos); + //Insert the new value in the hole + allocator_traits_type::construct(this->m_holder.alloc(), begin_ptr + pos + insertions_left - 1, position_value.get_val()); + if(--new_hole_size){ + //The hole was reduced by the new insertion by one + past_hole_values_destroyer.increment_size_backwards(size_type(1u)); + } + else{ + //Hole was just filled, disable exception rollback and change vector size + past_hole_values_destroyer.release(); + this->m_holder.m_size += element_count; + } + } + else{ + if(old_hole_size){ + //Hole was just filled by priv_insert_ordered_at_shift_range, disable exception rollback and change vector size + past_hole_values_destroyer.release(); + this->m_holder.m_size += element_count; + } + //Insert the new value in the already constructed range + begin_ptr[pos + insertions_left - 1] = position_value.get_val(); + } + --insertions_left; + old_hole_size = new_hole_size; + prev_pos = pos; + } + } + + template + void priv_set_difference_back(InputIt first1, InputIt last1, Compare comp) + { + T * old_first2 = this->priv_raw_begin(); + T * first2 = old_first2; + T * last2 = this->priv_raw_end(); + + while (first1 != last1) { + if (first2 == last2){ + this->insert(this->cend(), first1, last1); + return; + } + + if (comp(*first1, *first2)) { + this->emplace_back(*first1); + //Reallocation happened, update range + T * const raw_begin = this->priv_raw_begin(); + if(old_first2 != raw_begin){ + first2 = raw_begin + (first2 - old_first2); + last2 = first2 + (last2 - old_first2); + old_first2 = raw_begin; + } + + ++first1; + } + else { + if (!comp(*first2, *first1)) { + ++first1; + } + ++first2; + } + } + } + + template + BOOST_CONTAINER_FORCEINLINE void priv_merge_in_new_buffer(FwdIt, size_type, Compare, version_0) + { + throw_bad_alloc(); + } + + template + void priv_merge_in_new_buffer(FwdIt first, size_type n, Compare comp, Version) + { + size_type const new_size = this->size() + n; + size_type new_cap = new_size; + pointer p = pointer(); + pointer const new_storage = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p); + + BOOST_ASSERT((new_cap >= this->size() ) && (new_cap - this->size()) >= n); + allocator_type &a = this->m_holder.alloc(); + typename value_traits::ArrayDeallocator new_buffer_deallocator(new_storage, a, new_cap); + typename value_traits::ArrayDestructor new_values_destroyer(new_storage, a, 0u); + T* pbeg = this->priv_raw_begin(); + size_type const old_size = this->size(); + T* const pend = pbeg + old_size; + T* d_first = boost::movelib::to_raw_pointer(new_storage); + size_type added = n; + //Merge in new buffer loop + while(1){ + if(!n) { + ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pbeg, pend, d_first); + break; + } + else if(pbeg == pend) { + ::boost::container::uninitialized_move_alloc_n(this->m_holder.alloc(), first, n, d_first); + break; + } + //maintain stability moving external values only if they are strictly less + else if(comp(*first, *pbeg)) { + allocator_traits_type::construct( this->m_holder.alloc(), d_first, *first ); + new_values_destroyer.increment_size(1u); + ++first; + --n; + ++d_first; + } + else{ + allocator_traits_type::construct( this->m_holder.alloc(), d_first, boost::move(*pbeg) ); + new_values_destroyer.increment_size(1u); + ++pbeg; + ++d_first; + } + } + + //Nothrow operations + pointer const old_p = this->m_holder.start(); + size_type const old_cap = this->m_holder.capacity(); + boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size); + this->m_holder.deallocate(old_p, old_cap); + this->m_holder.m_size = old_size + added; + this->m_holder.start(new_storage); + this->m_holder.capacity(new_cap); + new_buffer_deallocator.release(); + new_values_destroyer.release(); + } + + BOOST_CONTAINER_FORCEINLINE bool room_enough() const + { return this->m_holder.m_size < this->m_holder.capacity(); } + + BOOST_CONTAINER_FORCEINLINE pointer back_ptr() const + { return this->m_holder.start() + this->m_holder.m_size; } + + size_type priv_index_of(pointer p) const + { + BOOST_ASSERT(this->m_holder.start() <= p); + BOOST_ASSERT(p <= (this->m_holder.start()+this->size())); + return static_cast(p - this->m_holder.start()); + } + + template + void priv_move_assign(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x + , typename dtl::enable_if_c + < dtl::is_version::value >::type * = 0) + { + if(!dtl::is_same::value && + this->capacity() < x.size()){ + throw_bad_alloc(); + } + T* const this_start = this->priv_raw_begin(); + T* const other_start = x.priv_raw_begin(); + const size_type this_sz = m_holder.m_size; + const size_type other_sz = static_cast(x.m_holder.m_size); + boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz); + this->m_holder.m_size = other_sz; + } + + template + void priv_move_assign(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x + , typename dtl::disable_if_or + < void + , dtl::is_version + , dtl::is_different + >::type * = 0) + { + //for move assignment, no aliasing (&x != this) is assummed. + BOOST_ASSERT(this != &x); + allocator_type &this_alloc = this->m_holder.alloc(); + allocator_type &x_alloc = x.m_holder.alloc(); + const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value; + + const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc); + const bool is_propagable_from_t = is_propagable_from(this_alloc, m_holder.start(), x_alloc, propagate_alloc); + const bool are_both_propagable = is_propagable_from_x && is_propagable_from_t; + + //Resources can be transferred if both allocators are + //going to be equal after this function (either propagated or already equal) + if(are_both_propagable){ + //Destroy objects but retain memory in case x reuses it in the future + this->clear(); + this->m_holder.swap_resources(x.m_holder); + } + else if(is_propagable_from_x){ + this->clear(); + this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity); + this->m_holder.steal_resources(x.m_holder); + } + //Else do a one by one move + else{ + this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin())) + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end() )) + ); + } + //Move allocator if needed + dtl::move_alloc(this_alloc, x_alloc, dtl::bool_()); + } + + template + void priv_copy_assign(const vector &x + , typename dtl::enable_if_c + < dtl::is_version::value >::type * = 0) + { + if(!dtl::is_same::value && + this->capacity() < x.size()){ + throw_bad_alloc(); + } + T* const this_start = this->priv_raw_begin(); + T* const other_start = x.priv_raw_begin(); + const size_type this_sz = m_holder.m_size; + const size_type other_sz = static_cast(x.m_holder.m_size); + boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz); + this->m_holder.m_size = other_sz; + } + + template + typename dtl::disable_if_or + < void + , dtl::is_version + , dtl::is_different + >::type + priv_copy_assign(const vector &x) + { + allocator_type &this_alloc = this->m_holder.alloc(); + const allocator_type &x_alloc = x.m_holder.alloc(); + dtl::bool_ flag; + if(flag && this_alloc != x_alloc){ + this->clear(); + this->shrink_to_fit(); + } + dtl::assign_alloc(this_alloc, x_alloc, flag); + this->assign( x.priv_raw_begin(), x.priv_raw_end() ); + } + + template //Template it to avoid it in explicit instantiations + void priv_swap(Vector &x, dtl::true_type) //version_0 + { this->m_holder.deep_swap(x.m_holder); } + + template //Template it to avoid it in explicit instantiations + void priv_swap(Vector &x, dtl::false_type) //version_N + { + const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value; + if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start() + , x.get_stored_allocator(), x.m_holder.start(), propagate_alloc)){ + //Just swap internals + this->m_holder.swap_resources(x.m_holder); + } + else{ + //Else swap element by element... + bool const t_smaller = this->size() < x.size(); + vector &sml = t_smaller ? *this : x; + vector &big = t_smaller ? x : *this; + + size_type const common_elements = sml.size(); + for(size_type i = 0; i != common_elements; ++i){ + boost::adl_move_swap(sml[i], big[i]); + } + //... and move-insert the remaining range + sml.insert( sml.cend() + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements))) + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end())) + ); + //Destroy remaining elements + big.erase(big.nth(common_elements), big.cend()); + } + //And now swap the allocator + dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), dtl::bool_()); + } + + void priv_reserve_no_capacity(size_type, version_0) + { throw_bad_alloc(); } + + dtl::insert_range_proxy, T*> priv_dummy_empty_proxy() + { + return dtl::insert_range_proxy, T*> + (::boost::make_move_iterator((T *)0)); + } + + void priv_reserve_no_capacity(size_type new_cap, version_1) + { + //There is not enough memory, allocate a new buffer + //Pass the hint so that allocators can take advantage of this. + pointer const p = this->m_holder.allocate(new_cap); + //We will reuse insert code, so create a dummy input iterator + this->priv_forward_range_insert_new_allocation + ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy()); + } + + void priv_reserve_no_capacity(size_type new_cap, version_2) + { + //There is not enough memory, allocate a new + //buffer or expand the old one. + bool same_buffer_start; + size_type real_cap = 0; + pointer reuse(this->m_holder.start()); + pointer const ret(this->m_holder.allocation_command(allocate_new | expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse)); + + //Check for forward expansion + same_buffer_start = reuse && this->m_holder.start() == ret; + if(same_buffer_start){ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->m_holder.capacity(real_cap); + } + else{ //If there is no forward expansion, move objects, we will reuse insertion code + T * const new_mem = boost::movelib::to_raw_pointer(ret); + T * const ins_pos = this->priv_raw_end(); + if(reuse){ //Backwards (and possibly forward) expansion + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_bwd; + #endif + this->priv_forward_range_insert_expand_backwards + ( new_mem , real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); + } + else{ //New buffer + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_forward_range_insert_new_allocation + ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); + } + } + } + + void priv_destroy_last(const bool moved = false) BOOST_NOEXCEPT_OR_NOTHROW + { + (void)moved; + const bool skip_destructor = value_traits::trivial_dctr || (value_traits::trivial_dctr_after_move && moved); + if(!skip_destructor){ + value_type* const p = this->priv_raw_end() - 1; + allocator_traits_type::destroy(this->get_stored_allocator(), p); + } + --this->m_holder.m_size; + } + + void priv_destroy_last_n(const size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(n <= this->m_holder.m_size); + if(!value_traits::trivial_dctr){ + T* const destroy_pos = this->priv_raw_begin() + (this->m_holder.m_size-n); + boost::container::destroy_alloc_n(this->get_stored_allocator(), destroy_pos, n); + } + this->m_holder.m_size -= n; + } + + template + void priv_uninitialized_construct_at_end(InpIt first, InpIt last) + { + T* const old_end_pos = this->priv_raw_end(); + T* const new_end_pos = boost::container::uninitialized_copy_alloc(this->m_holder.alloc(), first, last, old_end_pos); + this->m_holder.m_size += new_end_pos - old_end_pos; + } + + void priv_destroy_all() BOOST_NOEXCEPT_OR_NOTHROW + { + boost::container::destroy_alloc_n + (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size); + this->m_holder.m_size = 0; + } + + template + iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + return this->priv_forward_range_insert + ( vector_iterator_get_ptr(p), 1, dtl::get_insert_value_proxy(::boost::forward(x))); + } + + dtl::insert_copy_proxy priv_single_insert_proxy(const T &x) + { return dtl::insert_copy_proxy (x); } + + dtl::insert_move_proxy priv_single_insert_proxy(BOOST_RV_REF(T) x) + { return dtl::insert_move_proxy (x); } + + template + void priv_push_back(BOOST_FWD_REF(U) u) + { + if (BOOST_LIKELY(this->room_enough())){ + //There is more memory, just construct a new object at the end + allocator_traits_type::construct + ( this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward(u) ); + ++this->m_holder.m_size; + } + else{ + this->priv_forward_range_insert_no_capacity + ( this->back_ptr(), 1 + , this->priv_single_insert_proxy(::boost::forward(u)), alloc_version()); + } + } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_n_copies_proxy priv_resize_proxy(const T &x) + { return dtl::insert_n_copies_proxy(x); } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_default_initialized_n_proxy priv_resize_proxy(default_init_t) + { return dtl::insert_default_initialized_n_proxy(); } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_value_initialized_n_proxy priv_resize_proxy(value_init_t) + { return dtl::insert_value_initialized_n_proxy(); } + + template + void priv_resize(size_type new_size, const U& u) + { + const size_type sz = this->size(); + if (new_size < sz){ + //Destroy last elements + this->priv_destroy_last_n(sz - new_size); + } + else{ + const size_type n = new_size - this->size(); + this->priv_forward_range_insert_at_end(n, this->priv_resize_proxy(u), alloc_version()); + } + } + + BOOST_CONTAINER_FORCEINLINE void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW + {} + + void priv_shrink_to_fit(version_1) + { + const size_type cp = this->m_holder.capacity(); + if(cp){ + const size_type sz = this->size(); + if(!sz){ + this->m_holder.deallocate(this->m_holder.m_start, cp); + this->m_holder.m_start = pointer(); + this->m_holder.m_capacity = 0; + } + else if(sz < cp){ + //Allocate a new buffer. + //Pass the hint so that allocators can take advantage of this. + pointer const p = this->m_holder.allocate(sz); + + //We will reuse insert code, so create a dummy input iterator + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_forward_range_insert_new_allocation + ( boost::movelib::to_raw_pointer(p), sz + , this->priv_raw_begin(), 0, this->priv_dummy_empty_proxy()); + } + } + } + + void priv_shrink_to_fit(version_2) BOOST_NOEXCEPT_OR_NOTHROW + { + const size_type cp = this->m_holder.capacity(); + if(cp){ + const size_type sz = this->size(); + if(!sz){ + this->m_holder.deallocate(this->m_holder.m_start, cp); + this->m_holder.m_start = pointer(); + this->m_holder.m_capacity = 0; + } + else{ + size_type received_size = sz; + pointer reuse(this->m_holder.start()); + if(this->m_holder.allocation_command + (shrink_in_place | nothrow_allocation, cp, received_size, reuse)){ + this->m_holder.capacity(received_size); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_shrink; + #endif + } + } + } + } + + template + iterator priv_forward_range_insert_no_capacity + (const pointer &pos, const size_type, const InsertionProxy , version_0) + { + throw_bad_alloc(); + return iterator(pos); + } + + template + iterator priv_forward_range_insert_no_capacity + (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_1) + { + //Check if we have enough memory or try to expand current memory + const size_type n_pos = pos - this->m_holder.start(); + T *const raw_pos = boost::movelib::to_raw_pointer(pos); + + const size_type new_cap = this->m_holder.template next_capacity(n); + //Pass the hint so that allocators can take advantage of this. + T * const new_buf = boost::movelib::to_raw_pointer(this->m_holder.allocate(new_cap)); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_forward_range_insert_new_allocation + ( new_buf, new_cap, raw_pos, n, insert_range_proxy); + return iterator(this->m_holder.start() + n_pos); + } + + template + iterator priv_forward_range_insert_no_capacity + (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2) + { + //Check if we have enough memory or try to expand current memory + T *const raw_pos = boost::movelib::to_raw_pointer(pos); + const size_type n_pos = raw_pos - this->priv_raw_begin(); + + //There is not enough memory, allocate a new + //buffer or expand the old one. + size_type real_cap = this->m_holder.template next_capacity(n); + pointer reuse(this->m_holder.start()); + pointer const ret (this->m_holder.allocation_command + (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse)); + + //Buffer reallocated + if(reuse){ + //Forward expansion, delay insertion + if(this->m_holder.start() == ret){ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->m_holder.capacity(real_cap); + //Expand forward + this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy); + } + //Backwards (and possibly forward) expansion + else{ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_bwd; + #endif + this->priv_forward_range_insert_expand_backwards + (boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); + } + } + //New buffer + else{ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_forward_range_insert_new_allocation + ( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); + } + + return iterator(this->m_holder.start() + n_pos); + } + + template + iterator priv_forward_range_insert + (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy) + { + BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size); + //Check if we have enough memory or try to expand current memory + const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size; + + bool same_buffer_start = n <= remaining; + if (!same_buffer_start){ + return priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version()); + } + else{ + //Expand forward + T *const raw_pos = boost::movelib::to_raw_pointer(pos); + const size_type n_pos = raw_pos - this->priv_raw_begin(); + this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy); + return iterator(this->m_holder.start() + n_pos); + } + } + + template + iterator priv_forward_range_insert_at_end + (const size_type n, const InsertionProxy insert_range_proxy, version_0) + { + //Check if we have enough memory or try to expand current memory + const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size; + + if (n > remaining){ + //This will trigger an error + throw_bad_alloc(); + } + this->priv_forward_range_insert_at_end_expand_forward(n, insert_range_proxy); + return this->end(); + } + + template + BOOST_CONTAINER_FORCEINLINE iterator priv_forward_range_insert_at_end + (const size_type n, const InsertionProxy insert_range_proxy, AllocVersion) + { + return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy); + } + + //Takes the range pointed by [first_pos, last_pos) and shifts it to the right + //by 'shift_count'. 'limit_pos' marks the end of constructed elements. + // + //Precondition: first_pos <= last_pos <= limit_pos + // + //The shift operation might cross limit_pos so elements to moved beyond limit_pos + //are uninitialized_moved with an allocator. Other elements are moved. + // + //The shift operation might left uninitialized elements after limit_pos + //and the number of uninitialized elements is returned by the function. + // + //Old situation: + // first_pos last_pos old_limit + // | | | + // ____________V_______V__________________V_____________ + //| prefix | range | suffix |raw_mem ~ + //|____________|_______|__________________|_____________~ + // + //New situation in Case A (hole_size == 0): + // range is moved through move assignments + // + // first_pos last_pos limit_pos + // | | | + // ____________V_______V__________________V_____________ + //| prefix' | | | range |suffix'|raw_mem ~ + //|________________+______|___^___|_______|_____________~ + // | | + // |_>_>_>_>_>^ + // + // + //New situation in Case B (hole_size >= 0): + // range is moved through uninitialized moves + // + // first_pos last_pos limit_pos + // | | | + // ____________V_______V__________________V________________ + //| prefix' | | | [hole] | range | + //|_______________________________________|________|___^___| + // | | + // |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^ + // + //New situation in Case C (hole_size == 0): + // range is moved through move assignments and uninitialized moves + // + // first_pos last_pos limit_pos + // | | | + // ____________V_______V__________________V___ + //| prefix' | | | range | + //|___________________________________|___^___| + // | | + // |_>_>_>_>_>_>_>_>_>_>_>^ + size_type priv_insert_ordered_at_shift_range + (size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count) + { + BOOST_ASSERT(first_pos <= last_pos); + BOOST_ASSERT(last_pos <= limit_pos); + // + T* const begin_ptr = this->priv_raw_begin(); + T* const first_ptr = begin_ptr + first_pos; + T* const last_ptr = begin_ptr + last_pos; + + size_type hole_size = 0; + //Case A: + if((last_pos + shift_count) <= limit_pos){ + //All move assigned + boost::container::move_backward(first_ptr, last_ptr, last_ptr + shift_count); + } + //Case B: + else if((first_pos + shift_count) >= limit_pos){ + //All uninitialized_moved + ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count); + hole_size = first_pos + shift_count - limit_pos; + } + //Case C: + else{ + //Some uninitialized_moved + T* const limit_ptr = begin_ptr + limit_pos; + T* const boundary_ptr = limit_ptr - shift_count; + ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), boundary_ptr, last_ptr, limit_ptr); + //The rest is move assigned + boost::container::move_backward(first_ptr, boundary_ptr, limit_ptr); + } + return hole_size; + } + + private: + BOOST_CONTAINER_FORCEINLINE T *priv_raw_begin() const + { return boost::movelib::to_raw_pointer(m_holder.start()); } + + BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() const + { return this->priv_raw_begin() + this->m_holder.m_size; } + + template + void priv_forward_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy) + { + T* const old_finish = this->priv_raw_end(); + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); + this->m_holder.m_size += n; + } + + template + void priv_forward_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy) + { + //n can't be 0, because there is nothing to do in that case + if(BOOST_UNLIKELY(!n)) return; + //There is enough memory + T* const old_finish = this->priv_raw_end(); + const size_type elems_after = old_finish - pos; + + if (!elems_after){ + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); + this->m_holder.m_size += n; + } + else if (elems_after >= n){ + //New elements can be just copied. + //Move to uninitialized memory last objects + ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), old_finish - n, old_finish, old_finish); + this->m_holder.m_size += n; + //Copy previous to last objects to the initialized end + boost::container::move_backward(pos, old_finish - n, old_finish); + //Insert new objects in the pos + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n); + } + else { + //The new elements don't fit in the [pos, end()) range. + + //Copy old [pos, end()) elements to the uninitialized memory (a gap is created) + ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pos, old_finish, pos + n); + BOOST_TRY{ + //Copy first new elements in pos (gap is still there) + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elems_after); + //Copy to the beginning of the unallocated zone the last new elements (the gap is closed). + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n - elems_after); + this->m_holder.m_size += n; + } + BOOST_CATCH(...){ + boost::container::destroy_alloc_n(this->get_stored_allocator(), pos + n, elems_after); + BOOST_RETHROW + } + BOOST_CATCH_END + } + } + + template + void priv_forward_range_insert_new_allocation + (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy) + { + //n can be zero, if we want to reallocate! + T *new_finish = new_start; + T *old_finish; + //Anti-exception rollbacks + typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, this->m_holder.alloc(), new_cap); + typename value_traits::ArrayDestructor new_values_destroyer(new_start, this->m_holder.alloc(), 0u); + + //Initialize with [begin(), pos) old buffer + //the start of the new buffer + T * const old_buffer = this->priv_raw_begin(); + if(old_buffer){ + new_finish = ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), this->priv_raw_begin(), pos, old_finish = new_finish); + new_values_destroyer.increment_size(new_finish - old_finish); + } + //Initialize new objects, starting from previous point + old_finish = new_finish; + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); + new_finish += n; + new_values_destroyer.increment_size(new_finish - old_finish); + //Initialize from the rest of the old buffer, + //starting from previous point + if(old_buffer){ + new_finish = ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), pos, old_buffer + this->m_holder.m_size, new_finish); + //Destroy and deallocate old elements + //If there is allocated memory, destroy and deallocate + if(!value_traits::trivial_dctr_after_move) + boost::container::destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size); + this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity()); + } + this->m_holder.start(new_start); + this->m_holder.m_size = size_type(new_finish - new_start); + this->m_holder.capacity(new_cap); + //All construction successful, disable rollbacks + new_values_destroyer.release(); + new_buffer_deallocator.release(); + } + + template + void priv_forward_range_insert_expand_backwards + (T* const new_start, const size_type new_capacity, + T* const pos, const size_type n, InsertionProxy insert_range_proxy) + { + //n can be zero to just expand capacity + //Backup old data + T* const old_start = this->priv_raw_begin(); + const size_type old_size = this->m_holder.m_size; + T* const old_finish = old_start + old_size; + + //We can have 8 possibilities: + const size_type elemsbefore = static_cast(pos - old_start); + const size_type s_before = static_cast(old_start - new_start); + const size_type before_plus_new = elemsbefore + n; + + //Update the vector buffer information to a safe state + this->m_holder.start(new_start); + this->m_holder.capacity(new_capacity); + this->m_holder.m_size = 0; + + //If anything goes wrong, this object will destroy + //all the old objects to fulfill previous vector state + typename value_traits::ArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size); + //Check if s_before is big enough to hold the beginning of old data + new data + if(s_before >= before_plus_new){ + //Copy first old values before pos, after that the new objects + T *const new_elem_pos = + ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start); + this->m_holder.m_size = elemsbefore; + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_elem_pos, n); + this->m_holder.m_size = before_plus_new; + const size_type new_size = old_size + n; + //Check if s_before is so big that even copying the old data + new data + //there is a gap between the new data and the old data + if(s_before >= new_size){ + //Old situation: + // _________________________________________________________ + //| raw_mem | old_begin | old_end | + //| __________________________________|___________|_________| + // + //New situation: + // _________________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|__________|_________|________________________| + // + //Now initialize the rest of memory with the last old values + if(before_plus_new != new_size){ //Special case to avoid operations in back insertion + ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new); + //All new elements correctly constructed, avoid new element destruction + this->m_holder.m_size = new_size; + } + //Old values destroyed automatically with "old_values_destroyer" + //when "old_values_destroyer" goes out of scope unless the have trivial + //destructor after move. + if(value_traits::trivial_dctr_after_move) + old_values_destroyer.release(); + } + //s_before is so big that divides old_end + else{ + //Old situation: + // __________________________________________________ + //| raw_mem | old_begin | old_end | + //| ___________________________|___________|_________| + // + //New situation: + // __________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|__________|_________|_________________| + // + //Now initialize the rest of memory with the last old values + //All new elements correctly constructed, avoid new element destruction + const size_type raw_gap = s_before - before_plus_new; + if(!value_traits::trivial_dctr){ + //Now initialize the rest of s_before memory with the + //first of elements after new values + ::boost::container::uninitialized_move_alloc_n + (this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new); + //Now we have a contiguous buffer so program trailing element destruction + //and update size to the final size. + old_values_destroyer.shrink_forward(new_size-s_before); + this->m_holder.m_size = new_size; + //Now move remaining last objects in the old buffer begin + T * const remaining_pos = pos + raw_gap; + if(remaining_pos != old_start){ //Make sure data has to be moved + ::boost::container::move(remaining_pos, old_finish, old_start); + } + //Once moved, avoid calling the destructors if trivial after move + if(value_traits::trivial_dctr_after_move){ + old_values_destroyer.release(); + } + } + else{ //If trivial destructor, we can uninitialized copy + copy in a single uninitialized copy + ::boost::container::uninitialized_move_alloc_n + (this->m_holder.alloc(), pos, static_cast(old_finish - pos), new_start + before_plus_new); + this->m_holder.m_size = new_size; + old_values_destroyer.release(); + } + } + } + else{ + //Check if we have to do the insertion in two phases + //since maybe s_before is not big enough and + //the buffer was expanded both sides + // + //Old situation: + // _________________________________________________ + //| raw_mem | old_begin + old_end | raw_mem | + //|_________|_____________________|_________________| + // + //New situation with do_after: + // _________________________________________________ + //| old_begin + new + old_end | raw_mem | + //|___________________________________|_____________| + // + //New without do_after: + // _________________________________________________ + //| old_begin + new + old_end | raw_mem | + //|____________________________|____________________| + // + const bool do_after = n > s_before; + + //Now we can have two situations: the raw_mem of the + //beginning divides the old_begin, or the new elements: + if (s_before <= elemsbefore) { + //The raw memory divides the old_begin group: + // + //If we need two phase construction (do_after) + //new group is divided in new = new_beg + new_end groups + //In this phase only new_beg will be inserted + // + //Old situation: + // _________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|_________|___________|_________|_________________| + // + //New situation with do_after(1): + //This is not definitive situation, the second phase + //will include + // _________________________________________________ + //| old_begin | new_beg | old_end | raw_mem | + //|___________|_________|_________|_________________| + // + //New situation without do_after: + // _________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|_____|_________|_____________________| + // + //Copy the first part of old_begin to raw_mem + ::boost::container::uninitialized_move_alloc_n + (this->m_holder.alloc(), old_start, s_before, new_start); + //The buffer is all constructed until old_end, + //so program trailing destruction and assign final size + //if !do_after, s_before+n otherwise. + size_type new_1st_range; + if(do_after){ + new_1st_range = s_before; + //release destroyer and update size + old_values_destroyer.release(); + } + else{ + new_1st_range = n; + if(value_traits::trivial_dctr_after_move) + old_values_destroyer.release(); + else{ + old_values_destroyer.shrink_forward(old_size - (s_before - n)); + } + } + this->m_holder.m_size = old_size + new_1st_range; + //Now copy the second part of old_begin overwriting itself + T *const next = ::boost::container::move(old_start + s_before, pos, old_start); + //Now copy the new_beg elements + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, new_1st_range); + + //If there is no after work and the last old part needs to be moved to front, do it + if(!do_after && (n != s_before)){ + //Now displace old_end elements + ::boost::container::move(pos, old_finish, next + new_1st_range); + } + } + else { + //If we have to expand both sides, + //we will play if the first new values so + //calculate the upper bound of new values + + //The raw memory divides the new elements + // + //If we need two phase construction (do_after) + //new group is divided in new = new_beg + new_end groups + //In this phase only new_beg will be inserted + // + //Old situation: + // _______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|_______________|___________|_________|_________________| + // + //New situation with do_after(): + // ____________________________________________________ + //| old_begin | new_beg | old_end | raw_mem | + //|___________|_______________|_________|______________| + // + //New situation without do_after: + // ______________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|_____|_________|__________________________| + // + //First copy whole old_begin and part of new to raw_mem + T * const new_pos = ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), old_start, pos, new_start); + this->m_holder.m_size = elemsbefore; + const size_type mid_n = s_before - elemsbefore; + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_pos, mid_n); + //The buffer is all constructed until old_end, + //release destroyer + this->m_holder.m_size = old_size + s_before; + old_values_destroyer.release(); + + if(do_after){ + //Copy new_beg part + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, elemsbefore); + } + else{ + //Copy all new elements + const size_type rest_new = n - mid_n; + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, rest_new); + T* const move_start = old_start + rest_new; + //Displace old_end, but make sure data has to be moved + T* const move_end = move_start != pos ? ::boost::container::move(pos, old_finish, move_start) + : old_finish; + //Destroy remaining moved elements from old_end except if they + //have trivial destructor after being moved + size_type n_destroy = s_before - n; + if(!value_traits::trivial_dctr_after_move) + boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy); + this->m_holder.m_size -= n_destroy; + } + } + + //This is only executed if two phase construction is needed + if(do_after){ + //The raw memory divides the new elements + // + //Old situation: + // ______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|______________| + // + //New situation with do_after(1): + // _______________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_________|________|_________| + // + //New situation with do_after(2): + // ______________________________________________________ + //| old_begin + new | old_end |raw | + //|_______________________________________|_________|____| + // + const size_type n_after = n - s_before; + const size_type elemsafter = old_size - elemsbefore; + + //We can have two situations: + if (elemsafter >= n_after){ + //The raw_mem from end will divide displaced old_end + // + //Old situation: + // ______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|______________| + // + //New situation with do_after(1): + // _______________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_________|________|_________| + // + //First copy the part of old_end raw_mem + T* finish_n = old_finish - n_after; + ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), finish_n, old_finish, old_finish); + this->m_holder.m_size += n_after; + //Displace the rest of old_end to the new position + boost::container::move_backward(pos, finish_n, old_finish); + //Now overwrite with new_end + //The new_end part is [first + (n - n_after), last) + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n_after); + } + else { + //The raw_mem from end will divide new_end part + // + //Old situation: + // _____________________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|_____________________| + // + //New situation with do_after(2): + // _____________________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_______________|________|_________| + // + + const size_type mid_last_dist = n_after - elemsafter; + //First initialize data in raw memory + + //Copy to the old_end part to the uninitialized zone leaving a gap. + ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), pos, old_finish, old_finish + mid_last_dist); + + typename value_traits::ArrayDestructor old_end_destroyer + (old_finish + mid_last_dist, this->m_holder.alloc(), old_finish - pos); + + //Copy the first part to the already constructed old_end zone + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elemsafter); + //Copy the rest to the uninitialized zone filling the gap + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, mid_last_dist); + this->m_holder.m_size += n_after; + old_end_destroyer.release(); + } + } + } + } + + void priv_throw_if_out_of_range(size_type n) const + { + //If n is out of range, throw an out_of_range exception + if (n >= this->size()){ + throw_out_of_range("vector::at out of range"); + } + } + + BOOST_CONTAINER_FORCEINLINE bool priv_in_range(const_iterator pos) const + { + return (this->begin() <= pos) && (pos < this->end()); + } + + BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const + { + return (this->begin() <= pos) && (pos <= this->end()); + } + + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + public: + unsigned int num_expand_fwd; + unsigned int num_expand_bwd; + unsigned int num_shrink; + unsigned int num_alloc; + void reset_alloc_stats() + { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; } + #endif + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +}; + +}} //namespace boost::container + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace boost { + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; + +} + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +#include + +#endif // #ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP diff --git a/boost/container_hash/detail/float_functions.hpp b/boost/container_hash/detail/float_functions.hpp new file mode 100644 index 00000000..f3db52f9 --- /dev/null +++ b/boost/container_hash/detail/float_functions.hpp @@ -0,0 +1,336 @@ + +// Copyright 2005-2009 Daniel James. +// 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_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP) +#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include + +// Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have +// sufficiently good floating point support to not require any +// workarounds. +// +// When set to 0, the library tries to automatically +// use the best available implementation. This normally works well, but +// breaks when ambiguities are created by odd namespacing of the functions. +// +// Note that if this is set to 0, the library should still take full +// advantage of the platform's floating point support. + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +# define BOOST_HASH_CONFORMANT_FLOATS 0 +#elif defined(__LIBCOMO__) +# define BOOST_HASH_CONFORMANT_FLOATS 0 +#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// Rogue Wave library: +# define BOOST_HASH_CONFORMANT_FLOATS 0 +#elif defined(_LIBCPP_VERSION) +// libc++ +# define BOOST_HASH_CONFORMANT_FLOATS 1 +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +// GNU libstdc++ 3 +# if defined(__GNUC__) && __GNUC__ >= 4 +# define BOOST_HASH_CONFORMANT_FLOATS 1 +# else +# define BOOST_HASH_CONFORMANT_FLOATS 0 +# endif +#elif defined(__STL_CONFIG_H) +// generic SGI STL +# define BOOST_HASH_CONFORMANT_FLOATS 0 +#elif defined(__MSL_CPP__) +// MSL standard lib: +# define BOOST_HASH_CONFORMANT_FLOATS 0 +#elif defined(__IBMCPP__) +// VACPP std lib (probably conformant for much earlier version). +# if __IBMCPP__ >= 1210 +# define BOOST_HASH_CONFORMANT_FLOATS 1 +# else +# define BOOST_HASH_CONFORMANT_FLOATS 0 +# endif +#elif defined(MSIPL_COMPILE_H) +// Modena C++ standard library +# define BOOST_HASH_CONFORMANT_FLOATS 0 +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Dinkumware Library (this has to appear after any possible replacement libraries): +# if _CPPLIB_VER >= 405 +# define BOOST_HASH_CONFORMANT_FLOATS 1 +# else +# define BOOST_HASH_CONFORMANT_FLOATS 0 +# endif +#else +# define BOOST_HASH_CONFORMANT_FLOATS 0 +#endif + +#if BOOST_HASH_CONFORMANT_FLOATS + +// The standard library is known to be compliant, so don't use the +// configuration mechanism. + +namespace boost { + namespace hash_detail { + template + struct call_ldexp { + typedef Float float_type; + inline Float operator()(Float x, int y) const { + return std::ldexp(x, y); + } + }; + + template + struct call_frexp { + typedef Float float_type; + inline Float operator()(Float x, int* y) const { + return std::frexp(x, y); + } + }; + + template + struct select_hash_type + { + typedef Float type; + }; + } +} + +#else // BOOST_HASH_CONFORMANT_FLOATS == 0 + +// The C++ standard requires that the C float functions are overloarded +// for float, double and long double in the std namespace, but some of the older +// library implementations don't support this. On some that don't, the C99 +// float functions (frexpf, frexpl, etc.) are available. +// +// The following tries to automatically detect which are available. + +namespace boost { + namespace hash_detail { + + // Returned by dummy versions of the float functions. + + struct not_found { + // Implicitly convertible to float and long double in order to avoid + // a compile error when the dummy float functions are used. + + inline operator float() const { return 0; } + inline operator long double() const { return 0; } + }; + + // A type for detecting the return type of functions. + + template struct is; + template <> struct is { char x[10]; }; + template <> struct is { char x[20]; }; + template <> struct is { char x[30]; }; + template <> struct is { char x[40]; }; + + // Used to convert the return type of a function to a type for sizeof. + + template is float_type(T); + + // call_ldexp + // + // This will get specialized for float and long double + + template struct call_ldexp + { + typedef double float_type; + + inline double operator()(double a, int b) const + { + using namespace std; + return ldexp(a, b); + } + }; + + // call_frexp + // + // This will get specialized for float and long double + + template struct call_frexp + { + typedef double float_type; + + inline double operator()(double a, int* b) const + { + using namespace std; + return frexp(a, b); + } + }; + } +} + +// A namespace for dummy functions to detect when the actual function we want +// isn't available. ldexpl, ldexpf etc. might be added tby the macros below. +// +// AFAICT these have to be outside of the boost namespace, as if they're in +// the boost namespace they'll always be preferable to any other function +// (since the arguments are built in types, ADL can't be used). + +namespace boost_hash_detect_float_functions { + template boost::hash_detail::not_found ldexp(Float, int); + template boost::hash_detail::not_found frexp(Float, int*); +} + +// Macros for generating specializations of call_ldexp and call_frexp. +// +// check_cpp and check_c99 check if the C++ or C99 functions are available. +// +// Then the call_* functions select an appropriate implementation. +// +// I used c99_func in a few places just to get a unique name. +// +// Important: when using 'using namespace' at namespace level, include as +// little as possible in that namespace, as Visual C++ has an odd bug which +// can cause the namespace to be imported at the global level. This seems to +// happen mainly when there's a template in the same namesapce. + +#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ +namespace boost_hash_detect_float_functions { \ + template \ + boost::hash_detail::not_found c99_func(Float, type2); \ +} \ + \ +namespace boost { \ + namespace hash_detail { \ + namespace c99_func##_detect { \ + using namespace std; \ + using namespace boost_hash_detect_float_functions; \ + \ + struct check { \ + static type1 x; \ + static type2 y; \ + BOOST_STATIC_CONSTANT(bool, cpp = \ + sizeof(float_type(cpp_func(x,y))) \ + == sizeof(is)); \ + BOOST_STATIC_CONSTANT(bool, c99 = \ + sizeof(float_type(c99_func(x,y))) \ + == sizeof(is)); \ + }; \ + } \ + \ + template \ + struct call_c99_##c99_func : \ + boost::hash_detail::call_##cpp_func {}; \ + \ + template <> \ + struct call_c99_##c99_func { \ + typedef type1 float_type; \ + \ + template \ + inline type1 operator()(type1 a, T b) const \ + { \ + using namespace std; \ + return c99_func(a, b); \ + } \ + }; \ + \ + template \ + struct call_cpp_##c99_func : \ + call_c99_##c99_func< \ + ::boost::hash_detail::c99_func##_detect::check::c99 \ + > {}; \ + \ + template <> \ + struct call_cpp_##c99_func { \ + typedef type1 float_type; \ + \ + template \ + inline type1 operator()(type1 a, T b) const \ + { \ + using namespace std; \ + return cpp_func(a, b); \ + } \ + }; \ + \ + template <> \ + struct call_##cpp_func : \ + call_cpp_##c99_func< \ + ::boost::hash_detail::c99_func##_detect::check::cpp \ + > {}; \ + } \ +} + +#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \ +namespace boost { \ + namespace hash_detail { \ + \ + template <> \ + struct call_##cpp_func { \ + typedef type1 float_type; \ + inline type1 operator()(type1 x, type2 y) const { \ + return c99_func(x, y); \ + } \ + }; \ + } \ +} + +#if defined(ldexpf) +BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int) +#else +BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int) +#endif + +#if defined(ldexpl) +BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int) +#else +BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int) +#endif + +#if defined(frexpf) +BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*) +#else +BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*) +#endif + +#if defined(frexpl) +BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*) +#else +BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*) +#endif + +#undef BOOST_HASH_CALL_FLOAT_MACRO +#undef BOOST_HASH_CALL_FLOAT_FUNC + + +namespace boost +{ + namespace hash_detail + { + template + struct select_hash_type_impl { + typedef double type; + }; + + template <> + struct select_hash_type_impl { + typedef float type; + }; + + template <> + struct select_hash_type_impl { + typedef long double type; + }; + + + // select_hash_type + // + // If there is support for a particular floating point type, use that + // otherwise use double (there's always support for double). + + template + struct select_hash_type : select_hash_type_impl< + BOOST_DEDUCED_TYPENAME call_ldexp::float_type, + BOOST_DEDUCED_TYPENAME call_frexp::float_type + > {}; + } +} + +#endif // BOOST_HASH_CONFORMANT_FLOATS + +#endif diff --git a/boost/container_hash/detail/hash_float.hpp b/boost/container_hash/detail/hash_float.hpp new file mode 100644 index 00000000..f7634285 --- /dev/null +++ b/boost/container_hash/detail/hash_float.hpp @@ -0,0 +1,271 @@ + +// Copyright 2005-2012 Daniel James. +// 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_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER) +#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_MSVC) +#pragma warning(push) +#if BOOST_MSVC >= 1400 +#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does + // not satisfy test. Loop body not executed +#endif +#endif + +// Can we use fpclassify? + +// STLport +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define BOOST_HASH_USE_FPCLASSIFY 0 + +// GNU libstdc++ 3 +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \ + !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) +# define BOOST_HASH_USE_FPCLASSIFY 1 +# else +# define BOOST_HASH_USE_FPCLASSIFY 0 +# endif + +// Everything else +#else +# define BOOST_HASH_USE_FPCLASSIFY 0 +#endif + +namespace boost +{ + namespace hash_detail + { + inline void hash_float_combine(std::size_t& seed, std::size_t value) + { + seed ^= value + (seed<<6) + (seed>>2); + } + + //////////////////////////////////////////////////////////////////////// + // Binary hash function + // + // Only used for floats with known iec559 floats, and certain values in + // numeric_limits + + inline std::size_t hash_binary(char* ptr, std::size_t length) + { + std::size_t seed = 0; + + if (length >= sizeof(std::size_t)) { + std::memcpy(&seed, ptr, sizeof(std::size_t)); + length -= sizeof(std::size_t); + ptr += sizeof(std::size_t); + + while(length >= sizeof(std::size_t)) { + std::size_t buffer = 0; + std::memcpy(&buffer, ptr, sizeof(std::size_t)); + hash_float_combine(seed, buffer); + length -= sizeof(std::size_t); + ptr += sizeof(std::size_t); + } + } + + if (length > 0) { + std::size_t buffer = 0; + std::memcpy(&buffer, ptr, length); + hash_float_combine(seed, buffer); + } + + return seed; + } + + template + struct enable_binary_hash + { + BOOST_STATIC_CONSTANT(bool, value = + std::numeric_limits::is_iec559 && + std::numeric_limits::digits == digits && + std::numeric_limits::radix == 2 && + std::numeric_limits::max_exponent == max_exponent); + }; + + template + inline std::size_t float_hash_impl(Float v, + BOOST_DEDUCED_TYPENAME boost::enable_if_c< + enable_binary_hash::value, + std::size_t>::type) + { + return hash_binary((char*) &v, 4); + } + + + template + inline std::size_t float_hash_impl(Float v, + BOOST_DEDUCED_TYPENAME boost::enable_if_c< + enable_binary_hash::value, + std::size_t>::type) + { + return hash_binary((char*) &v, 8); + } + + template + inline std::size_t float_hash_impl(Float v, + BOOST_DEDUCED_TYPENAME boost::enable_if_c< + enable_binary_hash::value, + std::size_t>::type) + { + return hash_binary((char*) &v, 10); + } + + template + inline std::size_t float_hash_impl(Float v, + BOOST_DEDUCED_TYPENAME boost::enable_if_c< + enable_binary_hash::value, + std::size_t>::type) + { + return hash_binary((char*) &v, 16); + } + + //////////////////////////////////////////////////////////////////////// + // Portable hash function + // + // Used as a fallback when the binary hash function isn't supported. + + template + inline std::size_t float_hash_impl2(T v) + { + boost::hash_detail::call_frexp frexp; + boost::hash_detail::call_ldexp ldexp; + + int exp = 0; + + v = frexp(v, &exp); + + // A postive value is easier to hash, so combine the + // sign with the exponent and use the absolute value. + if(v < 0) { + v = -v; + exp += limits::max_exponent - + limits::min_exponent; + } + + v = ldexp(v, limits::digits); + std::size_t seed = static_cast(v); + v -= static_cast(seed); + + // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1; + std::size_t const length + = (limits::digits * + boost::static_log2::radix>::value + + limits::digits - 1) + / limits::digits; + + for(std::size_t i = 0; i != length; ++i) + { + v = ldexp(v, limits::digits); + std::size_t part = static_cast(v); + v -= static_cast(part); + hash_float_combine(seed, part); + } + + hash_float_combine(seed, static_cast(exp)); + + return seed; + } + +#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC) + template + inline std::size_t float_hash_impl(T v, ...) + { + typedef BOOST_DEDUCED_TYPENAME select_hash_type::type type; + return float_hash_impl2(static_cast(v)); + } +#endif + } +} + +#if BOOST_HASH_USE_FPCLASSIFY + +#include + +namespace boost +{ + namespace hash_detail + { + template + inline std::size_t float_hash_value(T v) + { +#if defined(fpclassify) + switch (fpclassify(v)) +#elif BOOST_HASH_CONFORMANT_FLOATS + switch (std::fpclassify(v)) +#else + using namespace std; + switch (fpclassify(v)) +#endif + { + case FP_ZERO: + return 0; + case FP_INFINITE: + return (std::size_t)(v > 0 ? -1 : -2); + case FP_NAN: + return (std::size_t)(-3); + case FP_NORMAL: + case FP_SUBNORMAL: + return float_hash_impl(v, 0); + default: + BOOST_ASSERT(0); + return 0; + } + } + } +} + +#else // !BOOST_HASH_USE_FPCLASSIFY + +namespace boost +{ + namespace hash_detail + { + template + inline bool is_zero(T v) + { +#if !defined(__GNUC__) && !defined(__clang__) + return v == 0; +#else + // GCC's '-Wfloat-equal' will complain about comparing + // v to 0, but because it disables warnings for system + // headers it won't complain if you use std::equal_to to + // compare with 0. Resulting in this silliness: + return std::equal_to()(v, 0); +#endif + } + + template + inline std::size_t float_hash_value(T v) + { + return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0); + } + } +} + +#endif // BOOST_HASH_USE_FPCLASSIFY + +#undef BOOST_HASH_USE_FPCLASSIFY + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif diff --git a/boost/container_hash/detail/limits.hpp b/boost/container_hash/detail/limits.hpp new file mode 100644 index 00000000..4a971a6a --- /dev/null +++ b/boost/container_hash/detail/limits.hpp @@ -0,0 +1,62 @@ + +// Copyright 2005-2009 Daniel James. +// 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) +// +// On some platforms std::limits gives incorrect values for long double. +// This tries to work around them. + +#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER) +#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include + +// On OpenBSD, numeric_limits is not reliable for long doubles, but +// the macros defined in are and support long double when STLport +// doesn't. + +#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE) +#include +#endif + +namespace boost +{ + namespace hash_detail + { + template + struct limits : std::numeric_limits {}; + +#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE) + template <> + struct limits + : std::numeric_limits + { + static long double epsilon() { + return LDBL_EPSILON; + } + + static long double (max)() { + return LDBL_MAX; + } + + static long double (min)() { + return LDBL_MIN; + } + + BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG); + BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP); + BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP); +#if defined(_STLP_NO_LONG_DOUBLE) + BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX); +#endif + }; +#endif // __OpenBSD__ + } +} + +#endif diff --git a/boost/container_hash/extensions.hpp b/boost/container_hash/extensions.hpp new file mode 100644 index 00000000..4eebb4bc --- /dev/null +++ b/boost/container_hash/extensions.hpp @@ -0,0 +1,414 @@ + +// Copyright 2005-2009 Daniel James. +// 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) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +// This implements the extensions to the standard. +// It's undocumented, so you shouldn't use it.... + +#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) +#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP + +#include +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_ARRAY) +# include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) +# include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_MEMORY) +# include +#endif + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +#include +#endif + +namespace boost +{ + template + std::size_t hash_value(std::pair const&); + template + std::size_t hash_value(std::vector const&); + template + std::size_t hash_value(std::list const& v); + template + std::size_t hash_value(std::deque const& v); + template + std::size_t hash_value(std::set const& v); + template + std::size_t hash_value(std::multiset const& v); + template + std::size_t hash_value(std::map const& v); + template + std::size_t hash_value(std::multimap const& v); + + template + std::size_t hash_value(std::complex const&); + + 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; + } + + inline std::size_t hash_range( + std::vector::iterator first, + std::vector::iterator last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + + return seed; + } + + inline std::size_t hash_range( + std::vector::const_iterator first, + std::vector::const_iterator last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + + return seed; + } + + inline void hash_range( + std::size_t& seed, + std::vector::iterator first, + std::vector::iterator last) + { + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + } + + inline void hash_range( + std::size_t& seed, + std::vector::const_iterator first, + std::vector::const_iterator last) + { + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + } + + template + std::size_t hash_value(std::vector const& v) + { + return boost::hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::list const& v) + { + return boost::hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::deque const& v) + { + return boost::hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::set const& v) + { + return boost::hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multiset const& v) + { + return boost::hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::map const& v) + { + return boost::hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multimap const& v) + { + return boost::hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::complex const& v) + { + boost::hash hasher; + std::size_t seed = hasher(v.imag()); + seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); + return seed; + } + +#if !defined(BOOST_NO_CXX11_HDR_ARRAY) + template + std::size_t hash_value(std::array const& v) + { + return boost::hash_range(v.begin(), v.end()); + } +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) + namespace hash_detail { + template + inline typename boost::enable_if_c<(I == std::tuple_size::value), + void>::type + hash_combine_tuple(std::size_t&, T const&) + { + } + + template + inline typename boost::enable_if_c<(I < std::tuple_size::value), + void>::type + hash_combine_tuple(std::size_t& seed, T const& v) + { + boost::hash_combine(seed, std::get(v)); + boost::hash_detail::hash_combine_tuple(seed, v); + } + + template + inline std::size_t hash_tuple(T const& v) + { + std::size_t seed = 0; + boost::hash_detail::hash_combine_tuple<0>(seed, v); + return seed; + } + } + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } +#else + + inline std::size_t hash_value(std::tuple<> const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + + template + inline std::size_t hash_value(std::tuple const& v) + { + return boost::hash_detail::hash_tuple(v); + } + +#endif + +#endif + +#if !defined(BOOST_NO_CXX11_SMART_PTR) + template + inline std::size_t hash_value(std::shared_ptr const& x) { + return boost::hash_value(x.get()); + } + + template + inline std::size_t hash_value(std::unique_ptr const& x) { + return boost::hash_value(x.get()); + } +#endif + + // + // call_hash_impl + // + + // On compilers without function template ordering, this deals with arrays. + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + namespace hash_detail + { + template + struct call_hash_impl + { + template + struct inner + { + static std::size_t call(T const& v) + { + using namespace boost; + return hash_value(v); + } + }; + }; + + template <> + struct call_hash_impl + { + template + struct inner + { + static std::size_t call(Array const& v) + { + const int size = sizeof(v) / sizeof(*v); + return boost::hash_range(v, v + size); + } + }; + }; + + template + struct call_hash + : public call_hash_impl::value> + ::BOOST_NESTED_TEMPLATE inner + { + }; + } +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + // + // boost::hash + // + + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template struct hash + : boost::hash_detail::hash_base + { +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + std::size_t operator()(T const& val) const + { + return hash_value(val); + } +#else + std::size_t operator()(T const& val) const + { + return hash_detail::call_hash::call(val); + } +#endif + }; + +#if BOOST_WORKAROUND(__DMC__, <= 0x848) + template struct hash + : boost::hash_detail::hash_base + { + std::size_t operator()(const T* val) const + { + return boost::hash_range(val, val+n); + } + }; +#endif + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // On compilers without partial specialization, boost::hash + // has already been declared to deal with pointers, so just + // need to supply the non-pointer version of hash_impl. + + namespace hash_detail + { + template + struct hash_impl; + + template <> + struct hash_impl + { + template + struct inner + : boost::hash_detail::hash_base + { +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + std::size_t operator()(T const& val) const + { + return hash_value(val); + } +#else + std::size_t operator()(T const& val) const + { + return hash_detail::call_hash::call(val); + } +#endif + }; + }; + } +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +} + +#endif diff --git a/boost/container_hash/hash.hpp b/boost/container_hash/hash.hpp new file mode 100644 index 00000000..76de7939 --- /dev/null +++ b/boost/container_hash/hash.hpp @@ -0,0 +1,761 @@ + +// Copyright 2005-2014 Daniel James. +// 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) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. +// +// This also contains public domain code from MurmurHash. From the +// MurmurHash header: + +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP) +#define BOOST_FUNCTIONAL_HASH_HASH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +#include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) +#include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) +#include +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) + +#if BOOST_MSVC >= 1400 +#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values + // are always of range '0' to '4294967295'. + // Loop executes infinitely. +#endif + +#endif + +#if BOOST_WORKAROUND(__GNUC__, < 3) \ + && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +#define BOOST_HASH_CHAR_TRAITS string_char_traits +#else +#define BOOST_HASH_CHAR_TRAITS char_traits +#endif + +#if defined(_MSC_VER) +# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r) +#else +# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r)) +#endif + +// Detect whether standard library has C++17 headers + +#if !defined(BOOST_HASH_CXX17) +# if defined(BOOST_MSVC) +# if defined(_HAS_CXX17) && _HAS_CXX17 +# define BOOST_HASH_CXX17 1 +# endif +# elif defined(__cplusplus) && __cplusplus >= 201703 +# define BOOST_HASH_CXX17 1 +# endif +#endif + +#if !defined(BOOST_HASH_CXX17) +# define BOOST_HASH_CXX17 0 +#endif + +#if BOOST_HASH_CXX17 && defined(__has_include) +# if !defined(BOOST_HASH_HAS_STRING_VIEW) && __has_include() +# define BOOST_HASH_HAS_STRING_VIEW 1 +# endif +# if !defined(BOOST_HASH_HAS_OPTIONAL) && __has_include() +# define BOOST_HASH_HAS_OPTIONAL 1 +# endif +# if !defined(BOOST_HASH_HAS_VARIANT) && __has_include() +# define BOOST_HASH_HAS_VARIANT 1 +# endif +#endif + +#if !defined(BOOST_HASH_HAS_STRING_VIEW) +# define BOOST_HASH_HAS_STRING_VIEW 0 +#endif + +#if !defined(BOOST_HASH_HAS_OPTIONAL) +# define BOOST_HASH_HAS_OPTIONAL 0 +#endif + +#if !defined(BOOST_HASH_HAS_VARIANT) +# define BOOST_HASH_HAS_VARIANT 0 +#endif + +#if BOOST_HASH_HAS_STRING_VIEW +# include +#endif + +#if BOOST_HASH_HAS_OPTIONAL +# include +#endif + +#if BOOST_HASH_HAS_VARIANT +# include +#endif + +namespace boost +{ + namespace hash_detail + { +#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC + template + struct hash_base + { + typedef T argument_type; + typedef std::size_t result_type; + }; +#else + template + struct hash_base : std::unary_function {}; +#endif + + struct enable_hash_value { typedef std::size_t type; }; + + template struct basic_numbers {}; + template struct long_numbers; + template struct ulong_numbers; + template struct float_numbers {}; + + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; +#endif + +#if !defined(BOOST_NO_CXX11_CHAR16_T) + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; +#endif + +#if !defined(BOOST_NO_CXX11_CHAR32_T) + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; +#endif + + // long_numbers is defined like this to allow for separate + // specialization for long_long and int128_type, in case + // they conflict. + template struct long_numbers2 {}; + template struct ulong_numbers2 {}; + template struct long_numbers : long_numbers2 {}; + template struct ulong_numbers : ulong_numbers2 {}; + +#if !defined(BOOST_NO_LONG_LONG) + template <> struct long_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct ulong_numbers : + boost::hash_detail::enable_hash_value {}; +#endif + +#if defined(BOOST_HAS_INT128) + template <> struct long_numbers2 : + boost::hash_detail::enable_hash_value {}; + template <> struct ulong_numbers2 : + boost::hash_detail::enable_hash_value {}; +#endif + + template <> struct float_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct float_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct float_numbers : + boost::hash_detail::enable_hash_value {}; + } + + template + typename boost::hash_detail::basic_numbers::type hash_value(T); + template + typename boost::hash_detail::long_numbers::type hash_value(T); + template + typename boost::hash_detail::ulong_numbers::type hash_value(T); + + template + typename boost::enable_if, std::size_t>::type + hash_value(T); + +#if !BOOST_WORKAROUND(__DMC__, <= 0x848) + template std::size_t hash_value(T* const&); +#else + template std::size_t hash_value(T*); +#endif + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template< class T, unsigned N > + std::size_t hash_value(const T (&x)[N]); + + template< class T, unsigned N > + std::size_t hash_value(T (&x)[N]); +#endif + + template + std::size_t hash_value( + std::basic_string, A> const&); + +#if BOOST_HASH_HAS_STRING_VIEW + template + std::size_t hash_value( + std::basic_string_view > const&); +#endif + + template + typename boost::hash_detail::float_numbers::type hash_value(T); + +#if BOOST_HASH_HAS_OPTIONAL + template + std::size_t hash_value(std::optional const&); +#endif + +#if BOOST_HASH_HAS_VARIANT + std::size_t hash_value(std::monostate); + template + std::size_t hash_value(std::variant const&); +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) + std::size_t hash_value(std::type_index); +#endif + +#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) + std::size_t hash_value(std::error_code const&); + std::size_t hash_value(std::error_condition const&); +#endif + + // Implementation + + namespace hash_detail + { + template + inline std::size_t hash_value_signed(T val) + { + const unsigned int size_t_bits = std::numeric_limits::digits; + // ceiling(std::numeric_limits::digits / size_t_bits) - 1 + const int length = (std::numeric_limits::digits - 1) + / static_cast(size_t_bits); + + std::size_t seed = 0; + T positive = val < 0 ? -1 - val : val; + + // Hopefully, this loop can be unrolled. + for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) + { + seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2); + } + seed ^= (std::size_t) val + (seed<<6) + (seed>>2); + + return seed; + } + + template + inline std::size_t hash_value_unsigned(T val) + { + const unsigned int size_t_bits = std::numeric_limits::digits; + // ceiling(std::numeric_limits::digits / size_t_bits) - 1 + const int length = (std::numeric_limits::digits - 1) + / static_cast(size_t_bits); + + std::size_t seed = 0; + + // Hopefully, this loop can be unrolled. + for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits) + { + seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2); + } + seed ^= (std::size_t) val + (seed<<6) + (seed>>2); + + return seed; + } + + template + inline void hash_combine_impl(SizeT& seed, SizeT value) + { + seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + + inline void hash_combine_impl(boost::uint32_t& h1, + boost::uint32_t k1) + { + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + k1 *= c1; + k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13); + h1 = h1*5+0xe6546b64; + } + + +// Don't define 64-bit hash combine on platforms without 64 bit integers, +// and also not for 32-bit gcc as it warns about the 64-bit constant. +#if !defined(BOOST_NO_INT64_T) && \ + !(defined(__GNUC__) && ULONG_MAX == 0xffffffff) + + inline void hash_combine_impl(boost::uint64_t& h, + boost::uint64_t k) + { + const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995); + const int r = 47; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + + // Completely arbitrary number, to prevent 0's + // from hashing to 0. + h += 0xe6546b64; + } + +#endif // BOOST_NO_INT64_T + } + + template + typename boost::hash_detail::basic_numbers::type hash_value(T v) + { + return static_cast(v); + } + + template + typename boost::hash_detail::long_numbers::type hash_value(T v) + { + return hash_detail::hash_value_signed(v); + } + + template + typename boost::hash_detail::ulong_numbers::type hash_value(T v) + { + return hash_detail::hash_value_unsigned(v); + } + + template + typename boost::enable_if, std::size_t>::type + hash_value(T v) + { + return static_cast(v); + } + + // Implementation by Alberto Barbati and Dave Harris. +#if !BOOST_WORKAROUND(__DMC__, <= 0x848) + template std::size_t hash_value(T* const& v) +#else + template std::size_t hash_value(T* v) +#endif + { +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 + // for some reason ptrdiff_t on OpenVMS compiler with + // 64 bit is not 64 bit !!! + std::size_t x = static_cast( + reinterpret_cast(v)); +#else + std::size_t x = static_cast( + reinterpret_cast(v)); +#endif + return x + (x >> 3); + } + +#if defined(BOOST_MSVC) +#pragma warning(push) +#if BOOST_MSVC <= 1400 +#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to + // 'unsigned int', possible loss of data + // A misguided attempt to detect 64-bit + // incompatability. +#endif +#endif + + template + inline void hash_combine(std::size_t& seed, T const& v) + { + boost::hash hasher; + return boost::hash_detail::hash_combine_impl(seed, hasher(v)); + } + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + + template + inline std::size_t hash_range(It first, It last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + + return seed; + } + + template + inline void hash_range(std::size_t& seed, It first, It last) + { + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + } + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + template + inline std::size_t hash_range(T* first, T* last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + boost::hash hasher; + seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + + return seed; + } + + template + inline void hash_range(std::size_t& seed, T* first, T* last) + { + for(; first != last; ++first) + { + boost::hash hasher; + seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2); + } + } +#endif + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template< class T, unsigned N > + inline std::size_t hash_value(const T (&x)[N]) + { + return hash_range(x, x + N); + } + + template< class T, unsigned N > + inline std::size_t hash_value(T (&x)[N]) + { + return hash_range(x, x + N); + } +#endif + + template + inline std::size_t hash_value( + std::basic_string, A> const& v) + { + return hash_range(v.begin(), v.end()); + } + +#if BOOST_HASH_HAS_STRING_VIEW + template + inline std::size_t hash_value( + std::basic_string_view > const& v) + { + return hash_range(v.begin(), v.end()); + } +#endif + + template + typename boost::hash_detail::float_numbers::type hash_value(T v) + { + return boost::hash_detail::float_hash_value(v); + } + +#if BOOST_HASH_HAS_OPTIONAL + template + inline std::size_t hash_value(std::optional const& v) { + if (!v) { + // Arbitray value for empty optional. + return 0x12345678; + } else { + boost::hash hf; + return hf(*v); + } + } +#endif + +#if BOOST_HASH_HAS_VARIANT + inline std::size_t hash_value(std::monostate) { + return 0x87654321; + } + + template + inline 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 + + +#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) + inline std::size_t hash_value(std::type_index v) + { + return v.hash_code(); + } +#endif + +#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) + inline std::size_t hash_value(std::error_code const& v) { + std::size_t seed = 0; + hash_combine(seed, v.value()); + hash_combine(seed, &v.category()); + return seed; + } + + inline std::size_t hash_value(std::error_condition const& v) { + std::size_t seed = 0; + hash_combine(seed, v.value()); + hash_combine(seed, &v.category()); + return seed; + } +#endif + + // + // boost::hash + // + + // Define the specializations required by the standard. The general purpose + // boost::hash is defined later in extensions.hpp if + // BOOST_HASH_NO_EXTENSIONS is not defined. + + // BOOST_HASH_SPECIALIZE - define a specialization for a type which is + // passed by copy. + // + // BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is + // passed by const reference. + // + // These are undefined later. + +#define BOOST_HASH_SPECIALIZE(type) \ + template <> struct hash \ + : public boost::hash_detail::hash_base \ + { \ + std::size_t operator()(type v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; + +#define BOOST_HASH_SPECIALIZE_REF(type) \ + template <> struct hash \ + : public boost::hash_detail::hash_base \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; + +#define BOOST_HASH_SPECIALIZE_TEMPLATE_REF(type) \ + struct hash \ + : public boost::hash_detail::hash_base \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; + + BOOST_HASH_SPECIALIZE(bool) + BOOST_HASH_SPECIALIZE(char) + BOOST_HASH_SPECIALIZE(signed char) + BOOST_HASH_SPECIALIZE(unsigned char) +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) + BOOST_HASH_SPECIALIZE(wchar_t) +#endif +#if !defined(BOOST_NO_CXX11_CHAR16_T) + BOOST_HASH_SPECIALIZE(char16_t) +#endif +#if !defined(BOOST_NO_CXX11_CHAR32_T) + BOOST_HASH_SPECIALIZE(char32_t) +#endif + BOOST_HASH_SPECIALIZE(short) + BOOST_HASH_SPECIALIZE(unsigned short) + BOOST_HASH_SPECIALIZE(int) + BOOST_HASH_SPECIALIZE(unsigned int) + BOOST_HASH_SPECIALIZE(long) + BOOST_HASH_SPECIALIZE(unsigned long) + + BOOST_HASH_SPECIALIZE(float) + BOOST_HASH_SPECIALIZE(double) + BOOST_HASH_SPECIALIZE(long double) + + BOOST_HASH_SPECIALIZE_REF(std::string) +#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) + BOOST_HASH_SPECIALIZE_REF(std::wstring) +#endif +#if !defined(BOOST_NO_CXX11_CHAR16_T) + BOOST_HASH_SPECIALIZE_REF(std::basic_string) +#endif +#if !defined(BOOST_NO_CXX11_CHAR32_T) + BOOST_HASH_SPECIALIZE_REF(std::basic_string) +#endif + +#if BOOST_HASH_HAS_STRING_VIEW + BOOST_HASH_SPECIALIZE_REF(std::string_view) +# if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) + BOOST_HASH_SPECIALIZE_REF(std::wstring_view) +# endif +# if !defined(BOOST_NO_CXX11_CHAR16_T) + BOOST_HASH_SPECIALIZE_REF(std::basic_string_view) +# endif +# if !defined(BOOST_NO_CXX11_CHAR32_T) + BOOST_HASH_SPECIALIZE_REF(std::basic_string_view) +# endif +#endif + +#if !defined(BOOST_NO_LONG_LONG) + BOOST_HASH_SPECIALIZE(boost::long_long_type) + BOOST_HASH_SPECIALIZE(boost::ulong_long_type) +#endif + +#if defined(BOOST_HAS_INT128) + BOOST_HASH_SPECIALIZE(boost::int128_type) + BOOST_HASH_SPECIALIZE(boost::uint128_type) +#endif + +#if BOOST_HASH_HAS_OPTIONAL + template + BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::optional) +#endif + +#if !defined(BOOST_HASH_HAS_VARIANT) + template + BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::variant) + BOOST_HASH_SPECIALIZE(std::monostate) +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) + BOOST_HASH_SPECIALIZE(std::type_index) +#endif + +#undef BOOST_HASH_SPECIALIZE +#undef BOOST_HASH_SPECIALIZE_REF +#undef BOOST_HASH_SPECIALIZE_TEMPLATE_REF + +// Specializing boost::hash for pointers. + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template + struct hash + : public boost::hash_detail::hash_base + { + std::size_t operator()(T* v) const + { +#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) + return boost::hash_value(v); +#else + std::size_t x = static_cast( + reinterpret_cast(v)); + + return x + (x >> 3); +#endif + } + }; + +#else + + // For compilers without partial specialization, we define a + // boost::hash for all remaining types. But hash_impl is only defined + // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS + // is defined there will still be a compile error for types not supported + // in the standard. + + namespace hash_detail + { + template + struct hash_impl; + + template <> + struct hash_impl + { + template + struct inner + : public boost::hash_detail::hash_base + { + std::size_t operator()(T val) const + { +#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590) + return boost::hash_value(val); +#else + std::size_t x = static_cast( + reinterpret_cast(val)); + + return x + (x >> 3); +#endif + } + }; + }; + } + + template struct hash + : public boost::hash_detail::hash_impl::value> + ::BOOST_NESTED_TEMPLATE inner + { + }; + +#endif +} + +#undef BOOST_HASH_CHAR_TRAITS +#undef BOOST_FUNCTIONAL_HASH_ROTL32 + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP + +// Include this outside of the include guards in case the file is included +// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it +// undefined. + +#if !defined(BOOST_HASH_NO_EXTENSIONS) \ + && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) +#include +#endif diff --git a/boost/container_hash/hash_fwd.hpp b/boost/container_hash/hash_fwd.hpp new file mode 100644 index 00000000..a87c182d --- /dev/null +++ b/boost/container_hash/hash_fwd.hpp @@ -0,0 +1,36 @@ + +// Copyright 2005-2009 Daniel James. +// 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) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) +#define BOOST_FUNCTIONAL_HASH_FWD_HPP + +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + + +namespace boost +{ + template struct hash; + + template void hash_combine(std::size_t& seed, T const& v); + + template std::size_t hash_range(It, It); + template void hash_range(std::size_t&, It, It); + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + template inline std::size_t hash_range(T*, T*); + template inline void hash_range(std::size_t&, T*, T*); +#endif +} + +#endif diff --git a/boost/core/addressof.hpp b/boost/core/addressof.hpp new file mode 100644 index 00000000..f7eab06b --- /dev/null +++ b/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(__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(__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/boost/core/checked_delete.hpp b/boost/core/checked_delete.hpp new file mode 100644 index 00000000..b086e03e --- /dev/null +++ b/boost/core/checked_delete.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_CORE_CHECKED_DELETE_HPP +#define BOOST_CORE_CHECKED_DELETE_HPP + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/checked_delete.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) 2003 Daniel Frey +// Copyright (c) 2003 Howard Hinnant +// +// 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/core/doc/html/core/checked_delete.html for documentation. +// + +namespace boost +{ + +// verify that types are complete for increased safety + +template inline void checked_delete(T * x) +{ + // intentionally complex - simplification causes regressions + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete x; +} + +template inline void checked_array_delete(T * x) +{ + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete [] x; +} + +template struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + // boost:: disables ADL + boost::checked_delete(x); + } +}; + +template struct checked_array_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + boost::checked_array_delete(x); + } +}; + +} // namespace boost + +#endif // #ifndef BOOST_CORE_CHECKED_DELETE_HPP diff --git a/boost/core/demangle.hpp b/boost/core/demangle.hpp new file mode 100644 index 00000000..dc714d80 --- /dev/null +++ b/boost/core/demangle.hpp @@ -0,0 +1,126 @@ +#ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED +#define BOOST_CORE_DEMANGLE_HPP_INCLUDED + +// core::demangle +// +// Copyright 2014 Peter Dimov +// Copyright 2014 Andrey Semashev +// +// 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(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and +// returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662 +#if defined( __has_include ) && (!defined( BOOST_GCC ) || (__GNUC__ + 0) >= 5) +# if __has_include() +# define BOOST_CORE_HAS_CXXABI_H +# endif +#elif defined( __GLIBCXX__ ) || defined( __GLIBCPP__ ) +# define BOOST_CORE_HAS_CXXABI_H +#endif + +#if defined( BOOST_CORE_HAS_CXXABI_H ) +# include +// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library +// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement +// abi::__cxa_demangle(). We detect this implementation by checking the include guard here. +# if defined( __GABIXX_CXXABI_H__ ) +# undef BOOST_CORE_HAS_CXXABI_H +# else +# include +# include +# endif +#endif + +namespace boost +{ + +namespace core +{ + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT; +inline void demangle_free( char const * name ) BOOST_NOEXCEPT; + +class scoped_demangled_name +{ +private: + char const * m_p; + +public: + explicit scoped_demangled_name( char const * name ) BOOST_NOEXCEPT : + m_p( demangle_alloc( name ) ) + { + } + + ~scoped_demangled_name() BOOST_NOEXCEPT + { + demangle_free( m_p ); + } + + char const * get() const BOOST_NOEXCEPT + { + return m_p; + } + + BOOST_DELETED_FUNCTION(scoped_demangled_name( scoped_demangled_name const& )) + BOOST_DELETED_FUNCTION(scoped_demangled_name& operator= ( scoped_demangled_name const& )) +}; + + +#if defined( BOOST_CORE_HAS_CXXABI_H ) + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT +{ + int status = 0; + std::size_t size = 0; + return abi::__cxa_demangle( name, NULL, &size, &status ); +} + +inline void demangle_free( char const * name ) BOOST_NOEXCEPT +{ + std::free( const_cast< char* >( name ) ); +} + +inline std::string demangle( char const * name ) +{ + scoped_demangled_name demangled_name( name ); + char const * p = demangled_name.get(); + if( !p ) + p = name; + return p; +} + +#else + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT +{ + return name; +} + +inline void demangle_free( char const * ) BOOST_NOEXCEPT +{ +} + +inline std::string demangle( char const * name ) +{ + return name; +} + +#endif + +} // namespace core + +} // namespace boost + +#undef BOOST_CORE_HAS_CXXABI_H + +#endif // #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED diff --git a/boost/core/enable_if.hpp b/boost/core/enable_if.hpp new file mode 100644 index 00000000..5dcef1e0 --- /dev/null +++ b/boost/core/enable_if.hpp @@ -0,0 +1,128 @@ +// Boost enable_if library + +// Copyright 2003 (c) The Trustees of Indiana University. + +// 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) + +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) +// Jeremiah Willcock (jewillco at osl.iu.edu) +// Andrew Lumsdaine (lums at osl.iu.edu) + + +#ifndef BOOST_CORE_ENABLE_IF_HPP +#define BOOST_CORE_ENABLE_IF_HPP + +#include "boost/config.hpp" + +// Even the definition of enable_if causes problems on some compilers, +// so it's macroed out for all compilers that do not support SFINAE + +#ifndef BOOST_NO_SFINAE + +namespace boost +{ + template + struct enable_if_has_type + { + typedef R type; + }; + + template + struct enable_if_c { + typedef T type; + }; + + template + struct enable_if_c {}; + + template + struct enable_if : public enable_if_c {}; + + template + struct lazy_enable_if_c { + typedef typename T::type type; + }; + + template + struct lazy_enable_if_c {}; + + template + struct lazy_enable_if : public lazy_enable_if_c {}; + + + template + struct disable_if_c { + typedef T type; + }; + + template + struct disable_if_c {}; + + template + struct disable_if : public disable_if_c {}; + + template + struct lazy_disable_if_c { + typedef typename T::type type; + }; + + template + struct lazy_disable_if_c {}; + + template + struct lazy_disable_if : public lazy_disable_if_c {}; + +} // namespace boost + +#else + +namespace boost { + + namespace detail { typedef void enable_if_default_T; } + + template + struct enable_if_does_not_work_on_this_compiler; + + template + struct enable_if_has_type : enable_if_does_not_work_on_this_compiler + { }; + + template + struct enable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct disable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct enable_if : enable_if_does_not_work_on_this_compiler + { }; + + template + struct disable_if : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_enable_if : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_disable_if : enable_if_does_not_work_on_this_compiler + { }; + +} // namespace boost + +#endif // BOOST_NO_SFINAE + +#endif diff --git a/boost/core/explicit_operator_bool.hpp b/boost/core/explicit_operator_bool.hpp new file mode 100644 index 00000000..a8936e2c --- /dev/null +++ b/boost/core/explicit_operator_bool.hpp @@ -0,0 +1,154 @@ +/* + * Copyright Andrey Semashev 2007 - 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) + */ + +/*! + * \file explicit_operator_bool.hpp + * \author Andrey Semashev + * \date 08.03.2009 + * + * This header defines a compatibility macro that implements an unspecified + * \c bool operator idiom, which is superseded with explicit conversion operators in + * C++11. + */ + +#ifndef BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP +#define BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + +/*! + * \brief The macro defines an explicit operator of conversion to \c bool + * + * The macro should be used inside the definition of a class that has to + * support the conversion. The class should also implement operator!, + * in terms of which the conversion operator will be implemented. + */ +#define BOOST_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE explicit operator bool () const\ + {\ + return !this->operator! ();\ + } + +/*! + * \brief The macro defines a noexcept explicit operator of conversion to \c bool + * + * The macro should be used inside the definition of a class that has to + * support the conversion. The class should also implement operator!, + * in terms of which the conversion operator will be implemented. + */ +#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\ + BOOST_FORCEINLINE explicit operator bool () const BOOST_NOEXCEPT\ + {\ + return !this->operator! ();\ + } + +/*! + * \brief The macro defines a constexpr explicit operator of conversion to \c bool + * + * The macro should be used inside the definition of a class that has to + * support the conversion. The class should also implement operator!, + * in terms of which the conversion operator will be implemented. + */ +#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const BOOST_NOEXCEPT\ + {\ + return !this->operator! ();\ + } + +#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + +#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG) +// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it +#define BOOST_NO_UNSPECIFIED_BOOL +#endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG) + +#if !defined(BOOST_NO_UNSPECIFIED_BOOL) + +namespace boost { + +namespace detail { + +#if !defined(_MSC_VER) && !defined(__IBMCPP__) + + struct unspecified_bool + { + // NOTE TO THE USER: If you see this in error messages then you tried + // to apply an unsupported operator on the object that supports + // explicit conversion to bool. + struct OPERATORS_NOT_ALLOWED; + static void true_value(OPERATORS_NOT_ALLOWED*) {} + }; + typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*); + +#else + + // MSVC and VACPP are too eager to convert pointer to function to void* even though they shouldn't + struct unspecified_bool + { + // NOTE TO THE USER: If you see this in error messages then you tried + // to apply an unsupported operator on the object that supports + // explicit conversion to bool. + struct OPERATORS_NOT_ALLOWED; + void true_value(OPERATORS_NOT_ALLOWED*) {} + }; + typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*); + +#endif + +} // namespace detail + +} // namespace boost + +#define BOOST_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\ + {\ + return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\ + } + +#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\ + BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const BOOST_NOEXCEPT\ + {\ + return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\ + } + +#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const BOOST_NOEXCEPT\ + {\ + return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\ + } + +#else // !defined(BOOST_NO_UNSPECIFIED_BOOL) + +#define BOOST_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE operator bool () const\ + {\ + return !this->operator! ();\ + } + +#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\ + BOOST_FORCEINLINE operator bool () const BOOST_NOEXCEPT\ + {\ + return !this->operator! ();\ + } + +#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ + BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const BOOST_NOEXCEPT\ + {\ + return !this->operator! ();\ + } + +#endif // !defined(BOOST_NO_UNSPECIFIED_BOOL) + +#endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + +#endif // BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP diff --git a/boost/core/ignore_unused.hpp b/boost/core/ignore_unused.hpp new file mode 100644 index 00000000..994e5f64 --- /dev/null +++ b/boost/core/ignore_unused.hpp @@ -0,0 +1,70 @@ +// 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 { + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts const& ...) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +#else + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&) +{} + +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 const&, T2 const&, T3 const&, T4 const&) +{} + +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/boost/core/is_same.hpp b/boost/core/is_same.hpp new file mode 100644 index 00000000..f373c654 --- /dev/null +++ b/boost/core/is_same.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED +#define BOOST_CORE_IS_SAME_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// is_same::value is true when T1 == T2 +// +// Copyright 2014 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 core +{ + +template< class T1, class T2 > struct is_same +{ + BOOST_STATIC_CONSTANT( bool, value = false ); +}; + +template< class T > struct is_same< T, T > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +} // namespace core + +} // namespace boost + +#endif // #ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED diff --git a/boost/core/lightweight_test.hpp b/boost/core/lightweight_test.hpp new file mode 100644 index 00000000..73557be2 --- /dev/null +++ b/boost/core/lightweight_test.hpp @@ -0,0 +1,465 @@ +#ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP +#define BOOST_CORE_LIGHTWEIGHT_TEST_HPP + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) +# pragma once +#endif + +// +// boost/core/lightweight_test.hpp - lightweight test library +// +// Copyright (c) 2002, 2009, 2014 Peter Dimov +// Copyright (2) Beman Dawes 2010, 2011 +// Copyright (3) Ion Gaztanaga 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 +// + +#include +#include +#include +#include +#include +#include +#include + +// IDE's like Visual Studio perform better if output goes to std::cout or +// some other stream, so allow user to configure output stream: +#ifndef BOOST_LIGHTWEIGHT_TEST_OSTREAM +# define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cerr +#endif + +namespace boost +{ + +namespace detail +{ + +struct report_errors_reminder +{ + bool called_report_errors_function; + + report_errors_reminder() : called_report_errors_function(false) {} + + ~report_errors_reminder() + { + BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called + } +}; + +inline report_errors_reminder& report_errors_remind() +{ + static report_errors_reminder r; + return r; +} + +inline int & test_errors() +{ + static int x = 0; + report_errors_remind(); + return x; +} + +inline void test_failed_impl(char const * expr, char const * file, int line, char const * function) +{ + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr << "' failed in function '" + << function << "'" << std::endl; + ++test_errors(); +} + +inline void error_impl(char const * msg, char const * file, int line, char const * function) +{ + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): " << msg << " in function '" + << function << "'" << std::endl; + ++test_errors(); +} + +inline void throw_failed_impl(char const * excep, char const * file, int line, char const * function) +{ + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): Exception '" << excep << "' not thrown in function '" + << function << "'" << std::endl; + ++test_errors(); +} + +// In the comparisons below, it is possible that T and U are signed and unsigned integer types, which generates warnings in some compilers. +// A cleaner fix would require common_type trait or some meta-programming, which would introduce a dependency on Boost.TypeTraits. To avoid +// the dependency we just disable the warnings. +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4389) +#elif defined(__clang__) && defined(__has_warning) +# if __has_warning("-Wsign-compare") +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wsign-compare" +# endif +#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wsign-compare" +#endif + +// specialize test output for char pointers to avoid printing as cstring +template inline const T& test_output_impl(const T& v) { return v; } +inline const void* test_output_impl(const char* v) { return v; } +inline const void* test_output_impl(const unsigned char* v) { return v; } +inline const void* test_output_impl(const signed char* v) { return v; } +inline const void* test_output_impl(char* v) { return v; } +inline const void* test_output_impl(unsigned char* v) { return v; } +inline const void* test_output_impl(signed char* v) { return v; } +template inline const void* test_output_impl(T volatile* v) { return const_cast(v); } + +#if !defined( BOOST_NO_CXX11_NULLPTR ) +inline const void* test_output_impl(std::nullptr_t) { return nullptr; } +#endif + +template inline void test_eq_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, T const & t, U const & u ) +{ + if( t == u ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " == " << expr2 + << "' failed in function '" << function << "': " + << "'" << test_output_impl(t) << "' != '" << test_output_impl(u) << "'" << std::endl; + ++test_errors(); + } +} + +template inline void test_ne_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, T const & t, U const & u ) +{ + if( t != u ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " != " << expr2 + << "' failed in function '" << function << "': " + << "'" << test_output_impl(t) << "' == '" << test_output_impl(u) << "'" << std::endl; + ++test_errors(); + } +} + +template inline void test_lt_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, T const & t, U const & u ) +{ + if( t < u ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " < " << expr2 + << "' failed in function '" << function << "': " + << "'" << test_output_impl(t) << "' >= '" << test_output_impl(u) << "'" << std::endl; + ++test_errors(); + } +} + +template inline void test_le_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, T const & t, U const & u ) +{ + if( t <= u ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " <= " << expr2 + << "' failed in function '" << function << "': " + << "'" << test_output_impl(t) << "' > '" << test_output_impl(u) << "'" << std::endl; + ++test_errors(); + } +} + +template inline void test_gt_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, T const & t, U const & u ) +{ + if( t > u ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " > " << expr2 + << "' failed in function '" << function << "': " + << "'" << test_output_impl(t) << "' <= '" << test_output_impl(u) << "'" << std::endl; + ++test_errors(); + } +} + +template inline void test_ge_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, T const & t, U const & u ) +{ + if( t >= u ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " >= " << expr2 + << "' failed in function '" << function << "': " + << "'" << test_output_impl(t) << "' < '" << test_output_impl(u) << "'" << std::endl; + ++test_errors(); + } +} + +inline void test_cstr_eq_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, char const * const t, char const * const u ) +{ + if( std::strcmp(t, u) == 0 ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " == " << expr2 + << "' failed in function '" << function << "': " + << "'" << t << "' != '" << u << "'" << std::endl; + ++test_errors(); + } +} + +inline void test_cstr_ne_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, char const * const t, char const * const u ) +{ + if( std::strcmp(t, u) != 0 ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " == " << expr2 + << "' failed in function '" << function << "': " + << "'" << t << "' == '" << u << "'" << std::endl; + ++test_errors(); + } +} + +template +void test_all_eq_impl(FormattedOutputFunction& output, + char const * file, int line, char const * function, + InputIterator1 first_begin, InputIterator1 first_end, + InputIterator2 second_begin, InputIterator2 second_end) +{ + InputIterator1 first_it = first_begin; + InputIterator2 second_it = second_begin; + typename std::iterator_traits::difference_type first_index = 0; + typename std::iterator_traits::difference_type second_index = 0; + std::size_t error_count = 0; + const std::size_t max_count = 8; + do + { + while ((first_it != first_end) && (second_it != second_end) && (*first_it == *second_it)) + { + ++first_it; + ++second_it; + ++first_index; + ++second_index; + } + if ((first_it == first_end) || (second_it == second_end)) + { + break; // do-while + } + if (error_count == 0) + { + output << file << "(" << line << "): Container contents differ in function '" << function << "':"; + } + else if (error_count >= max_count) + { + output << " ..."; + break; + } + output << " [" << first_index << "] '" << test_output_impl(*first_it) << "' != '" << test_output_impl(*second_it) << "'"; + ++first_it; + ++second_it; + ++first_index; + ++second_index; + ++error_count; + } while (first_it != first_end); + + first_index += std::distance(first_it, first_end); + second_index += std::distance(second_it, second_end); + if (first_index != second_index) + { + if (error_count == 0) + { + output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")"; + } + else + { + output << " [*] size(" << first_index << ") != size(" << second_index << ")"; + } + ++error_count; + } + + if (error_count == 0) + { + boost::detail::report_errors_remind(); + } + else + { + output << std::endl; + ++boost::detail::test_errors(); + } +} + +template +void test_all_with_impl(FormattedOutputFunction& output, + char const * file, int line, char const * function, + InputIterator1 first_begin, InputIterator1 first_end, + InputIterator2 second_begin, InputIterator2 second_end, + BinaryPredicate predicate) +{ + InputIterator1 first_it = first_begin; + InputIterator2 second_it = second_begin; + typename std::iterator_traits::difference_type first_index = 0; + typename std::iterator_traits::difference_type second_index = 0; + std::size_t error_count = 0; + const std::size_t max_count = 8; + do + { + while ((first_it != first_end) && (second_it != second_end) && predicate(*first_it, *second_it)) + { + ++first_it; + ++second_it; + ++first_index; + ++second_index; + } + if ((first_it == first_end) || (second_it == second_end)) + { + break; // do-while + } + if (error_count == 0) + { + output << file << "(" << line << "): Container contents differ in function '" << function << "':"; + } + else if (error_count >= max_count) + { + output << " ..."; + break; + } + output << " [" << first_index << "]"; + ++first_it; + ++second_it; + ++first_index; + ++second_index; + ++error_count; + } while (first_it != first_end); + + first_index += std::distance(first_it, first_end); + second_index += std::distance(second_it, second_end); + if (first_index != second_index) + { + if (error_count == 0) + { + output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")"; + } + else + { + output << " [*] size(" << first_index << ") != size(" << second_index << ")"; + } + ++error_count; + } + + if (error_count == 0) + { + report_errors_remind(); + } + else + { + output << std::endl; + ++test_errors(); + } +} + +#if defined(_MSC_VER) +# pragma warning(pop) +#elif defined(__clang__) && defined(__has_warning) +# if __has_warning("-Wsign-compare") +# pragma clang diagnostic pop +# endif +#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 +# pragma GCC diagnostic pop +#endif + +} // namespace detail + +inline int report_errors() +{ + boost::detail::report_errors_remind().called_report_errors_function = true; + + int errors = boost::detail::test_errors(); + + if( errors == 0 ) + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << "No errors detected." << std::endl; + return 0; + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl; + return 1; + } +} + +} // namespace boost + +#define BOOST_TEST(expr) ((expr)? (void)0: ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)) +#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr)) + +#define BOOST_ERROR(msg) ( ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) + +#define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) +#define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) + +#define BOOST_TEST_LT(expr1,expr2) ( ::boost::detail::test_lt_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) +#define BOOST_TEST_LE(expr1,expr2) ( ::boost::detail::test_le_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) +#define BOOST_TEST_GT(expr1,expr2) ( ::boost::detail::test_gt_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) +#define BOOST_TEST_GE(expr1,expr2) ( ::boost::detail::test_ge_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) + +#define BOOST_TEST_CSTR_EQ(expr1,expr2) ( ::boost::detail::test_cstr_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) +#define BOOST_TEST_CSTR_NE(expr1,expr2) ( ::boost::detail::test_cstr_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) + +#define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) ( ::boost::detail::test_all_eq_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2) ) +#define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) ) + +#ifndef BOOST_NO_EXCEPTIONS + #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ + try { \ + EXPR; \ + ::boost::detail::throw_failed_impl \ + (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ + } \ + catch(EXCEP const&) { \ + } \ + catch(...) { \ + ::boost::detail::throw_failed_impl \ + (#EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ + } \ + // +#else + #define BOOST_TEST_THROWS( EXPR, EXCEP ) +#endif + +#endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP diff --git a/boost/core/no_exceptions_support.hpp b/boost/core/no_exceptions_support.hpp new file mode 100644 index 00000000..e2453d08 --- /dev/null +++ b/boost/core/no_exceptions_support.hpp @@ -0,0 +1,44 @@ +#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(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# define BOOST_TRY { if ("") +# define BOOST_CATCH(x) else if (!"") +# else +# define BOOST_TRY { if (true) +# define BOOST_CATCH(x) else if (false) +# endif +# define BOOST_RETHROW +# define BOOST_CATCH_END } +#endif + + +#endif diff --git a/boost/core/noncopyable.hpp b/boost/core/noncopyable.hpp new file mode 100644 index 00000000..6ae8c244 --- /dev/null +++ b/boost/core/noncopyable.hpp @@ -0,0 +1,48 @@ +// 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 +{ + class noncopyable + { + 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/boost/core/ref.hpp b/boost/core/ref.hpp new file mode 100644 index 00000000..7d768ffc --- /dev/null +++ b/boost/core/ref.hpp @@ -0,0 +1,301 @@ +#ifndef BOOST_CORE_REF_HPP +#define BOOST_CORE_REF_HPP + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +// +// ref.hpp - ref/cref, useful helper functions +// +// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) +// Copyright (C) 2001, 2002 Peter Dimov +// Copyright (C) 2002 David Abrahams +// +// Copyright (C) 2014 Glen Joseph Fernandes +// glenfe at live dot com +// Copyright (C) 2014 Agustin Berge +// +// 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/core/doc/html/core/ref.html for documentation. +// + +/** + @file +*/ + +/** + Boost namespace. +*/ +namespace boost +{ + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + struct ref_workaround_tag {}; + +#endif + +// reference_wrapper + +/** + @brief Contains a reference to an object of type `T`. + + `reference_wrapper` is primarily used to "feed" references to + function templates (algorithms) that take their parameter by + value. It provides an implicit conversion to `T&`, which + usually allows the function templates to work on references + unmodified. +*/ +template class reference_wrapper +{ +public: + /** + Type `T`. + */ + typedef T type; + + /** + Constructs a `reference_wrapper` object that stores a + reference to `t`. + + @remark Does not throw. + */ + BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {} + +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + /** + @remark Construction from a temporary object is disabled. + */ + BOOST_DELETED_FUNCTION(reference_wrapper(T&& t)) +public: +#endif + + /** + @return The stored reference. + @remark Does not throw. + */ + BOOST_FORCEINLINE operator T& () const { return *t_; } + + /** + @return The stored reference. + @remark Does not throw. + */ + BOOST_FORCEINLINE T& get() const { return *t_; } + + /** + @return A pointer to the object referenced by the stored + reference. + @remark Does not throw. + */ + BOOST_FORCEINLINE T* get_pointer() const { return t_; } + +private: + + T* t_; +}; + +// ref + +/** + @cond +*/ +#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) +# define BOOST_REF_CONST +#else +# define BOOST_REF_CONST const +#endif +/** + @endcond +*/ + +/** + @return `reference_wrapper(t)` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref( T & t ) +{ +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + return reference_wrapper( t, ref_workaround_tag() ); + +#else + + return reference_wrapper( t ); + +#endif +} + +// cref + +/** + @return `reference_wrapper(t)` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST cref( T const & t ) +{ + return reference_wrapper(t); +} + +#undef BOOST_REF_CONST + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +/** + @cond +*/ +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_REF_DELETE +#else +# define BOOST_REF_DELETE = delete +#endif +/** + @endcond +*/ + +/** + @remark Construction from a temporary object is disabled. +*/ +template void ref(T const&&) BOOST_REF_DELETE; + +/** + @remark Construction from a temporary object is disabled. +*/ +template void cref(T const&&) BOOST_REF_DELETE; + +#undef BOOST_REF_DELETE + +#endif + +// is_reference_wrapper + +/** + @brief Determine if a type `T` is an instantiation of + `reference_wrapper`. + + The value static constant will be true if the type `T` is a + specialization of `reference_wrapper`. +*/ +template struct is_reference_wrapper +{ + BOOST_STATIC_CONSTANT( bool, value = false ); +}; + +/** + @cond +*/ +template struct is_reference_wrapper< reference_wrapper > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +#if !defined(BOOST_NO_CV_SPECIALIZATIONS) + +template struct is_reference_wrapper< reference_wrapper const > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +template struct is_reference_wrapper< reference_wrapper volatile > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +template struct is_reference_wrapper< reference_wrapper const volatile > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS) + +/** + @endcond +*/ + + +// unwrap_reference + +/** + @brief Find the type in a `reference_wrapper`. + + The `typedef` type is `T::type` if `T` is a + `reference_wrapper`, `T` otherwise. +*/ +template struct unwrap_reference +{ + typedef T type; +}; + +/** + @cond +*/ +template struct unwrap_reference< reference_wrapper > +{ + typedef T type; +}; + +#if !defined(BOOST_NO_CV_SPECIALIZATIONS) + +template struct unwrap_reference< reference_wrapper const > +{ + typedef T type; +}; + +template struct unwrap_reference< reference_wrapper volatile > +{ + typedef T type; +}; + +template struct unwrap_reference< reference_wrapper const volatile > +{ + typedef T type; +}; + +#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS) + +/** + @endcond +*/ + +// unwrap_ref + +/** + @return `unwrap_reference::type&(t)` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE typename unwrap_reference::type& unwrap_ref( T & t ) +{ + return t; +} + +// get_pointer + +/** + @cond +*/ +template BOOST_FORCEINLINE T* get_pointer( reference_wrapper const & r ) +{ + return r.get_pointer(); +} +/** + @endcond +*/ + +} // namespace boost + +#endif // #ifndef BOOST_CORE_REF_HPP diff --git a/boost/core/scoped_enum.hpp b/boost/core/scoped_enum.hpp new file mode 100644 index 00000000..56dd0ede --- /dev/null +++ b/boost/core/scoped_enum.hpp @@ -0,0 +1,194 @@ +// scoped_enum.hpp ---------------------------------------------------------// + +// Copyright Beman Dawes, 2009 +// Copyright (C) 2011-2012 Vicente J. Botet Escriba +// Copyright (C) 2012 Anthony Williams + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CORE_SCOPED_ENUM_HPP +#define BOOST_CORE_SCOPED_ENUM_HPP + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost +{ + +#ifdef BOOST_NO_CXX11_SCOPED_ENUMS + + /** + * Meta-function to get the native enum type associated to an enum class or its emulation. + */ + template + struct native_type + { + /** + * The member typedef type names the native enum type associated to the scoped enum, + * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum. + */ + typedef typename EnumType::enum_type type; + }; + + /** + * Casts a scoped enum to its underlying type. + * + * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type. + * @param v A scoped enum. + * @returns The underlying type. + * @throws No-throws. + */ + template + inline + BOOST_CONSTEXPR UnderlyingType underlying_cast(EnumType v) BOOST_NOEXCEPT + { + return v.get_underlying_value_(); + } + + /** + * Casts a scoped enum to its native enum type. + * + * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can. + * + * EnumType the scoped enum type + * + * @param v A scoped enum. + * @returns The native enum value. + * @throws No-throws. + */ + template + inline + BOOST_CONSTEXPR typename EnumType::enum_type native_value(EnumType e) BOOST_NOEXCEPT + { + return e.get_native_value_(); + } + +#else // BOOST_NO_CXX11_SCOPED_ENUMS + + template + struct native_type + { + typedef EnumType type; + }; + + template + inline + BOOST_CONSTEXPR UnderlyingType underlying_cast(EnumType v) BOOST_NOEXCEPT + { + return static_cast(v); + } + + template + inline + BOOST_CONSTEXPR EnumType native_value(EnumType e) BOOST_NOEXCEPT + { + return e; + } + +#endif // BOOST_NO_CXX11_SCOPED_ENUMS +} + + +#ifdef BOOST_NO_CXX11_SCOPED_ENUMS + +#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS + +#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ + explicit BOOST_CONSTEXPR operator underlying_type() const BOOST_NOEXCEPT { return get_underlying_value_(); } + +#else + +#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR + +#endif + +/** + * Start a declaration of a scoped enum. + * + * @param EnumType The new scoped enum. + * @param UnderlyingType The underlying type. + */ +#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \ + struct EnumType { \ + typedef void is_boost_scoped_enum_tag; \ + typedef UnderlyingType underlying_type; \ + EnumType() BOOST_NOEXCEPT {} \ + explicit BOOST_CONSTEXPR EnumType(underlying_type v) BOOST_NOEXCEPT : v_(v) {} \ + BOOST_CONSTEXPR underlying_type get_underlying_value_() const BOOST_NOEXCEPT { return v_; } \ + BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \ + private: \ + underlying_type v_; \ + typedef EnumType self_type; \ + public: \ + enum enum_type + +#define BOOST_SCOPED_ENUM_DECLARE_END2() \ + BOOST_CONSTEXPR enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \ + friend BOOST_CONSTEXPR bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \ + friend BOOST_CONSTEXPR bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \ + friend BOOST_CONSTEXPR bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \ + friend BOOST_CONSTEXPR bool operator !=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \ + friend BOOST_CONSTEXPR bool operator !=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \ + friend BOOST_CONSTEXPR bool operator !=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \ + friend BOOST_CONSTEXPR bool operator <(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \ + friend BOOST_CONSTEXPR bool operator >(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \ + friend BOOST_CONSTEXPR bool operator >(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \ + friend BOOST_CONSTEXPR bool operator >=(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \ + friend BOOST_CONSTEXPR bool operator >=(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \ + friend BOOST_CONSTEXPR bool operator >=(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \ + }; + +#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) \ + ; \ + BOOST_CONSTEXPR EnumType(enum_type v) BOOST_NOEXCEPT : v_(v) {} \ + BOOST_SCOPED_ENUM_DECLARE_END2() + +/** + * Starts a declaration of a scoped enum with the default int underlying type. + * + * @param EnumType The new scoped enum. + */ +#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \ + BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int) + +/** + * Name of the native enum type. + * + * @param EnumType The new scoped enum. + */ +#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type +/** + * Forward declares an scoped enum. + * + * @param EnumType The scoped enum. + */ +#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType + +#else // BOOST_NO_CXX11_SCOPED_ENUMS + +#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType : UnderlyingType +#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType +#define BOOST_SCOPED_ENUM_DECLARE_END2() +#define BOOST_SCOPED_ENUM_DECLARE_END(EnumType) ; + +#define BOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType +#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType + +#endif // BOOST_NO_CXX11_SCOPED_ENUMS + +// Deprecated macros +#define BOOST_SCOPED_ENUM_START(name) BOOST_SCOPED_ENUM_DECLARE_BEGIN(name) +#define BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_DECLARE_END2() +#define BOOST_SCOPED_ENUM(name) BOOST_SCOPED_ENUM_NATIVE(name) + +#endif // BOOST_CORE_SCOPED_ENUM_HPP diff --git a/boost/core/swap.hpp b/boost/core/swap.hpp new file mode 100644 index 00000000..baa1be97 --- /dev/null +++ b/boost/core/swap.hpp @@ -0,0 +1,60 @@ +// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker +// +// 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) +// For more information, see http://www.boost.org + + +#ifndef BOOST_CORE_SWAP_HPP +#define BOOST_CORE_SWAP_HPP + +// Note: the implementation of this utility contains various workarounds: +// - swap_impl is put outside the boost namespace, to avoid infinite +// recursion (causing stack overflow) when swapping objects of a primitive +// type. +// - swap_impl has a using-directive, rather than a using-declaration, +// because some compilers (including MSVC 7.1, Borland 5.9.3, and +// Intel 8.1) don't do argument-dependent lookup when it has a +// using-declaration instead. +// - boost::swap has two template arguments, instead of one, to +// avoid ambiguity when swapping objects of a Boost type that does +// not have its own boost::swap overload. + +#include //for std::swap (C++11) +#include //for std::swap (C++98) +#include //for std::size_t +#include + +namespace boost_swap_impl +{ + template + BOOST_GPU_ENABLED + void swap_impl(T& left, T& right) + { + using namespace std;//use std::swap if argument dependent lookup fails + swap(left,right); + } + + template + BOOST_GPU_ENABLED + void swap_impl(T (& left)[N], T (& right)[N]) + { + for (std::size_t i = 0; i < N; ++i) + { + ::boost_swap_impl::swap_impl(left[i], right[i]); + } + } +} + +namespace boost +{ + template + BOOST_GPU_ENABLED + void swap(T1& left, T2& right) + { + ::boost_swap_impl::swap_impl(left, right); + } +} + +#endif diff --git a/boost/core/typeinfo.hpp b/boost/core/typeinfo.hpp new file mode 100644 index 00000000..e67b4a31 --- /dev/null +++ b/boost/core/typeinfo.hpp @@ -0,0 +1,151 @@ +#ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED +#define BOOST_CORE_TYPEINFO_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// core::typeinfo, BOOST_CORE_TYPEID +// +// Copyright 2007, 2014 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 + +#if defined( BOOST_NO_TYPEID ) + +#include +#include + +namespace boost +{ + +namespace core +{ + +class typeinfo +{ +private: + + typeinfo( typeinfo const& ); + typeinfo& operator=( typeinfo const& ); + + char const * name_; + +public: + + explicit typeinfo( char const * name ): name_( name ) + { + } + + bool operator==( typeinfo const& rhs ) const + { + return this == &rhs; + } + + bool operator!=( typeinfo const& rhs ) const + { + return this != &rhs; + } + + bool before( typeinfo const& rhs ) const + { + return std::less< typeinfo const* >()( this, &rhs ); + } + + char const* name() const + { + return name_; + } +}; + +inline char const * demangled_name( core::typeinfo const & ti ) +{ + return ti.name(); +} + +} // namespace core + +namespace detail +{ + +template struct core_typeid_ +{ + static boost::core::typeinfo ti_; + + static char const * name() + { + return BOOST_CURRENT_FUNCTION; + } +}; + +#if defined(__SUNPRO_CC) +// see #4199, the Sun Studio compiler gets confused about static initialization +// constructor arguments. But an assignment works just fine. +template boost::core::typeinfo core_typeid_< T >::ti_ = core_typeid_< T >::name(); +#else +template boost::core::typeinfo core_typeid_< T >::ti_(core_typeid_< T >::name()); +#endif + +template struct core_typeid_< T & >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T const >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T volatile >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T const volatile >: core_typeid_< T > +{ +}; + +} // namespace detail + +} // namespace boost + +#define BOOST_CORE_TYPEID(T) (boost::detail::core_typeid_::ti_) + +#else + +#include +#include + +namespace boost +{ + +namespace core +{ + +#if defined( BOOST_NO_STD_TYPEINFO ) + +typedef ::type_info typeinfo; + +#else + +typedef std::type_info typeinfo; + +#endif + +inline std::string demangled_name( core::typeinfo const & ti ) +{ + return core::demangle( ti.name() ); +} + +} // namespace core + +} // namespace boost + +#define BOOST_CORE_TYPEID(T) typeid(T) + +#endif + +#endif // #ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED diff --git a/boost/cregex.hpp b/boost/cregex.hpp new file mode 100644 index 00000000..b7a918eb --- /dev/null +++ b/boost/cregex.hpp @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * 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/libs/regex for most recent version. + * FILE cregex.cpp + * VERSION see + * DESCRIPTION: Declares POSIX API functions + * + boost::RegEx high level wrapper. + */ + +#ifndef BOOST_RE_CREGEX_HPP +#define BOOST_RE_CREGEX_HPP + +#ifndef BOOST_REGEX_CONFIG_HPP +#include +#endif + +#include + +#endif /* include guard */ + + + + + + + + + + diff --git a/boost/cstdint.hpp b/boost/cstdint.hpp new file mode 100644 index 00000000..c8474c46 --- /dev/null +++ b/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(__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 __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/boost/cstdlib.hpp b/boost/cstdlib.hpp new file mode 100644 index 00000000..63221463 --- /dev/null +++ b/boost/cstdlib.hpp @@ -0,0 +1,41 @@ +// boost/cstdlib.hpp header ------------------------------------------------// + +// Copyright Beman Dawes 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/utility/cstdlib.html for documentation. + +// Revision History +// 26 Feb 01 Initial version (Beman Dawes) + +#ifndef BOOST_CSTDLIB_HPP +#define BOOST_CSTDLIB_HPP + +#include + +namespace boost +{ + // The intent is to propose the following for addition to namespace std + // in the C++ Standard Library, and to then deprecate EXIT_SUCCESS and + // EXIT_FAILURE. As an implementation detail, this header defines the + // new constants in terms of EXIT_SUCCESS and EXIT_FAILURE. In a new + // standard, the constants would be implementation-defined, although it + // might be worthwhile to "suggest" (which a standard is allowed to do) + // values of 0 and 1 respectively. + + // Rationale for having multiple failure values: some environments may + // wish to distinguish between different classes of errors. + // Rationale for choice of values: programs often use values < 100 for + // their own error reporting. Values > 255 are sometimes reserved for + // system detected errors. 200/201 were suggested to minimize conflict. + + const int exit_success = EXIT_SUCCESS; // implementation-defined value + const int exit_failure = EXIT_FAILURE; // implementation-defined value + const int exit_exception_failure = 200; // otherwise uncaught exception + const int exit_test_failure = 201; // report_error or + // report_critical_error called. +} + +#endif + diff --git a/boost/current_function.hpp b/boost/current_function.hpp new file mode 100644 index 00000000..86955cb0 --- /dev/null +++ b/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 (c) 2002 Peter Dimov and Multi Media Ltd. +// +// 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/current_function.html +// + +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__) + +# 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/boost/date_time/adjust_functors.hpp b/boost/date_time/adjust_functors.hpp new file mode 100644 index 00000000..ec2a7076 --- /dev/null +++ b/boost/date_time/adjust_functors.hpp @@ -0,0 +1,164 @@ +#ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___ +#define _DATE_TIME_ADJUST_FUNCTORS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/date.hpp" +#include "boost/date_time/wrapping_int.hpp" + +namespace boost { +namespace date_time { + + + //! Functor to iterate a fixed number of days + template + class day_functor + { + public: + typedef typename date_type::duration_type duration_type; + day_functor(int f) : f_(f) {} + duration_type get_offset(const date_type&) const + { + return duration_type(f_); + } + duration_type get_neg_offset(const date_type&) const + { + return duration_type(-f_); + } + private: + int f_; + }; + + + //! Provides calculation to find next nth month given a date + /*! This adjustment function provides the logic for 'month-based' + * advancement on a ymd based calendar. The policy it uses + * to handle the non existant end of month days is to back + * up to the last day of the month. Also, if the starting + * date is the last day of a month, this functor will attempt + * to adjust to the end of the month. + + */ + template + class month_functor + { + public: + typedef typename date_type::duration_type duration_type; + typedef typename date_type::calendar_type cal_type; + typedef typename cal_type::ymd_type ymd_type; + typedef typename cal_type::day_type day_type; + + month_functor(int f) : f_(f), origDayOfMonth_(0) {} + duration_type get_offset(const date_type& d) const + { + ymd_type ymd(d.year_month_day()); + if (origDayOfMonth_ == 0) { + origDayOfMonth_ = ymd.day; + day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month)); + if (endOfMonthDay == ymd.day) { + origDayOfMonth_ = -1; //force the value to the end of month + } + } + typedef date_time::wrapping_int2 wrap_int2; + wrap_int2 wi(ymd.month); + //calc the year wrap around, add() returns 0 or 1 if wrapped + const typename ymd_type::year_type year(static_cast(ymd.year + wi.add(f_))); +// std::cout << "trace wi: " << wi.as_int() << std::endl; +// std::cout << "trace year: " << year << std::endl; + //find the last day for the new month + day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int())); + //original was the end of month -- force to last day of month + if (origDayOfMonth_ == -1) { + return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d; + } + day_type dayOfMonth = origDayOfMonth_; + if (dayOfMonth > resultingEndOfMonthDay) { + dayOfMonth = resultingEndOfMonthDay; + } + return date_type(year, wi.as_int(), dayOfMonth) - d; + } + //! Returns a negative duration_type + duration_type get_neg_offset(const date_type& d) const + { + ymd_type ymd(d.year_month_day()); + if (origDayOfMonth_ == 0) { + origDayOfMonth_ = ymd.day; + day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month)); + if (endOfMonthDay == ymd.day) { + origDayOfMonth_ = -1; //force the value to the end of month + } + } + typedef date_time::wrapping_int2 wrap_int2; + wrap_int2 wi(ymd.month); + //calc the year wrap around, add() returns 0 or 1 if wrapped + const typename ymd_type::year_type year(static_cast(ymd.year + wi.subtract(f_))); + //find the last day for the new month + day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int())); + //original was the end of month -- force to last day of month + if (origDayOfMonth_ == -1) { + return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d; + } + day_type dayOfMonth = origDayOfMonth_; + if (dayOfMonth > resultingEndOfMonthDay) { + dayOfMonth = resultingEndOfMonthDay; + } + return date_type(year, wi.as_int(), dayOfMonth) - d; + } + private: + int f_; + mutable short origDayOfMonth_; + }; + + + //! Functor to iterate a over weeks + template + class week_functor + { + public: + typedef typename date_type::duration_type duration_type; + typedef typename date_type::calendar_type calendar_type; + week_functor(int f) : f_(f) {} + duration_type get_offset(const date_type&) const + { + return duration_type(f_*static_cast(calendar_type::days_in_week())); + } + duration_type get_neg_offset(const date_type&) const + { + return duration_type(-f_*static_cast(calendar_type::days_in_week())); + } + private: + int f_; + }; + + //! Functor to iterate by a year adjusting for leap years + template + class year_functor + { + public: + //typedef typename date_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + year_functor(int f) : _mf(f * 12) {} + duration_type get_offset(const date_type& d) const + { + return _mf.get_offset(d); + } + duration_type get_neg_offset(const date_type& d) const + { + return _mf.get_neg_offset(d); + } + private: + month_functor _mf; + }; + + +} }//namespace date_time + + +#endif + diff --git a/boost/date_time/c_time.hpp b/boost/date_time/c_time.hpp new file mode 100644 index 00000000..0b07a1b2 --- /dev/null +++ b/boost/date_time/c_time.hpp @@ -0,0 +1,123 @@ +#ifndef DATE_TIME_C_TIME_HPP___ +#define DATE_TIME_C_TIME_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +/*! @file c_time.hpp + Provide workarounds related to the ctime header +*/ + +#include +#include // to be able to convert from string literals to exceptions +#include +#include +#include + +//Work around libraries that don't put time_t and time in namespace std +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::time_t; using ::time; using ::localtime; + using ::tm; using ::gmtime; } +#endif // BOOST_NO_STDC_NAMESPACE + +//The following is used to support high precision time clocks +#ifdef BOOST_HAS_GETTIMEOFDAY +#include +#endif + +#ifdef BOOST_HAS_FTIME +#include +#endif + +namespace boost { +namespace date_time { + //! Provides a uniform interface to some 'ctime' functions + /*! Provides a uniform interface to some ctime functions and + * their '_r' counterparts. The '_r' functions require a pointer to a + * user created std::tm struct whereas the regular functions use a + * staticly created struct and return a pointer to that. These wrapper + * functions require the user to create a std::tm struct and send in a + * pointer to it. This struct may be used to store the resulting time. + * The returned pointer may or may not point to this struct, however, + * it will point to the result of the corresponding function. + * All functions do proper checking of the C function results and throw + * exceptions on error. Therefore the functions will never return NULL. + */ + struct c_time { + public: +#if defined(BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS) + //! requires a pointer to a user created std::tm struct + inline + static std::tm* localtime(const std::time_t* t, std::tm* result) + { + // localtime_r() not in namespace std??? +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 + std::tm tmp; + if(!localtime_r(t,&tmp)) + result = 0; + else + *result = tmp; +#else + result = localtime_r(t, result); +#endif + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to local time")); + return result; + } + //! requires a pointer to a user created std::tm struct + inline + static std::tm* gmtime(const std::time_t* t, std::tm* result) + { + // gmtime_r() not in namespace std??? +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 + std::tm tmp; + if(!gmtime_r(t,&tmp)) + result = 0; + else + *result = tmp; +#else + result = gmtime_r(t, result); +#endif + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time")); + return result; + } +#else // BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS + +#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) +#pragma warning(push) // preserve warning settings +#pragma warning(disable : 4996) // disable depricated localtime/gmtime warning on vc8 +#endif // _MSC_VER >= 1400 + //! requires a pointer to a user created std::tm struct + inline + static std::tm* localtime(const std::time_t* t, std::tm* result) + { + result = std::localtime(t); + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to local time")); + return result; + } + //! requires a pointer to a user created std::tm struct + inline + static std::tm* gmtime(const std::time_t* t, std::tm* result) + { + result = std::gmtime(t); + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time")); + return result; + } +#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) +#pragma warning(pop) // restore warnings to previous state +#endif // _MSC_VER >= 1400 + +#endif // BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS + }; +}} // namespaces + +#endif // DATE_TIME_C_TIME_HPP___ diff --git a/boost/date_time/compiler_config.hpp b/boost/date_time/compiler_config.hpp new file mode 100644 index 00000000..e37d0614 --- /dev/null +++ b/boost/date_time/compiler_config.hpp @@ -0,0 +1,169 @@ +#ifndef DATE_TIME_COMPILER_CONFIG_HPP___ +#define DATE_TIME_COMPILER_CONFIG_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include + +// With boost release 1.33, date_time will be using a different, +// more flexible, IO system. This new system is not compatible with +// old compilers. The original date_time IO system remains for those +// compilers. They must define this macro to use the legacy IO. +// (defined(__BORLANDC__) && (__BORLANDC__ <= 0x0581) ) ) && + #if( BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) \ + || BOOST_WORKAROUND( __GNUC__, < 3) \ + || (BOOST_WORKAROUND( _MSC_VER, <= 1300) ) \ + ) \ + && !defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +# define USE_DATE_TIME_PRE_1_33_FACET_IO +#endif + + +// This file performs some local compiler configurations + +#include //set up locale configurations + +//Set up a configuration parameter for platforms that have +//GetTimeOfDay +#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME) +#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK +#endif + +// To Force no default constructors for date & ptime, un-comment following +//#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR + +// Include extensions to date_duration - comment out to remove this feature +#define BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES +// these extensions are known to cause problems with gcc295 +#if defined(__GNUC__) && (__GNUC__ < 3) +#undef BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES +#endif + +#if (defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) || BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) ) +#define BOOST_DATE_TIME_NO_MEMBER_INIT +#endif + +// include these types before we try to re-define them +#include + +//Define INT64_C for compilers that don't have it +#if (!defined(INT64_C)) +#define INT64_C(value) int64_t(value) +#endif + + +/* Workaround for Borland iterator error. Error was "Cannot convert 'istream *' to 'wistream *' in function istream_iterator<>::istream_iterator() */ +#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_RW_LIB) +#define BOOST_DATE_TIME_NO_WISTREAM_ITERATOR +#endif + + +// Borland v5.64 does not have the following in std namespace; v5.5.1 does +#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_STLPORT) +#include +namespace std { + using stlport::tolower; + using stlport::ctype; + using stlport::use_facet; +} +#endif + +// workaround for errors associated with output for date classes +// modifications and input streaming for time classes. +// Compilers affected are: +// gcc295, msvc (neither with STLPort), any borland +// +#if (((defined(__GNUC__) && (__GNUC__ < 3)) || \ + (defined(_MSC_VER) && (_MSC_VER < 1300)) ) && \ + !defined(_STLP_OWN_IOSTREAMS) ) || \ + BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) +#define BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS +#endif + +// The macro marks up places where compiler complains for missing return statement or +// uninitialized variables after calling to boost::throw_exception. +// BOOST_UNREACHABLE_RETURN doesn't work since even compilers that support +// unreachable statements detection emit such warnings. +#if defined(_MSC_VER) +// Use special MSVC extension to markup unreachable code +# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) __assume(false) +#elif !defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION) +// Call to a non-returning function should suppress the warning +# if defined(BOOST_NO_STDC_NAMESPACE) +namespace std { + using ::abort; +} +# endif // defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) std::abort() +#else +// For other poor compilers the specified expression is compiled. Usually, this would be a return statement. +# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) x +#endif + +/* The following handles the definition of the necessary macros + * for dll building on Win32 platforms. + * + * For code that will be placed in the date_time .dll, + * it must be properly prefixed with BOOST_DATE_TIME_DECL. + * The corresponding .cpp file must have BOOST_DATE_TIME_SOURCE + * defined before including its header. For examples see: + * greg_month.hpp & greg_month.cpp + * + */ + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_DATE_TIME_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK) + // export if this is our own source, otherwise import: +# ifdef BOOST_DATE_TIME_SOURCE +# define BOOST_DATE_TIME_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_DATE_TIME_DECL BOOST_SYMBOL_IMPORT +# endif // BOOST_DATE_TIME_SOURCE +#endif // DYN_LINK +// +// if BOOST_WHATEVER_DECL isn't defined yet define it now: +#ifndef BOOST_DATE_TIME_DECL +# define BOOST_DATE_TIME_DECL +#endif + +// +// Automatically link to the correct build variant where possible. +// +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_date_time +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#if defined(BOOST_HAS_THREADS) +# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) || defined(__BORLANDC__) + //no reentrant posix functions (eg: localtime_r) +# elif (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT))) +# define BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS +# endif +#endif + + +#endif diff --git a/boost/date_time/constrained_value.hpp b/boost/date_time/constrained_value.hpp new file mode 100644 index 00000000..b1122d76 --- /dev/null +++ b/boost/date_time/constrained_value.hpp @@ -0,0 +1,121 @@ +#ifndef CONSTRAINED_VALUE_HPP___ +#define CONSTRAINED_VALUE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include +#include + +namespace boost { + +//! Namespace containing constrained_value template and types +namespace CV { + //! Represent a min or max violation type + enum violation_enum {min_violation, max_violation}; + + //! A template to specify a constrained basic value type + /*! This template provides a quick way to generate + * an integer type with a constrained range. The type + * provides for the ability to specify the min, max, and + * and error handling policy. + * + * value policies + * A class that provides the range limits via the min and + * max functions as well as a function on_error that + * determines how errors are handled. A common strategy + * would be to assert or throw and exception. The on_error + * is passed both the current value and the new value that + * is in error. + * + */ + template + class BOOST_SYMBOL_VISIBLE constrained_value { + public: + typedef typename value_policies::value_type value_type; + // typedef except_type exception_type; + constrained_value(value_type value) : value_((min)()) + { + assign(value); + } + constrained_value& operator=(value_type v) + { + assign(v); + return *this; + } + //! Return the max allowed value (traits method) + static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();} + //! Return the min allowed value (traits method) + static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();} + //! Coerce into the representation type + operator value_type() const {return value_;} + protected: + value_type value_; + private: + void assign(value_type value) + { + //adding 1 below gets rid of a compiler warning which occurs when the + //min_value is 0 and the type is unsigned.... + if (value+1 < (min)()+1) { + value_policies::on_error(value_, value, min_violation); + return; + } + if (value > (max)()) { + value_policies::on_error(value_, value, max_violation); + return; + } + value_ = value; + } +}; + + //! Template to shortcut the constrained_value policy creation process + template + class BOOST_SYMBOL_VISIBLE simple_exception_policy + { + struct BOOST_SYMBOL_VISIBLE exception_wrapper : public exception_type + { + // In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode, + // we'll have to provide a way to acquire std::exception from the exception being thrown. + // However, we cannot derive from it, since it would make it interceptable by this class, + // which might not be what the user wanted. + operator std::out_of_range () const + { + // TODO: Make the message more descriptive by using arguments to on_error + return std::out_of_range("constrained value boundary has been violated"); + } + }; + + typedef typename mpl::if_< + is_base_of< std::exception, exception_type >, + exception_type, + exception_wrapper + >::type actual_exception_type; + + public: + typedef rep_type value_type; + static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; } + static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; } + static void on_error(rep_type, rep_type, violation_enum) + { + boost::throw_exception(actual_exception_type()); + } + }; + + + +} } //namespace CV + + + + +#endif diff --git a/boost/date_time/date.hpp b/boost/date_time/date.hpp new file mode 100644 index 00000000..18333fd3 --- /dev/null +++ b/boost/date_time/date.hpp @@ -0,0 +1,209 @@ +#ifndef DATE_TIME_DATE_HPP___ +#define DATE_TIME_DATE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //!Representation of timepoint at the one day level resolution. + /*! + The date template represents an interface shell for a date class + that is based on a year-month-day system such as the gregorian + or iso systems. It provides basic operations to enable calculation + and comparisons. + + Theory + + This date representation fundamentally departs from the C tm struct + approach. The goal for this type is to provide efficient date + operations (add, subtract) and storage (minimize space to represent) + in a concrete class. Thus, the date uses a count internally to + represent a particular date. The calendar parameter defines + the policies for converting the the year-month-day and internal + counted form here. Applications that need to perform heavy + formatting of the same date repeatedly will perform better + by using the year-month-day representation. + + Internally the date uses a day number to represent the date. + This is a monotonic time representation. This representation + allows for fast comparison as well as simplifying + the creation of writing numeric operations. Essentially, the + internal day number is like adjusted julian day. The adjustment + is determined by the Epoch date which is represented as day 1 of + the calendar. Day 0 is reserved for negative infinity so that + any actual date is automatically greater than negative infinity. + When a date is constructed from a date or formatted for output, + the appropriate conversions are applied to create the year, month, + day representations. + */ + + + template + class BOOST_SYMBOL_VISIBLE date : private + boost::less_than_comparable > + { + public: + typedef T date_type; + typedef calendar calendar_type; + typedef typename calendar::date_traits_type traits_type; + typedef duration_type_ duration_type; + typedef typename calendar::year_type year_type; + typedef typename calendar::month_type month_type; + typedef typename calendar::day_type day_type; + typedef typename calendar::ymd_type ymd_type; + typedef typename calendar::date_rep_type date_rep_type; + typedef typename calendar::date_int_type date_int_type; + typedef typename calendar::day_of_week_type day_of_week_type; + date(year_type y, month_type m, day_type d) + : days_(calendar::day_number(ymd_type(y, m, d))) + {} + date(const ymd_type& ymd) + : days_(calendar::day_number(ymd)) + {} + //let the compiler write copy, assignment, and destructor + year_type year() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.year; + } + month_type month() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.month; + } + day_type day() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.day; + } + day_of_week_type day_of_week() const + { + ymd_type ymd = calendar::from_day_number(days_); + return calendar::day_of_week(ymd); + } + ymd_type year_month_day() const + { + return calendar::from_day_number(days_); + } + bool operator<(const date_type& rhs) const + { + return days_ < rhs.days_; + } + bool operator==(const date_type& rhs) const + { + return days_ == rhs.days_; + } + //! check to see if date is a special value + bool is_special()const + { + return(is_not_a_date() || is_infinity()); + } + //! check to see if date is not a value + bool is_not_a_date() const + { + return traits_type::is_not_a_number(days_); + } + //! check to see if date is one of the infinity values + bool is_infinity() const + { + return traits_type::is_inf(days_); + } + //! check to see if date is greater than all possible dates + bool is_pos_infinity() const + { + return traits_type::is_pos_inf(days_); + } + //! check to see if date is greater than all possible dates + bool is_neg_infinity() const + { + return traits_type::is_neg_inf(days_); + } + //! return as a special value or a not_special if a normal date + special_values as_special() const + { + return traits_type::to_special(days_); + } + duration_type operator-(const date_type& d) const + { + if (!this->is_special() && !d.is_special()) + { + // The duration underlying type may be wider than the date underlying type. + // Thus we calculate the difference in terms of two durations from some common fixed base date. + typedef typename duration_type::duration_rep_type duration_rep_type; + return duration_type(static_cast< duration_rep_type >(days_) - static_cast< duration_rep_type >(d.days_)); + } + else + { + // In this case the difference will be a special value, too + date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_); + return duration_type(val.as_special()); + } + } + + date_type operator-(const duration_type& dd) const + { + if(dd.is_special()) + { + return date_type(date_rep_type(days_) - dd.get_rep()); + } + return date_type(date_rep_type(days_) - static_cast(dd.days())); + } + date_type operator-=(const duration_type& dd) + { + *this = *this - dd; + return date_type(days_); + } + date_rep_type day_count() const + { + return days_; + } + //allow internal access from operators + date_type operator+(const duration_type& dd) const + { + if(dd.is_special()) + { + return date_type(date_rep_type(days_) + dd.get_rep()); + } + return date_type(date_rep_type(days_) + static_cast(dd.days())); + } + date_type operator+=(const duration_type& dd) + { + *this = *this + dd; + return date_type(days_); + } + + //see reference + protected: + /*! This is a private constructor which allows for the creation of new + dates. It is not exposed to users since that would require class + users to understand the inner workings of the date class. + */ + explicit date(date_int_type days) : days_(days) {} + explicit date(date_rep_type days) : days_(days.as_number()) {} + date_int_type days_; + + }; + + + + +} } // namespace date_time + + + + +#endif diff --git a/boost/date_time/date_clock_device.hpp b/boost/date_time/date_clock_device.hpp new file mode 100644 index 00000000..2145d65f --- /dev/null +++ b/boost/date_time/date_clock_device.hpp @@ -0,0 +1,77 @@ +#ifndef DATE_CLOCK_DEVICE_HPP___ +#define DATE_CLOCK_DEVICE_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/c_time.hpp" + + +namespace boost { +namespace date_time { + + //! A clock providing day level services based on C time_t capabilities + /*! This clock uses Posix interfaces as its implementation and hence + * uses the timezone settings of the operating system. Incorrect + * user settings will result in incorrect results for the calls + * to local_day. + */ + template + class day_clock + { + public: + typedef typename date_type::ymd_type ymd_type; + //! Get the local day as a date type + static date_type local_day() + { + return date_type(local_day_ymd()); + } + //! Get the local day as a ymd_type + static typename date_type::ymd_type local_day_ymd() + { + ::std::tm result; + ::std::tm* curr = get_local_time(result); + return ymd_type(static_cast(curr->tm_year + 1900), + static_cast(curr->tm_mon + 1), + static_cast(curr->tm_mday)); + } + //! Get the current day in universal date as a ymd_type + static typename date_type::ymd_type universal_day_ymd() + { + ::std::tm result; + ::std::tm* curr = get_universal_time(result); + return ymd_type(static_cast(curr->tm_year + 1900), + static_cast(curr->tm_mon + 1), + static_cast(curr->tm_mday)); + } + //! Get the UTC day as a date type + static date_type universal_day() + { + return date_type(universal_day_ymd()); + } + + private: + static ::std::tm* get_local_time(std::tm& result) + { + ::std::time_t t; + ::std::time(&t); + return c_time::localtime(&t, &result); + } + static ::std::tm* get_universal_time(std::tm& result) + { + ::std::time_t t; + ::std::time(&t); + return c_time::gmtime(&t, &result); + } + + }; + +} } //namespace date_time + + +#endif diff --git a/boost/date_time/date_defs.hpp b/boost/date_time/date_defs.hpp new file mode 100644 index 00000000..6c80db3a --- /dev/null +++ b/boost/date_time/date_defs.hpp @@ -0,0 +1,26 @@ +#ifndef DATE_TIME_DATE_DEFS_HPP +#define DATE_TIME_DATE_DEFS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + + +namespace boost { +namespace date_time { + + //! An enumeration of weekday names + enum weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; + + //! Simple enum to allow for nice programming with Jan, Feb, etc + enum months_of_year {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths}; + +} } //namespace date_time + + + +#endif diff --git a/boost/date_time/date_duration.hpp b/boost/date_time/date_duration.hpp new file mode 100644 index 00000000..82c75b42 --- /dev/null +++ b/boost/date_time/date_duration.hpp @@ -0,0 +1,151 @@ +#ifndef DATE_TIME_DATE_DURATION__ +#define DATE_TIME_DATE_DURATION__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Duration type with date level resolution + template + class BOOST_SYMBOL_VISIBLE date_duration : private + boost::less_than_comparable1< date_duration< duration_rep_traits > + , boost::equality_comparable1< date_duration< duration_rep_traits > + , boost::addable1< date_duration< duration_rep_traits > + , boost::subtractable1< date_duration< duration_rep_traits > + , boost::dividable2< date_duration< duration_rep_traits >, int + > > > > > + { + public: + typedef typename duration_rep_traits::int_type duration_rep_type; + typedef typename duration_rep_traits::impl_type duration_rep; + + //! Construct from a day count + explicit date_duration(duration_rep day_count) : days_(day_count) {} + + /*! construct from special_values - only works when + * instantiated with duration_traits_adapted */ + date_duration(special_values sv) : + days_(duration_rep::from_special(sv)) + {} + + // copy constructor required for addable<> & subtractable<> + //! Construct from another date_duration (Copy Constructor) + date_duration(const date_duration& other) : + days_(other.days_) + {} + + //! returns days_ as it's instantiated type - used for streaming + duration_rep get_rep()const + { + return days_; + } + special_values as_special() const + { + return days_.as_special(); + } + bool is_special()const + { + return days_.is_special(); + } + //! returns days as value, not object. + duration_rep_type days() const + { + return duration_rep_traits::as_number(days_); + } + //! Returns the smallest duration -- used by to calculate 'end' + static date_duration unit() + { + return date_duration(1); + } + //! Equality + bool operator==(const date_duration& rhs) const + { + return days_ == rhs.days_; + } + //! Less + bool operator<(const date_duration& rhs) const + { + return days_ < rhs.days_; + } + + /* For shortcut operators (+=, -=, etc) simply using + * "days_ += days_" may not work. If instantiated with + * an int_adapter, shortcut operators are not present, + * so this will not compile */ + + //! Subtract another duration -- result is signed + date_duration& operator-=(const date_duration& rhs) + { + //days_ -= rhs.days_; + days_ = days_ - rhs.days_; + return *this; + } + //! Add a duration -- result is signed + date_duration& operator+=(const date_duration& rhs) + { + days_ = days_ + rhs.days_; + return *this; + } + + //! unary- Allows for dd = -date_duration(2); -> dd == -2 + date_duration operator-() const + { + return date_duration(get_rep() * (-1)); + } + //! Division operations on a duration with an integer. + date_duration& operator/=(int divisor) + { + days_ = days_ / divisor; + return *this; + } + + //! return sign information + bool is_negative() const + { + return days_ < 0; + } + + private: + duration_rep days_; + }; + + + /*! Struct for instantiating date_duration with NO special values + * functionality. Allows for transparent implementation of either + * date_duration or date_duration > */ + struct BOOST_SYMBOL_VISIBLE duration_traits_long + { + typedef long int_type; + typedef long impl_type; + static int_type as_number(impl_type i) { return i; } + }; + + /*! Struct for instantiating date_duration WITH special values + * functionality. Allows for transparent implementation of either + * date_duration or date_duration > */ + struct BOOST_SYMBOL_VISIBLE duration_traits_adapted + { + typedef long int_type; + typedef boost::date_time::int_adapter impl_type; + static int_type as_number(impl_type i) { return i.as_number(); } + }; + + +} } //namspace date_time + + +#endif + diff --git a/boost/date_time/date_duration_types.hpp b/boost/date_time/date_duration_types.hpp new file mode 100644 index 00000000..7271d019 --- /dev/null +++ b/boost/date_time/date_duration_types.hpp @@ -0,0 +1,270 @@ +#ifndef DATE_DURATION_TYPES_HPP___ +#define DATE_DURATION_TYPES_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or + * http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Additional duration type that represents a number of n*7 days + template + class BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration { + public: + weeks_duration(typename duration_config::impl_type w) + : date_duration(w * 7) {} + weeks_duration(special_values sv) + : date_duration(sv) {} + }; + + // predeclare + template + class BOOST_SYMBOL_VISIBLE years_duration; + + //! additional duration type that represents a logical month + /*! A logical month enables things like: "date(2002,Mar,2) + months(2) -> + * 2002-May2". If the date is a last day-of-the-month, the result will + * also be a last-day-of-the-month. + */ + template + class BOOST_SYMBOL_VISIBLE months_duration + { + private: + typedef typename base_config::int_rep int_rep; + typedef typename int_rep::int_type int_type; + typedef typename base_config::date_type date_type; + typedef typename date_type::duration_type duration_type; + typedef typename base_config::month_adjustor_type month_adjustor_type; + typedef months_duration months_type; + typedef years_duration years_type; + public: + months_duration(int_rep num) : _m(num) {} + months_duration(special_values sv) : _m(sv) + { + _m = int_rep::from_special(sv); + } + int_rep number_of_months() const { return _m; } + //! returns a negative duration + duration_type get_neg_offset(const date_type& d) const + { + month_adjustor_type m_adj(_m.as_number()); + return duration_type(m_adj.get_neg_offset(d)); + } + duration_type get_offset(const date_type& d) const + { + month_adjustor_type m_adj(_m.as_number()); + return duration_type(m_adj.get_offset(d)); + } + bool operator==(const months_type& rhs) const + { + return(_m == rhs._m); + } + bool operator!=(const months_type& rhs) const + { + return(_m != rhs._m); + } + months_type operator+(const months_type& rhs)const + { + return months_type(_m + rhs._m); + } + months_type& operator+=(const months_type& rhs) + { + _m = _m + rhs._m; + return *this; + } + months_type operator-(const months_type& rhs)const + { + return months_type(_m - rhs._m); + } + months_type& operator-=(const months_type& rhs) + { + _m = _m - rhs._m; + return *this; + } + months_type operator*(const int_type rhs)const + { + return months_type(_m * rhs); + } + months_type& operator*=(const int_type rhs) + { + _m = _m * rhs; + return *this; + } + months_type operator/(const int_type rhs)const + { + return months_type(_m / rhs); + } + months_type& operator/=(const int_type rhs) + { + _m = _m / rhs; + return *this; + } + months_type operator+(const years_type& y)const + { + return months_type(y.number_of_years() * 12 + _m); + } + months_type& operator+=(const years_type& y) + { + _m = y.number_of_years() * 12 + _m; + return *this; + } + months_type operator-(const years_type& y) const + { + return months_type(_m - y.number_of_years() * 12); + } + months_type& operator-=(const years_type& y) + { + _m = _m - y.number_of_years() * 12; + return *this; + } + + // + friend date_type operator+(const date_type& d, const months_type& m) + { + return d + m.get_offset(d); + } + friend date_type operator+=(date_type& d, const months_type& m) + { + return d += m.get_offset(d); + } + friend date_type operator-(const date_type& d, const months_type& m) + { + // get_neg_offset returns a negative duration, so we add + return d + m.get_neg_offset(d); + } + friend date_type operator-=(date_type& d, const months_type& m) + { + // get_neg_offset returns a negative duration, so we add + return d += m.get_neg_offset(d); + } + + private: + int_rep _m; + }; + + //! additional duration type that represents a logical year + /*! A logical year enables things like: "date(2002,Mar,2) + years(2) -> + * 2004-Mar-2". If the date is a last day-of-the-month, the result will + * also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) -> + * 2004-Feb-29). + */ + template + class BOOST_SYMBOL_VISIBLE years_duration + { + private: + typedef typename base_config::int_rep int_rep; + typedef typename int_rep::int_type int_type; + typedef typename base_config::date_type date_type; + typedef typename date_type::duration_type duration_type; + typedef typename base_config::month_adjustor_type month_adjustor_type; + typedef years_duration years_type; + typedef months_duration months_type; + public: + years_duration(int_rep num) : _y(num) {} + years_duration(special_values sv) : _y(sv) + { + _y = int_rep::from_special(sv); + } + int_rep number_of_years() const { return _y; } + //! returns a negative duration + duration_type get_neg_offset(const date_type& d) const + { + month_adjustor_type m_adj(_y.as_number() * 12); + return duration_type(m_adj.get_neg_offset(d)); + } + duration_type get_offset(const date_type& d) const + { + month_adjustor_type m_adj(_y.as_number() * 12); + return duration_type(m_adj.get_offset(d)); + } + bool operator==(const years_type& rhs) const + { + return(_y == rhs._y); + } + bool operator!=(const years_type& rhs) const + { + return(_y != rhs._y); + } + years_type operator+(const years_type& rhs)const + { + return years_type(_y + rhs._y); + } + years_type& operator+=(const years_type& rhs) + { + _y = _y + rhs._y; + return *this; + } + years_type operator-(const years_type& rhs)const + { + return years_type(_y - rhs._y); + } + years_type& operator-=(const years_type& rhs) + { + _y = _y - rhs._y; + return *this; + } + years_type operator*(const int_type rhs)const + { + return years_type(_y * rhs); + } + years_type& operator*=(const int_type rhs) + { + _y = _y * rhs; + return *this; + } + years_type operator/(const int_type rhs)const + { + return years_type(_y / rhs); + } + years_type& operator/=(const int_type rhs) + { + _y = _y / rhs; + return *this; + } + months_type operator+(const months_type& m) const + { + return(months_type(_y * 12 + m.number_of_months())); + } + months_type operator-(const months_type& m) const + { + return(months_type(_y * 12 - m.number_of_months())); + } + + // + friend date_type operator+(const date_type& d, const years_type& y) + { + return d + y.get_offset(d); + } + friend date_type operator+=(date_type& d, const years_type& y) + { + return d += y.get_offset(d); + } + friend date_type operator-(const date_type& d, const years_type& y) + { + // get_neg_offset returns a negative duration, so we add + return d + y.get_neg_offset(d); + } + friend date_type operator-=(date_type& d, const years_type& y) + { + // get_neg_offset returns a negative duration, so we add + return d += y.get_neg_offset(d); + } + + private: + int_rep _y; + }; + +}} // namespace boost::date_time + +#endif // DATE_DURATION_TYPES_HPP___ diff --git a/boost/date_time/date_format_simple.hpp b/boost/date_time/date_format_simple.hpp new file mode 100644 index 00000000..45299037 --- /dev/null +++ b/boost/date_time/date_format_simple.hpp @@ -0,0 +1,159 @@ +#ifndef DATE_TIME_SIMPLE_FORMAT_HPP___ +#define DATE_TIME_SIMPLE_FORMAT_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/parse_format_base.hpp" + +namespace boost { +namespace date_time { + +//! Class to provide simple basic formatting rules +template +class simple_format { +public: + + //! String used printed is date is invalid + static const charT* not_a_date() + { + return "not-a-date-time"; + } + //! String used to for positive infinity value + static const charT* pos_infinity() + { + return "+infinity"; + } + //! String used to for positive infinity value + static const charT* neg_infinity() + { + return "-infinity"; + } + //! Describe month format + static month_format_spec month_format() + { + return month_as_short_string; + } + static ymd_order_spec date_order() + { + return ymd_order_iso; //YYYY-MM-DD + } + //! This format uses '-' to separate date elements + static bool has_date_sep_chars() + { + return true; + } + //! Char to sep? + static charT year_sep_char() + { + return '-'; + } + //! char between year-month + static charT month_sep_char() + { + return '-'; + } + //! Char to separate month-day + static charT day_sep_char() + { + return '-'; + } + //! char between date-hours + static charT hour_sep_char() + { + return ' '; + } + //! char between hour and minute + static charT minute_sep_char() + { + return ':'; + } + //! char for second + static charT second_sep_char() + { + return ':'; + } + +}; + +#ifndef BOOST_NO_STD_WSTRING + +//! Specialization of formmating rules for wchar_t +template<> +class simple_format { +public: + + //! String used printed is date is invalid + static const wchar_t* not_a_date() + { + return L"not-a-date-time"; + } + //! String used to for positive infinity value + static const wchar_t* pos_infinity() + { + return L"+infinity"; + } + //! String used to for positive infinity value + static const wchar_t* neg_infinity() + { + return L"-infinity"; + } + //! Describe month format + static month_format_spec month_format() + { + return month_as_short_string; + } + static ymd_order_spec date_order() + { + return ymd_order_iso; //YYYY-MM-DD + } + //! This format uses '-' to separate date elements + static bool has_date_sep_chars() + { + return true; + } + //! Char to sep? + static wchar_t year_sep_char() + { + return '-'; + } + //! char between year-month + static wchar_t month_sep_char() + { + return '-'; + } + //! Char to separate month-day + static wchar_t day_sep_char() + { + return '-'; + } + //! char between date-hours + static wchar_t hour_sep_char() + { + return ' '; + } + //! char between hour and minute + static wchar_t minute_sep_char() + { + return ':'; + } + //! char for second + static wchar_t second_sep_char() + { + return ':'; + } + +}; + +#endif // BOOST_NO_STD_WSTRING +} } //namespace date_time + + + + +#endif diff --git a/boost/date_time/date_formatting.hpp b/boost/date_time/date_formatting.hpp new file mode 100644 index 00000000..c1b69a8c --- /dev/null +++ b/boost/date_time/date_formatting.hpp @@ -0,0 +1,137 @@ +#ifndef DATE_TIME_DATE_FORMATTING_HPP___ +#define DATE_TIME_DATE_FORMATTING_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/compiler_config.hpp" +#include +#include +#include +#include + +/* NOTE: "formatter" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * date_formatting_limited.hpp + */ + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class month_formatter + { + typedef std::basic_ostream ostream_type; + public: + //! Formats a month as as string into an ostream + /*! This function demands that month_type provide + * functions for converting to short and long strings + * if that capability is used. + */ + static ostream_type& format_month(const month_type& month, + ostream_type &os) + { + switch (format_type::month_format()) + { + case month_as_short_string: + { + os << month.as_short_string(); + break; + } + case month_as_long_string: + { + os << month.as_long_string(); + break; + } + case month_as_integer: + { + boost::io::basic_ios_fill_saver ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number(); + break; + } + default: + break; + + } + return os; + } // format_month + }; + + + //! Convert ymd to a standard string formatting policies + template + class ymd_formatter + { + public: + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + static std::basic_string ymd_to_string(ymd_type ymd) + { + typedef typename ymd_type::month_type month_type; + std::basic_ostringstream ss; + + // Temporarily switch to classic locale to prevent possible formatting + // of year with comma or other character (for example 2,008). + ss.imbue(std::locale::classic()); + ss << ymd.year; + ss.imbue(std::locale()); + + if (format_type::has_date_sep_chars()) { + ss << format_type::month_sep_char(); + } + //this name is a bit ugly, oh well.... + month_formatter::format_month(ymd.month, ss); + if (format_type::has_date_sep_chars()) { + ss << format_type::day_sep_char(); + } + ss << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.day; + return ss.str(); + } + }; + + + //! Convert a date to string using format policies + template + class date_formatter + { + public: + typedef std::basic_string string_type; + //! Convert to a date to standard string using format policies + static string_type date_to_string(date_type d) + { + typedef typename date_type::ymd_type ymd_type; + if (d.is_not_a_date()) { + return string_type(format_type::not_a_date()); + } + if (d.is_neg_infinity()) { + return string_type(format_type::neg_infinity()); + } + if (d.is_pos_infinity()) { + return string_type(format_type::pos_infinity()); + } + ymd_type ymd = d.year_month_day(); + return ymd_formatter::ymd_to_string(ymd); + } + }; + + +} } //namespace date_time + + +#endif + diff --git a/boost/date_time/date_formatting_limited.hpp b/boost/date_time/date_formatting_limited.hpp new file mode 100644 index 00000000..7c5c1735 --- /dev/null +++ b/boost/date_time/date_formatting_limited.hpp @@ -0,0 +1,121 @@ +#ifndef DATE_TIME_DATE_FORMATTING_LIMITED_HPP___ +#define DATE_TIME_DATE_FORMATTING_LIMITED_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/compiler_config.hpp" +#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class month_formatter + { + public: + //! Formats a month as as string into an ostream + /*! This function demands that month_type provide + * functions for converting to short and long strings + * if that capability is used. + */ + static std::ostream& format_month(const month_type& month, + std::ostream& os) + { + switch (format_type::month_format()) + { + case month_as_short_string: + { + os << month.as_short_string(); + break; + } + case month_as_long_string: + { + os << month.as_long_string(); + break; + } + case month_as_integer: + { + os << std::setw(2) << std::setfill('0') << month.as_number(); + break; + } + + } + return os; + } // format_month + }; + + + //! Convert ymd to a standard string formatting policies + template + class ymd_formatter + { + public: + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + static std::string ymd_to_string(ymd_type ymd) + { + typedef typename ymd_type::month_type month_type; + std::ostringstream ss; + ss << ymd.year; + if (format_type::has_date_sep_chars()) { + ss << format_type::month_sep_char(); + } + //this name is a bit ugly, oh well.... + month_formatter::format_month(ymd.month, ss); + if (format_type::has_date_sep_chars()) { + ss << format_type::day_sep_char(); + } + ss << std::setw(2) << std::setfill('0') + << ymd.day; + return ss.str(); + } + }; + + + //! Convert a date to string using format policies + template + class date_formatter + { + public: + //! Convert to a date to standard string using format policies + static std::string date_to_string(date_type d) + { + typedef typename date_type::ymd_type ymd_type; + if (d.is_not_a_date()) { + return format_type::not_a_date(); + } + if (d.is_neg_infinity()) { + return format_type::neg_infinity(); + } + if (d.is_pos_infinity()) { + return format_type::pos_infinity(); + } + ymd_type ymd = d.year_month_day(); + return ymd_formatter::ymd_to_string(ymd); + } + }; + + +} } //namespace date_time + + +#endif + diff --git a/boost/date_time/date_formatting_locales.hpp b/boost/date_time/date_formatting_locales.hpp new file mode 100644 index 00000000..a1daad33 --- /dev/null +++ b/boost/date_time/date_formatting_locales.hpp @@ -0,0 +1,234 @@ +#ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___ +#define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_names_put.hpp" +#include "boost/date_time/parse_format_base.hpp" +#include +//#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class ostream_month_formatter + { + public: + typedef typename facet_type::month_type month_type; + typedef std::basic_ostream ostream_type; + + //! Formats a month as as string into an output iterator + static void format_month(const month_type& month, + ostream_type& os, + const facet_type& f) + { + + switch (f.month_format()) + { + case month_as_short_string: + { + std::ostreambuf_iterator oitr(os); + f.put_month_short(oitr, month.as_enum()); + break; + } + case month_as_long_string: + { + std::ostreambuf_iterator oitr(os); + f.put_month_long(oitr, month.as_enum()); + break; + } + case month_as_integer: + { + boost::io::basic_ios_fill_saver ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number(); + break; + } + + } + } // format_month + + }; + + + //! Formats a weekday + template + class ostream_weekday_formatter + { + public: + typedef typename facet_type::month_type month_type; + typedef std::basic_ostream ostream_type; + + //! Formats a month as as string into an output iterator + static void format_weekday(const weekday_type& wd, + ostream_type& os, + const facet_type& f, + bool as_long_string) + { + + std::ostreambuf_iterator oitr(os); + if (as_long_string) { + f.put_weekday_long(oitr, wd.as_enum()); + } + else { + f.put_weekday_short(oitr, wd.as_enum()); + } + + } // format_weekday + + }; + + + //! Convert ymd to a standard string formatting policies + template + class ostream_ymd_formatter + { + public: + typedef typename ymd_type::month_type month_type; + typedef ostream_month_formatter month_formatter_type; + typedef std::basic_ostream ostream_type; + typedef std::basic_string foo_type; + + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + // static string_type ymd_to_string(ymd_type ymd) +// { +// std::ostringstream ss; +// facet_type dnp; +// ymd_put(ymd, ss, dnp); +// return ss.str(); +// } + + + // Put ymd to ostream -- part of ostream refactor + static void ymd_put(ymd_type ymd, + ostream_type& os, + const facet_type& f) + { + boost::io::basic_ios_fill_saver ifs(os); + std::ostreambuf_iterator oitr(os); + switch (f.date_order()) { + case ymd_order_iso: { + os << ymd.year; + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + os << std::setw(2) << std::setfill(os.widen('0')) + << ymd.day; + break; + } + case ymd_order_us: { + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + os << std::setw(2) << std::setfill(os.widen('0')) + << ymd.day; + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + os << ymd.year; + break; + } + case ymd_order_dmy: { + os << std::setw(2) << std::setfill(os.widen('0')) + << ymd.day; + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + os << ymd.year; + break; + } + } + } + }; + + + //! Convert a date to string using format policies + template + class ostream_date_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename date_type::ymd_type ymd_type; + + //! Put date into an ostream + static void date_put(const date_type& d, + ostream_type& os, + const facet_type& f) + { + special_values sv = d.as_special(); + if (sv == not_special) { + ymd_type ymd = d.year_month_day(); + ostream_ymd_formatter::ymd_put(ymd, os, f); + } + else { // output a special value + std::ostreambuf_iterator coi(os); + f.put_special_value(coi, sv); + } + } + + + //! Put date into an ostream + static void date_put(const date_type& d, + ostream_type& os) + { + //retrieve the local from the ostream + std::locale locale = os.getloc(); + if (std::has_facet(locale)) { + const facet_type& f = std::use_facet(locale); + date_put(d, os, f); + } + else { + //default to something sensible if no facet installed + facet_type default_facet; + date_put(d, os, default_facet); + } + } // date_to_ostream + }; //class date_formatter + + +} } //namespace date_time + +#endif + +#endif + diff --git a/boost/date_time/date_generators.hpp b/boost/date_time/date_generators.hpp new file mode 100644 index 00000000..274ce1f0 --- /dev/null +++ b/boost/date_time/date_generators.hpp @@ -0,0 +1,509 @@ +#ifndef DATE_TIME_DATE_GENERATORS_HPP__ +#define DATE_TIME_DATE_GENERATORS_HPP__ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file date_generators.hpp + Definition and implementation of date algorithm templates +*/ + +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //! Base class for all generators that take a year and produce a date. + /*! This class is a base class for polymorphic function objects that take + a year and produce a concrete date. + @param date_type The type representing a date. This type must + export a calender_type which defines a year_type. + */ + template + class year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::year_type year_type; + year_based_generator() {} + virtual ~year_based_generator() {} + virtual date_type get_date(year_type y) const = 0; + //! Returns a string for use in a POSIX time_zone string + virtual std::string to_string() const =0; + }; + + //! Generates a date by applying the year to the given month and day. + /*! + Example usage: + @code + partial_date pd(1, Jan); + partial_date pd2(70); + date d = pd.get_date(2002); //2002-Jan-01 + date d2 = pd2.get_date(2002); //2002-Mar-10 + @endcode + \ingroup date_alg + */ + template + class partial_date : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_type day_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + typedef typename duration_type::duration_rep duration_rep; + partial_date(day_type d, month_type m) : + day_(d), + month_(m) + {} + //! Partial date created from number of days into year. Range 1-366 + /*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument + * exceeds range, partial_date will be created with closest in-range value. + * 60 will always be Feb29, if get_date() is called with a non-leap year + * an exception will be thrown */ + partial_date(duration_rep days) : + day_(1), // default values + month_(1) + { + date_type d1(2000,1,1); + if(days > 1) { + if(days > 366) // prevents wrapping + { + days = 366; + } + days = days - 1; + duration_type dd(days); + d1 = d1 + dd; + } + day_ = d1.day(); + month_ = d1.month(); + } + //! Return a concrete date when provided with a year specific year. + /*! Will throw an 'invalid_argument' exception if a partial_date object, + * instantiated with Feb-29, has get_date called with a non-leap year. + * Example: + * @code + * partial_date pd(29, Feb); + * pd.get_date(2003); // throws invalid_argument exception + * pg.get_date(2000); // returns 2000-2-29 + * @endcode + */ + date_type get_date(year_type y) const + { + if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) { + std::ostringstream ss; + ss << "No Feb 29th in given year of " << y << "."; + boost::throw_exception(std::invalid_argument(ss.str())); + } + return date_type(y, month_, day_); + } + date_type operator()(year_type y) const + { + return get_date(y); + //return date_type(y, month_, day_); + } + bool operator==(const partial_date& rhs) const + { + return (month_ == rhs.month_) && (day_ == rhs.day_); + } + bool operator<(const partial_date& rhs) const + { + if (month_ < rhs.month_) return true; + if (month_ > rhs.month_) return false; + //months are equal + return (day_ < rhs.day_); + } + + // added for streaming purposes + month_type month() const + { + return month_; + } + day_type day() const + { + return day_; + } + + //! Returns string suitable for use in POSIX time zone string + /*! Returns string formatted with up to 3 digits: + * Jan-01 == "0" + * Feb-29 == "58" + * Dec-31 == "365" */ + virtual std::string to_string() const + { + std::ostringstream ss; + date_type d(2004, month_, day_); + unsigned short c = d.day_of_year(); + c--; // numbered 0-365 while day_of_year is 1 based... + ss << c; + return ss.str(); + } + private: + day_type day_; + month_type month_; + }; + + + //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5. + BOOST_DATE_TIME_DECL const char* nth_as_str(int n); + + //! Useful generator functor for finding holidays + /*! Based on the idea in Cal. Calc. for finding holidays that are + * the 'first Monday of September'. When instantiated with + * 'fifth' kday of month, the result will be the last kday of month + * which can be the fourth or fifth depending on the structure of + * the month. + * + * The algorithm here basically guesses for the first + * day of the month. Then finds the first day of the correct + * type. That is, if the first of the month is a Tuesday + * and it needs Wenesday then we simply increment by a day + * and then we can add the length of a week until we get + * to the 'nth kday'. There are probably more efficient + * algorithms based on using a mod 7, but this one works + * reasonably well for basic applications. + * \ingroup date_alg + */ + template + class nth_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + enum week_num {first=1, second, third, fourth, fifth}; + nth_kday_of_month(week_num week_no, + day_of_week_type dow, + month_type m) : + month_(m), + wn_(week_no), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type y) const + { + date_type d(y, month_, 1); //first day of month + duration_type one_day(1); + duration_type one_week(7); + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + int week = 1; + while (week < wn_) { + d = d + one_week; + week++; + } + // remove wrapping to next month behavior + if(d.month() != month_) { + d = d - one_week; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + week_num nth_week() const + { + return wn_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + const char* nth_week_as_str() const + { + return nth_as_str(wn_); + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */ + virtual std::string to_string() const + { + std::ostringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << static_cast(wn_) << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + week_num wn_; + day_of_week_type dow_; + }; + + //! Useful generator functor for finding holidays and daylight savings + /*! Similar to nth_kday_of_month, but requires less paramters + * \ingroup date_alg + */ + template + class first_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + //!Specify the first 'Sunday' in 'April' spec + /*!@param dow The day of week, eg: Sunday, Monday, etc + * @param m The month of the year, eg: Jan, Feb, Mar, etc + */ + first_kday_of_month(day_of_week_type dow, month_type m) : + month_(m), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type year) const + { + date_type d(year, month_,1); + duration_type one_day(1); + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */ + virtual std::string to_string() const + { + std::ostringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << 1 << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + day_of_week_type dow_; + }; + + + + //! Calculate something like Last Sunday of January + /*! Useful generator functor for finding holidays and daylight savings + * Get the last day of the month and then calculate the difference + * to the last previous day. + * @param date_type A date class that exports day_of_week, month_type, etc. + * \ingroup date_alg + */ + template + class last_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + //!Specify the date spec like last 'Sunday' in 'April' spec + /*!@param dow The day of week, eg: Sunday, Monday, etc + * @param m The month of the year, eg: Jan, Feb, Mar, etc + */ + last_kday_of_month(day_of_week_type dow, month_type m) : + month_(m), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type year) const + { + date_type d(year, month_, calendar_type::end_of_month_day(year,month_)); + duration_type one_day(1); + while (dow_ != d.day_of_week()) { + d = d - one_day; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */ + virtual std::string to_string() const + { + std::ostringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << 5 << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + day_of_week_type dow_; + }; + + + //! Calculate something like "First Sunday after Jan 1,2002 + /*! Date generator that takes a date and finds kday after + *@code + typedef boost::date_time::first_kday_after firstkdayafter; + firstkdayafter fkaf(Monday); + fkaf.get_date(date(2002,Feb,1)); + @endcode + * \ingroup date_alg + */ + template + class first_kday_after + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename date_type::duration_type duration_type; + first_kday_after(day_of_week_type dow) : + dow_(dow) + {} + //! Return next kday given. + date_type get_date(date_type start_day) const + { + duration_type one_day(1); + date_type d = start_day + one_day; + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + return d; + } + // added for streaming + day_of_week_type day_of_week() const + { + return dow_; + } + private: + day_of_week_type dow_; + }; + + //! Calculate something like "First Sunday before Jan 1,2002 + /*! Date generator that takes a date and finds kday after + *@code + typedef boost::date_time::first_kday_before firstkdaybefore; + firstkdaybefore fkbf(Monday); + fkbf.get_date(date(2002,Feb,1)); + @endcode + * \ingroup date_alg + */ + template + class first_kday_before + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename date_type::duration_type duration_type; + first_kday_before(day_of_week_type dow) : + dow_(dow) + {} + //! Return next kday given. + date_type get_date(date_type start_day) const + { + duration_type one_day(1); + date_type d = start_day - one_day; + while (dow_ != d.day_of_week()) { + d = d - one_day; + } + return d; + } + // added for streaming + day_of_week_type day_of_week() const + { + return dow_; + } + private: + day_of_week_type dow_; + }; + + //! Calculates the number of days until the next weekday + /*! Calculates the number of days until the next weekday. + * If the date given falls on a Sunday and the given weekday + * is Tuesday the result will be 2 days */ + template + inline + typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd) + { + typedef typename date_type::duration_type duration_type; + duration_type wks(0); + duration_type dd(wd.as_number() - d.day_of_week().as_number()); + if(dd.is_negative()){ + wks = duration_type(7); + } + return dd + wks; + } + + //! Calculates the number of days since the previous weekday + /*! Calculates the number of days since the previous weekday + * If the date given falls on a Sunday and the given weekday + * is Tuesday the result will be 5 days. The answer will be a positive + * number because Tuesday is 5 days before Sunday, not -5 days before. */ + template + inline + typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd) + { + typedef typename date_type::duration_type duration_type; + duration_type wks(0); + duration_type dd(wd.as_number() - d.day_of_week().as_number()); + if(dd.days() > 0){ + wks = duration_type(7); + } + // we want a number of days, not an offset. The value returned must + // be zero or larger. + return (-dd + wks); + } + + //! Generates a date object representing the date of the following weekday from the given date + /*! Generates a date object representing the date of the following + * weekday from the given date. If the date given is 2004-May-9 + * (a Sunday) and the given weekday is Tuesday then the resulting date + * will be 2004-May-11. */ + template + inline + date_type next_weekday(const date_type& d, const weekday_type& wd) + { + return d + days_until_weekday(d, wd); + } + + //! Generates a date object representing the date of the previous weekday from the given date + /*! Generates a date object representing the date of the previous + * weekday from the given date. If the date given is 2004-May-9 + * (a Sunday) and the given weekday is Tuesday then the resulting date + * will be 2004-May-4. */ + template + inline + date_type previous_weekday(const date_type& d, const weekday_type& wd) + { + return d - days_before_weekday(d, wd); + } + +} } //namespace date_time + + + + +#endif + diff --git a/boost/date_time/date_iterator.hpp b/boost/date_time/date_iterator.hpp new file mode 100644 index 00000000..3526ba18 --- /dev/null +++ b/boost/date_time/date_iterator.hpp @@ -0,0 +1,101 @@ +#ifndef DATE_ITERATOR_HPP___ +#define DATE_ITERATOR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include + +namespace boost { +namespace date_time { + //! An iterator over dates with varying resolution (day, week, month, year, etc) + enum date_resolutions {day, week, months, year, decade, century, NumDateResolutions}; + + //! Base date iterator type + /*! This class provides the skeleton for the creation of iterators. + * New and interesting interators can be created by plugging in a new + * function that derives the next value from the current state. + * generation of various types of -based information. + * + * Template Parameters + * + * date_type + * + * The date_type is a concrete date_type. The date_type must + * define a duration_type and a calendar_type. + */ + template + class date_itr_base { + // works, but benefit unclear at the moment + // class date_itr_base : public std::iterator{ + public: + typedef typename date_type::duration_type duration_type; + typedef date_type value_type; + typedef std::input_iterator_tag iterator_category; + + date_itr_base(date_type d) : current_(d) {} + virtual ~date_itr_base() {} + date_itr_base& operator++() + { + current_ = current_ + get_offset(current_); + return *this; + } + date_itr_base& operator--() + { + current_ = current_ + get_neg_offset(current_); + return *this; + } + virtual duration_type get_offset(const date_type& current) const=0; + virtual duration_type get_neg_offset(const date_type& current) const=0; + date_type operator*() {return current_;} + date_type* operator->() {return ¤t_;} + bool operator< (const date_type& d) {return current_ < d;} + bool operator<= (const date_type& d) {return current_ <= d;} + bool operator> (const date_type& d) {return current_ > d;} + bool operator>= (const date_type& d) {return current_ >= d;} + bool operator== (const date_type& d) {return current_ == d;} + bool operator!= (const date_type& d) {return current_ != d;} + private: + date_type current_; + }; + + //! Overrides the base date iterator providing hook for functors + /* + * offset_functor + * + * The offset functor must define a get_offset function that takes the + * current point in time and calculates and offset. + * + */ + template + class date_itr : public date_itr_base { + public: + typedef typename date_type::duration_type duration_type; + date_itr(date_type d, int factor=1) : + date_itr_base(d), + of_(factor) + {} + private: + virtual duration_type get_offset(const date_type& current) const + { + return of_.get_offset(current); + } + virtual duration_type get_neg_offset(const date_type& current) const + { + return of_.get_neg_offset(current); + } + offset_functor of_; + }; + + + +} } //namespace date_time + + +#endif diff --git a/boost/date_time/date_names_put.hpp b/boost/date_time/date_names_put.hpp new file mode 100644 index 00000000..20da2d2e --- /dev/null +++ b/boost/date_time/date_names_put.hpp @@ -0,0 +1,321 @@ +#ifndef DATE_TIME_DATE_NAMES_PUT_HPP___ +#define DATE_TIME_DATE_NAMES_PUT_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include // set BOOST_DATE_TIME_NO_LOCALE + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Output facet base class for gregorian dates. + /*! This class is a base class for date facets used to localize the + * names of months and the names of days in the week. + * + * Requirements of Config + * - define an enumeration month_enum that enumerates the months. + * The enumeration should be '1' based eg: Jan==1 + * - define as_short_string and as_long_string + * + * (see langer & kreft p334). + * + */ + template > + class BOOST_SYMBOL_VISIBLE date_names_put : public std::locale::facet + { + public: + date_names_put() {} + typedef OutputIterator iter_type; + typedef typename Config::month_type month_type; + typedef typename Config::month_enum month_enum; + typedef typename Config::weekday_enum weekday_enum; + typedef typename Config::special_value_enum special_value_enum; + //typedef typename Config::format_type format_type; + typedef std::basic_string string_type; + typedef charT char_type; + static const char_type default_special_value_names[3][17]; + static const char_type separator[2]; + + static std::locale::id id; + +#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) + std::locale::id& __get_id (void) const { return id; } +#endif + + void put_special_value(iter_type& oitr, special_value_enum sv) const + { + do_put_special_value(oitr, sv); + } + void put_month_short(iter_type& oitr, month_enum moy) const + { + do_put_month_short(oitr, moy); + } + void put_month_long(iter_type& oitr, month_enum moy) const + { + do_put_month_long(oitr, moy); + } + void put_weekday_short(iter_type& oitr, weekday_enum wd) const + { + do_put_weekday_short(oitr, wd); + } + void put_weekday_long(iter_type& oitr, weekday_enum wd) const + { + do_put_weekday_long(oitr, wd); + } + bool has_date_sep_chars() const + { + return do_has_date_sep_chars(); + } + void year_sep_char(iter_type& oitr) const + { + do_year_sep_char(oitr); + } + //! char between year-month + void month_sep_char(iter_type& oitr) const + { + do_month_sep_char(oitr); + } + //! Char to separate month-day + void day_sep_char(iter_type& oitr) const + { + do_day_sep_char(oitr); + } + //! Determines the order to put the date elements + ymd_order_spec date_order() const + { + return do_date_order(); + } + //! Determines if month is displayed as integer, short or long string + month_format_spec month_format() const + { + return do_month_format(); + } + + protected: + //! Default facet implementation uses month_type defaults + virtual void do_put_month_short(iter_type& oitr, month_enum moy) const + { + month_type gm(moy); + charT c = '\0'; + put_string(oitr, gm.as_short_string(c)); + } + //! Default facet implementation uses month_type defaults + virtual void do_put_month_long(iter_type& oitr, + month_enum moy) const + { + month_type gm(moy); + charT c = '\0'; + put_string(oitr, gm.as_long_string(c)); + } + //! Default facet implementation for special value types + virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const + { + if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin + string_type s(default_special_value_names[sv]); + put_string(oitr, s); + } + } + virtual void do_put_weekday_short(iter_type&, weekday_enum) const + { + } + virtual void do_put_weekday_long(iter_type&, weekday_enum) const + { + } + virtual bool do_has_date_sep_chars() const + { + return true; + } + virtual void do_year_sep_char(iter_type& oitr) const + { + string_type s(separator); + put_string(oitr, s); + } + //! char between year-month + virtual void do_month_sep_char(iter_type& oitr) const + { + string_type s(separator); + put_string(oitr, s); + } + //! Char to separate month-day + virtual void do_day_sep_char(iter_type& oitr) const + { + string_type s(separator); //put in '-' + put_string(oitr, s); + } + //! Default for date order + virtual ymd_order_spec do_date_order() const + { + return ymd_order_iso; + } + //! Default month format + virtual month_format_spec do_month_format() const + { + return month_as_short_string; + } + void put_string(iter_type& oi, const charT* const s) const + { + string_type s1(boost::lexical_cast(s)); + typename string_type::iterator si,end; + for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) { + *oi = *si; + } + } + void put_string(iter_type& oi, const string_type& s1) const + { + typename string_type::const_iterator si,end; + for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) { + *oi = *si; + } + } + }; + + template + const typename date_names_put::char_type + date_names_put::default_special_value_names[3][17] = { + {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'}, + {'-','i','n','f','i','n','i','t','y'}, + {'+','i','n','f','i','n','i','t','y'} }; + + template + const typename date_names_put::char_type + date_names_put::separator[2] = + {'-', '\0'} ; + + + //! Generate storage location for a std::locale::id + template + std::locale::id date_names_put::id; + + //! A date name output facet that takes an array of char* to define strings + template > + class BOOST_SYMBOL_VISIBLE all_date_names_put : public date_names_put + { + public: + all_date_names_put(const charT* const month_short_names[], + const charT* const month_long_names[], + const charT* const special_value_names[], + const charT* const weekday_short_names[], + const charT* const weekday_long_names[], + charT separator_char = '-', + ymd_order_spec order_spec = ymd_order_iso, + month_format_spec month_format = month_as_short_string) : + month_short_names_(month_short_names), + month_long_names_(month_long_names), + special_value_names_(special_value_names), + weekday_short_names_(weekday_short_names), + weekday_long_names_(weekday_long_names), + order_spec_(order_spec), + month_format_spec_(month_format) + { + separator_char_[0] = separator_char; + separator_char_[1] = '\0'; + + } + typedef OutputIterator iter_type; + typedef typename Config::month_enum month_enum; + typedef typename Config::weekday_enum weekday_enum; + typedef typename Config::special_value_enum special_value_enum; + + const charT* const* get_short_month_names() const + { + return month_short_names_; + } + const charT* const* get_long_month_names() const + { + return month_long_names_; + } + const charT* const* get_special_value_names() const + { + return special_value_names_; + } + const charT* const* get_short_weekday_names()const + { + return weekday_short_names_; + } + const charT* const* get_long_weekday_names()const + { + return weekday_long_names_; + } + + protected: + //! Generic facet that takes array of chars + virtual void do_put_month_short(iter_type& oitr, month_enum moy) const + { + this->put_string(oitr, month_short_names_[moy-1]); + } + //! Long month names + virtual void do_put_month_long(iter_type& oitr, month_enum moy) const + { + this->put_string(oitr, month_long_names_[moy-1]); + } + //! Special values names + virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const + { + this->put_string(oitr, special_value_names_[sv]); + } + virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const + { + this->put_string(oitr, weekday_short_names_[wd]); + } + virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const + { + this->put_string(oitr, weekday_long_names_[wd]); + } + //! char between year-month + virtual void do_month_sep_char(iter_type& oitr) const + { + this->put_string(oitr, separator_char_); + } + //! Char to separate month-day + virtual void do_day_sep_char(iter_type& oitr) const + { + this->put_string(oitr, separator_char_); + } + //! Set the date ordering + virtual ymd_order_spec do_date_order() const + { + return order_spec_; + } + //! Set the date ordering + virtual month_format_spec do_month_format() const + { + return month_format_spec_; + } + + private: + const charT* const* month_short_names_; + const charT* const* month_long_names_; + const charT* const* special_value_names_; + const charT* const* weekday_short_names_; + const charT* const* weekday_long_names_; + charT separator_char_[2]; + ymd_order_spec order_spec_; + month_format_spec month_format_spec_; + }; + +} } //namespace boost::date_time + +#endif //BOOST_NO_STD_LOCALE + +#endif diff --git a/boost/date_time/date_parsing.hpp b/boost/date_time/date_parsing.hpp new file mode 100644 index 00000000..33c53660 --- /dev/null +++ b/boost/date_time/date_parsing.hpp @@ -0,0 +1,316 @@ +#ifndef _DATE_TIME_DATE_PARSING_HPP___ +#define _DATE_TIME_DATE_PARSING_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_DATE_TIME_NO_LOCALE) +#include // ::tolower(int) +#else +#include // std::tolower(char, locale) +#endif + +namespace boost { +namespace date_time { + + //! A function to replace the std::transform( , , ,tolower) construct + /*! This function simply takes a string, and changes all the characters + * in that string to lowercase (according to the default system locale). + * In the event that a compiler does not support locales, the old + * C style tolower() is used. + */ + inline + std::string + convert_to_lower(std::string inp) + { +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + const std::locale loc(std::locale::classic()); +#endif + std::string::size_type i = 0, n = inp.length(); + for (; i < n; ++i) { + inp[i] = +#if defined(BOOST_DATE_TIME_NO_LOCALE) + static_cast(std::tolower(inp[i])); +#else + // tolower and others were brought in to std for borland >= v564 + // in compiler_config.hpp + std::tolower(inp[i], loc); +#endif + } + return inp; + } + + //! Helper function for parse_date. + /* Used by-value parameter because we change the string and may + * want to preserve the original argument */ + template + inline unsigned short + month_str_to_ushort(std::string const& s) { + if((s.at(0) >= '0') && (s.at(0) <= '9')) { + return boost::lexical_cast(s); + } + else { + std::string str = convert_to_lower(s); + typename month_type::month_map_ptr_type ptr = month_type::get_month_map_ptr(); + typename month_type::month_map_type::iterator iter = ptr->find(str); + if(iter != ptr->end()) { // required for STLport + return iter->second; + } + } + return 13; // intentionally out of range - name not found + } + + //! Find index of a string in either of 2 arrays + /*! find_match searches both arrays for a match to 's'. Both arrays + * must contain 'size' elements. The index of the match is returned. + * If no match is found, 'size' is returned. + * Ex. "Jan" returns 0, "Dec" returns 11, "Tue" returns 2. + * 'size' can be sent in with: (greg_month::max)() (which 12), + * (greg_weekday::max)() + 1 (which is 7) or date_time::NumSpecialValues */ + template + short find_match(const charT* const* short_names, + const charT* const* long_names, + short size, + const std::basic_string& s) { + for(short i = 0; i < size; ++i){ + if(short_names[i] == s || long_names[i] == s){ + return i; + } + } + return size; // not-found, return a value out of range + } + + //! Generic function to parse a delimited date (eg: 2002-02-10) + /*! Accepted formats are: "2003-02-10" or " 2003-Feb-10" or + * "2003-Feburary-10" + * The order in which the Month, Day, & Year appear in the argument + * string can be accomodated by passing in the appropriate ymd_order_spec + */ + template + date_type + parse_date(const std::string& s, int order_spec = ymd_order_iso) { + std::string spec_str; + if(order_spec == ymd_order_iso) { + spec_str = "ymd"; + } + else if(order_spec == ymd_order_dmy) { + spec_str = "dmy"; + } + else { // (order_spec == ymd_order_us) + spec_str = "mdy"; + } + + typedef typename date_type::month_type month_type; + unsigned pos = 0; + unsigned short year(0), month(0), day(0); + typedef typename std::basic_string::traits_type traits_type; + typedef boost::char_separator char_separator_type; + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef boost::tokenizer::const_iterator, + std::basic_string >::iterator tokenizer_iterator; + // may need more delimiters, these work for the regression tests + const char sep_char[] = {',','-','.',' ','/','\0'}; + char_separator_type sep(sep_char); + tokenizer tok(s,sep); + for(tokenizer_iterator beg=tok.begin(); + beg!=tok.end() && pos < spec_str.size(); + ++beg, ++pos) { + switch(spec_str.at(pos)) { + case 'y': + { + year = boost::lexical_cast(*beg); + break; + } + case 'm': + { + month = month_str_to_ushort(*beg); + break; + } + case 'd': + { + day = boost::lexical_cast(*beg); + break; + } + default: break; + } //switch + } + return date_type(year, month, day); + } + + //! Generic function to parse undelimited date (eg: 20020201) + template + date_type + parse_undelimited_date(const std::string& s) { + int offsets[] = {4,2,2}; + int pos = 0; + //typename date_type::ymd_type ymd((year_type::min)(),1,1); + unsigned short y = 0, m = 0, d = 0; + + /* The two bool arguments state that parsing will not wrap + * (only the first 8 characters will be parsed) and partial + * strings will not be parsed. + * Ex: + * "2005121" will parse 2005 & 12, but not the "1" */ + boost::offset_separator osf(offsets, offsets+3, false, false); + + typedef typename boost::tokenizer::const_iterator, + std::basic_string > tokenizer_type; + tokenizer_type tok(s, osf); + for(typename tokenizer_type::iterator ti=tok.begin(); ti!=tok.end();++ti) { + unsigned short i = boost::lexical_cast(*ti); + switch(pos) { + case 0: y = i; break; + case 1: m = i; break; + case 2: d = i; break; + default: break; + } + pos++; + } + return date_type(y,m,d); + } + + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the iterators that reference the + * begining & end of a char[] or string. All elements are + * used in output string */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type const& end, + char) + { + std::ostringstream ss; + while(beg != end) { + ss << *beg++; + } + return parse_date(ss.str()); + } + + //! Helper function for 'date gregorian::from_stream()' + /*! Returns the first string found in the stream referenced by the + * begining & end iterators */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type const& /* end */, + std::string const&) + { + return parse_date(*beg); + } + + /* I believe the wchar stuff would be best elsewhere, perhaps in + * parse_date<>()? In the mean time this gets us started... */ + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the iterators that reference the + * begining & end of a wstring. All elements are + * used in output string */ + template + inline + date_type from_stream_type(iterator_type& beg, + iterator_type const& end, + wchar_t) + { + std::ostringstream ss; +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + std::locale loc; + std::ctype const& fac = std::use_facet >(loc); + while(beg != end) { + ss << fac.narrow(*beg++, 'X'); // 'X' will cause exception to be thrown + } +#else + while(beg != end) { + char c = 'X'; // 'X' will cause exception to be thrown + const wchar_t wc = *beg++; + if (wc >= 0 && wc <= 127) + c = static_cast< char >(wc); + ss << c; + } +#endif + return parse_date(ss.str()); + } +#ifndef BOOST_NO_STD_WSTRING + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the first wstring found in the stream + * referenced by the begining & end iterators */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type const& /* end */, + std::wstring const&) { + std::wstring ws = *beg; + std::ostringstream ss; + std::wstring::iterator wsb = ws.begin(), wse = ws.end(); +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + std::locale loc; + std::ctype const& fac = std::use_facet >(loc); + while(wsb != wse) { + ss << fac.narrow(*wsb++, 'X'); // 'X' will cause exception to be thrown + } +#else + while(wsb != wse) { + char c = 'X'; // 'X' will cause exception to be thrown + const wchar_t wc = *wsb++; + if (wc >= 0 && wc <= 127) + c = static_cast< char >(wc); + ss << c; + } +#endif + return parse_date(ss.str()); + } +#endif // BOOST_NO_STD_WSTRING +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings +#else + //! function called by wrapper functions: date_period_from_(w)string() + template + period + from_simple_string_type(const std::basic_string& s){ + typedef typename std::basic_string::traits_type traits_type; + typedef typename boost::char_separator char_separator; + typedef typename boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + const charT sep_list[4] = {'[','/',']','\0'}; + char_separator sep(sep_list); + tokenizer tokens(s, sep); + typename tokenizer::iterator tok_it = tokens.begin(); + std::basic_string date_string = *tok_it; + // get 2 string iterators and generate a date from them + typename std::basic_string::iterator date_string_start = date_string.begin(), + date_string_end = date_string.end(); + typedef typename std::iterator_traits::iterator>::value_type value_type; + date_type d1 = from_stream_type(date_string_start, date_string_end, value_type()); + date_string = *(++tok_it); // next token + date_string_start = date_string.begin(), date_string_end = date_string.end(); + date_type d2 = from_stream_type(date_string_start, date_string_end, value_type()); + return period(d1, d2); + } +#endif + +} } //namespace date_time + + + + +#endif + diff --git a/boost/date_time/dst_rules.hpp b/boost/date_time/dst_rules.hpp new file mode 100644 index 00000000..73a98996 --- /dev/null +++ b/boost/date_time/dst_rules.hpp @@ -0,0 +1,391 @@ +#ifndef DATE_TIME_DST_RULES_HPP__ +#define DATE_TIME_DST_RULES_HPP__ + +/* Copyright (c) 2002,2003, 2007 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file dst_rules.hpp + Contains template class to provide static dst rule calculations +*/ + +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/date_defs.hpp" +#include + +namespace boost { + namespace date_time { + + enum time_is_dst_result {is_not_in_dst, is_in_dst, + ambiguous, invalid_time_label}; + + + //! Dynamic class used to caluclate dst transition information + template + class dst_calculator + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + + //! Check the local time offset when on dst start day + /*! On this dst transition, the time label between + * the transition boundary and the boudary + the offset + * are invalid times. If before the boundary then still + * not in dst. + *@param time_of_day Time offset in the day for the local time + *@param dst_start_offset_minutes Local day offset for start of dst + *@param dst_length_minutes Number of minutes to adjust clock forward + *@retval status of time label w.r.t. dst + */ + static time_is_dst_result + process_local_dst_start_day(const time_duration_type& time_of_day, + unsigned int dst_start_offset_minutes, + long dst_length_minutes) + { + //std::cout << "here" << std::endl; + if (time_of_day < time_duration_type(0,dst_start_offset_minutes,0)) { + return is_not_in_dst; + } + long offset = dst_start_offset_minutes + dst_length_minutes; + if (time_of_day >= time_duration_type(0,offset,0)) { + return is_in_dst; + } + return invalid_time_label; + } + + //! Check the local time offset when on the last day of dst + /*! This is the calculation for the DST end day. On that day times + * prior to the conversion time - dst_length (1 am in US) are still + * in dst. Times between the above and the switch time are + * ambiguous. Times after the start_offset are not in dst. + *@param time_of_day Time offset in the day for the local time + *@param dst_end_offset_minutes Local time of day for end of dst + *@retval status of time label w.r.t. dst + */ + static time_is_dst_result + process_local_dst_end_day(const time_duration_type& time_of_day, + unsigned int dst_end_offset_minutes, + long dst_length_minutes) + { + //in US this will be 60 so offset in day is 1,0,0 + int offset = dst_end_offset_minutes-dst_length_minutes; + if (time_of_day < time_duration_type(0,offset,0)) { + return is_in_dst; + } + if (time_of_day >= time_duration_type(0,dst_end_offset_minutes,0)) { + return is_not_in_dst; + } + return ambiguous; + } + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @param current_day The day to check for dst + * @param time_of_day Time offset within the day to check + * @param dst_start_day Starting day of dst for the given locality + * @param dst_start_offset Time offset within day for dst boundary + * @param dst_end_day Ending day of dst for the given locality + * @param dst_end_offset Time offset within day given in dst for dst boundary + * @param dst_length lenght of dst adjusment + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result + local_is_dst(const date_type& current_day, + const time_duration_type& time_of_day, + const date_type& dst_start_day, + const time_duration_type& dst_start_offset, + const date_type& dst_end_day, + const time_duration_type& dst_end_offset, + const time_duration_type& dst_length_minutes) + { + unsigned int start_minutes = static_cast( + dst_start_offset.hours() * 60 + dst_start_offset.minutes()); + unsigned int end_minutes = static_cast( + dst_end_offset.hours() * 60 + dst_end_offset.minutes()); + long length_minutes = static_cast( + dst_length_minutes.hours() * 60 + dst_length_minutes.minutes()); + + return local_is_dst(current_day, time_of_day, + dst_start_day, start_minutes, + dst_end_day, end_minutes, + length_minutes); + } + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @param current_day The day to check for dst + * @param time_of_day Time offset within the day to check + * @param dst_start_day Starting day of dst for the given locality + * @param dst_start_offset_minutes Offset within day for dst + * boundary (eg 120 for US which is 02:00:00) + * @param dst_end_day Ending day of dst for the given locality + * @param dst_end_offset_minutes Offset within day given in dst for dst + * boundary (eg 120 for US which is 02:00:00) + * @param dst_length_minutes Length of dst adjusment (eg: 60 for US) + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result + local_is_dst(const date_type& current_day, + const time_duration_type& time_of_day, + const date_type& dst_start_day, + unsigned int dst_start_offset_minutes, + const date_type& dst_end_day, + unsigned int dst_end_offset_minutes, + long dst_length_minutes) + { + //in northern hemisphere dst is in the middle of the year + if (dst_start_day < dst_end_day) { + if ((current_day > dst_start_day) && (current_day < dst_end_day)) { + return is_in_dst; + } + if ((current_day < dst_start_day) || (current_day > dst_end_day)) { + return is_not_in_dst; + } + } + else {//southern hemisphere dst is at begining /end of year + if ((current_day < dst_start_day) && (current_day > dst_end_day)) { + return is_not_in_dst; + } + if ((current_day > dst_start_day) || (current_day < dst_end_day)) { + return is_in_dst; + } + } + + if (current_day == dst_start_day) { + return process_local_dst_start_day(time_of_day, + dst_start_offset_minutes, + dst_length_minutes); + } + + if (current_day == dst_end_day) { + return process_local_dst_end_day(time_of_day, + dst_end_offset_minutes, + dst_length_minutes); + } + //you should never reach this statement + return invalid_time_label; + } + + }; + + + //! Compile-time configurable daylight savings time calculation engine + /* This template provides the ability to configure a daylight savings + * calculation at compile time covering all the cases. Unfortunately + * because of the number of dimensions related to daylight savings + * calculation the number of parameters is high. In addition, the + * start and end transition rules are complex types that specify + * an algorithm for calculation of the starting day and ending + * day of daylight savings time including the month and day + * specifications (eg: last sunday in October). + * + * @param date_type A type that represents dates, typically gregorian::date + * @param time_duration_type Used for the offset in the day calculations + * @param dst_traits A set of traits that define the rules of dst + * calculation. The dst_trait must include the following: + * start_rule_functor - Rule to calculate the starting date of a + * dst transition (eg: last_kday_of_month). + * start_day - static function that returns month of dst start for + * start_rule_functor + * start_month -static function that returns day or day of week for + * dst start of dst + * end_rule_functor - Rule to calculate the end of dst day. + * end_day - static fucntion that returns end day for end_rule_functor + * end_month - static function that returns end month for end_rule_functor + * dst_start_offset_minutes - number of minutes from start of day to transition to dst -- 120 (or 2:00 am) is typical for the U.S. and E.U. + * dst_start_offset_minutes - number of minutes from start of day to transition off of dst -- 180 (or 3:00 am) is typical for E.U. + * dst_length_minutes - number of minutes that dst shifts clock + */ + template + class dst_calc_engine + { + public: + typedef typename date_type::year_type year_type; + typedef typename date_type::calendar_type calendar_type; + typedef dst_calculator dstcalc; + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result local_is_dst(const date_type& d, + const time_duration_type& td) + { + + year_type y = d.year(); + date_type dst_start = local_dst_start_day(y); + date_type dst_end = local_dst_end_day(y); + return dstcalc::local_is_dst(d,td, + dst_start, + dst_traits::dst_start_offset_minutes(), + dst_end, + dst_traits::dst_end_offset_minutes(), + dst_traits::dst_shift_length_minutes()); + + } + + static bool is_dst_boundary_day(date_type d) + { + year_type y = d.year(); + return ((d == local_dst_start_day(y)) || + (d == local_dst_end_day(y))); + } + + //! The time of day for the dst transition (eg: typically 01:00:00 or 02:00:00) + static time_duration_type dst_offset() + { + return time_duration_type(0,dst_traits::dst_shift_length_minutes(),0); + } + + static date_type local_dst_start_day(year_type year) + { + return dst_traits::local_dst_start_day(year); + } + + static date_type local_dst_end_day(year_type year) + { + return dst_traits::local_dst_end_day(year); + } + + + }; + + //! Depricated: Class to calculate dst boundaries for US time zones + /* Use dst_calc_engine instead. + * In 2007 US/Canada DST rules changed + * (http://en.wikipedia.org/wiki/Energy_Policy_Act_of_2005#Change_to_daylight_saving_time). + */ + template //1 hour == 60 min in US + class us_dst_rules + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + typedef typename date_type::year_type year_type; + typedef typename date_type::calendar_type calendar_type; + typedef date_time::last_kday_of_month lkday; + typedef date_time::first_kday_of_month fkday; + typedef date_time::nth_kday_of_month nkday; + typedef dst_calculator dstcalc; + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result local_is_dst(const date_type& d, + const time_duration_type& td) + { + + year_type y = d.year(); + date_type dst_start = local_dst_start_day(y); + date_type dst_end = local_dst_end_day(y); + return dstcalc::local_is_dst(d,td, + dst_start,dst_start_offset_minutes, + dst_end, dst_start_offset_minutes, + dst_length_minutes); + + } + + + static bool is_dst_boundary_day(date_type d) + { + year_type y = d.year(); + return ((d == local_dst_start_day(y)) || + (d == local_dst_end_day(y))); + } + + static date_type local_dst_start_day(year_type year) + { + if (year >= year_type(2007)) { + //second sunday in march + nkday ssim(nkday::second, Sunday, gregorian::Mar); + return ssim.get_date(year); + } else { + //first sunday in april + fkday fsia(Sunday, gregorian::Apr); + return fsia.get_date(year); + } + } + + static date_type local_dst_end_day(year_type year) + { + if (year >= year_type(2007)) { + //first sunday in november + fkday fsin(Sunday, gregorian::Nov); + return fsin.get_date(year); + } else { + //last sunday in october + lkday lsio(Sunday, gregorian::Oct); + return lsio.get_date(year); + } + } + + static time_duration_type dst_offset() + { + return time_duration_type(0,dst_length_minutes,0); + } + + private: + + + }; + + //! Used for local time adjustments in places that don't use dst + template + class null_dst_rules + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + + + //! Calculates if the given local time is dst or not + /*! @retval Always is_not_in_dst since this is for zones without dst + */ + static time_is_dst_result local_is_dst(const date_type&, + const time_duration_type&) + { + return is_not_in_dst; + } + + //! Calculates if the given utc time is in dst + static time_is_dst_result utc_is_dst(const date_type&, + const time_duration_type&) + { + return is_not_in_dst; + } + + static bool is_dst_boundary_day(date_type /*d*/) + { + return false; + } + + static time_duration_type dst_offset() + { + return time_duration_type(0,0,0); + } + + }; + + + } } //namespace date_time + + + +#endif diff --git a/boost/date_time/filetime_functions.hpp b/boost/date_time/filetime_functions.hpp new file mode 100644 index 00000000..f5ef7bfb --- /dev/null +++ b/boost/date_time/filetime_functions.hpp @@ -0,0 +1,84 @@ +#ifndef DATE_TIME_FILETIME_FUNCTIONS_HPP__ +#define DATE_TIME_FILETIME_FUNCTIONS_HPP__ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file filetime_functions.hpp + * Function(s) for converting between a FILETIME structure and a + * time object. This file is only available on systems that have + * BOOST_HAS_FTIME defined. + */ + +#include + +#if defined(BOOST_HAS_FTIME) // skip this file if no FILETIME + +#include +#include +#include + +namespace boost { + +namespace date_time { + +//! Create a time object from an initialized FILETIME struct. +/*! + * Create a time object from an initialized FILETIME struct. + * A FILETIME struct holds 100-nanosecond units (0.0000001). When + * built with microsecond resolution the file_time's sub second value + * will be truncated. Nanosecond resolution has no truncation. + * + * \note The function is templated on the FILETIME type, so that + * it can be used with both native FILETIME and the ad-hoc + * boost::detail::winapi::FILETIME_ type. + */ +template< typename TimeT, typename FileTimeT > +inline +TimeT time_from_ftime(const FileTimeT& ft) +{ + typedef typename TimeT::date_type date_type; + typedef typename TimeT::date_duration_type date_duration_type; + typedef typename TimeT::time_duration_type time_duration_type; + + // https://svn.boost.org/trac/boost/ticket/2523 + // Since this function can be called with arbitrary times, including ones that + // are before 1970-Jan-01, we'll have to cast the time a bit differently, + // than it is done in the microsec_clock::file_time_to_microseconds function. This allows to + // avoid integer wrapping for dates before 1970-Jan-01. + + // 100-nanos since 1601-Jan-01 + uint64_t ft_as_integer = (static_cast< uint64_t >(ft.dwHighDateTime) << 32) | static_cast< uint64_t >(ft.dwLowDateTime); + uint64_t sec = ft_as_integer / 10000000UL; + uint32_t sub_sec = static_cast< uint32_t >(ft_as_integer % 10000000UL) // 100-nanoseconds since the last second +#if !defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG) + / 10U; // microseconds since the last second +#else + * 100U; // nanoseconds since the last second +#endif + + // split sec into usable chunks: days, hours, minutes, & seconds + const uint32_t sec_per_day = 86400; // seconds per day + uint32_t days = static_cast< uint32_t >(sec / sec_per_day); + uint32_t tmp = static_cast< uint32_t >(sec % sec_per_day); + uint32_t hours = tmp / 3600; // sec_per_hour + tmp %= 3600; + uint32_t minutes = tmp / 60; // sec_per_min + tmp %= 60; + uint32_t seconds = tmp; // seconds + + date_duration_type dd(days); + date_type d = date_type(1601, Jan, 01) + dd; + return TimeT(d, time_duration_type(hours, minutes, seconds, sub_sec)); +} + +}} // boost::date_time + +#endif // BOOST_HAS_FTIME + +#endif // DATE_TIME_FILETIME_FUNCTIONS_HPP__ diff --git a/boost/date_time/gregorian/conversion.hpp b/boost/date_time/gregorian/conversion.hpp new file mode 100644 index 00000000..c844c4e3 --- /dev/null +++ b/boost/date_time/gregorian/conversion.hpp @@ -0,0 +1,68 @@ +#ifndef _GREGORIAN__CONVERSION_HPP___ +#define _GREGORIAN__CONVERSION_HPP___ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace gregorian { + + //! Converts a date to a tm struct. Throws out_of_range exception if date is a special value + inline + std::tm to_tm(const date& d) + { + if (d.is_special()) + { + std::string s = "tm unable to handle "; + switch (d.as_special()) + { + case date_time::not_a_date_time: + s += "not-a-date-time value"; break; + case date_time::neg_infin: + s += "-infinity date value"; break; + case date_time::pos_infin: + s += "+infinity date value"; break; + default: + s += "a special date value"; break; + } + boost::throw_exception(std::out_of_range(s)); + } + + std::tm datetm; + std::memset(&datetm, 0, sizeof(datetm)); + boost::gregorian::date::ymd_type ymd = d.year_month_day(); + datetm.tm_year = ymd.year - 1900; + datetm.tm_mon = ymd.month - 1; + datetm.tm_mday = ymd.day; + datetm.tm_wday = d.day_of_week(); + datetm.tm_yday = d.day_of_year() - 1; + datetm.tm_isdst = -1; // negative because not enough info to set tm_isdst + return datetm; + } + + //! Converts a tm structure into a date dropping the any time values. + inline + date date_from_tm(const std::tm& datetm) + { + return date(static_cast(datetm.tm_year+1900), + static_cast(datetm.tm_mon+1), + static_cast(datetm.tm_mday)); + } + +} } //namespace boost::gregorian + +#endif diff --git a/boost/date_time/gregorian/formatters.hpp b/boost/date_time/gregorian/formatters.hpp new file mode 100644 index 00000000..d486ef0f --- /dev/null +++ b/boost/date_time/gregorian/formatters.hpp @@ -0,0 +1,162 @@ +#ifndef GREGORIAN_FORMATTERS_HPP___ +#define GREGORIAN_FORMATTERS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/gregorian/gregorian_types.hpp" +#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +#include "boost/date_time/date_formatting_limited.hpp" +#else +#include "boost/date_time/date_formatting.hpp" +#endif +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_format_simple.hpp" + +/* NOTE: "to_*_string" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * formatters_limited.hpp + */ + +namespace boost { +namespace gregorian { + + // wrapper function for to_simple_(w)string(date) + template + inline + std::basic_string to_simple_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date& d) { + return to_simple_string_type(d); + } + + + // wrapper function for to_simple_(w)string(date_period) + template + inline std::basic_string to_simple_string_type(const date_period& d) { + typedef std::basic_string string_type; + charT b = '[', m = '/', e=']'; + + string_type d1(date_time::date_formatter,charT>::date_to_string(d.begin())); + string_type d2(date_time::date_formatter,charT>::date_to_string(d.last())); + return string_type(b + d1 + m + d2 + e); + } + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date_period& d) { + return to_simple_string_type(d); + } + + // wrapper function for to_iso_(w)string(date_period) + template + inline std::basic_string to_iso_string_type(const date_period& d) { + charT sep = '/'; + std::basic_string s(date_time::date_formatter,charT>::date_to_string(d.begin())); + return s + sep + date_time::date_formatter,charT>::date_to_string(d.last()); + } + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date_period& d) { + return to_iso_string_type(d); + } + + + // wrapper function for to_iso_extended_(w)string(date) + template + inline std::basic_string to_iso_extended_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::string to_iso_extended_string(const date& d) { + return to_iso_extended_string_type(d); + } + + // wrapper function for to_iso_(w)string(date) + template + inline std::basic_string to_iso_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date& d) { + return to_iso_string_type(d); + } + + + + + // wrapper function for to_sql_(w)string(date) + template + inline std::basic_string to_sql_string_type(const date& d) + { + date::ymd_type ymd = d.year_month_day(); + std::basic_ostringstream ss; + ss << ymd.year << "-" + << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.month.as_number() //solves problem with gcc 3.1 hanging + << "-" + << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.day; + return ss.str(); + } + inline std::string to_sql_string(const date& d) { + return to_sql_string_type(d); + } + + +#if !defined(BOOST_NO_STD_WSTRING) + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::wstring to_simple_wstring(const date_period& d) { + return to_simple_string_type(d); + } + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::wstring to_simple_wstring(const date& d) { + return to_simple_string_type(d); + } + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::wstring to_iso_wstring(const date_period& d) { + return to_iso_string_type(d); + } + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::wstring to_iso_extended_wstring(const date& d) { + return to_iso_extended_string_type(d); + } + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::wstring to_iso_wstring(const date& d) { + return to_iso_string_type(d); + } + inline std::wstring to_sql_wstring(const date& d) { + return to_sql_string_type(d); + } +#endif // BOOST_NO_STD_WSTRING + +} } //namespace gregorian + + +#endif + diff --git a/boost/date_time/gregorian/formatters_limited.hpp b/boost/date_time/gregorian/formatters_limited.hpp new file mode 100644 index 00000000..755f5aa6 --- /dev/null +++ b/boost/date_time/gregorian/formatters_limited.hpp @@ -0,0 +1,81 @@ +#ifndef GREGORIAN_FORMATTERS_LIMITED_HPP___ +#define GREGORIAN_FORMATTERS_LIMITED_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/date_formatting_limited.hpp" +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_format_simple.hpp" +#include "boost/date_time/compiler_config.hpp" + +namespace boost { +namespace gregorian { + + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date& d) { + return date_time::date_formatter >::date_to_string(d); + } + + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date_period& d) { + std::string s("["); + std::string d1(date_time::date_formatter >::date_to_string(d.begin())); + std::string d2(date_time::date_formatter >::date_to_string(d.last())); + return std::string("[" + d1 + "/" + d2 + "]"); + } + + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date_period& d) { + std::string s(date_time::date_formatter >::date_to_string(d.begin())); + return s + "/" + date_time::date_formatter >::date_to_string(d.last()); + } + + + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::string to_iso_extended_string(const date& d) { + return date_time::date_formatter >::date_to_string(d); + } + + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date& d) { + return date_time::date_formatter >::date_to_string(d); + } + + + + inline std::string to_sql_string(const date& d) + { + date::ymd_type ymd = d.year_month_day(); + std::ostringstream ss; + ss << ymd.year << "-" + << std::setw(2) << std::setfill('0') + << ymd.month.as_number() //solves problem with gcc 3.1 hanging + << "-" + << std::setw(2) << std::setfill('0') + << ymd.day; + return ss.str(); + } + + +} } //namespace gregorian + + +#endif + diff --git a/boost/date_time/gregorian/greg_calendar.hpp b/boost/date_time/gregorian/greg_calendar.hpp new file mode 100644 index 00000000..16e47c1d --- /dev/null +++ b/boost/date_time/gregorian/greg_calendar.hpp @@ -0,0 +1,49 @@ +#ifndef GREGORIAN_GREGORIAN_CALENDAR_HPP__ +#define GREGORIAN_GREGORIAN_CALENDAR_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //!An internal date representation that includes infinities, not a date + typedef date_time::int_adapter fancy_date_rep; + + //! Gregorian calendar for this implementation, hard work in the base + class BOOST_SYMBOL_VISIBLE gregorian_calendar : + public date_time::gregorian_calendar_base { + public: + //! Type to hold a weekday (eg: Sunday, Monday,...) + typedef greg_weekday day_of_week_type; + //! Counter type from 1 to 366 for gregorian dates. + typedef greg_day_of_year_rep day_of_year_type; + //! Internal date representation that handles infinity, not a date + typedef fancy_date_rep date_rep_type; + //! Date rep implements the traits stuff as well + typedef fancy_date_rep date_traits_type; + + + private: + }; + +} } //namespace gregorian + + + + +#endif + diff --git a/boost/date_time/gregorian/greg_date.hpp b/boost/date_time/gregorian/greg_date.hpp new file mode 100644 index 00000000..4f56bedf --- /dev/null +++ b/boost/date_time/gregorian/greg_date.hpp @@ -0,0 +1,137 @@ +#ifndef GREG_DATE_HPP___ +#define GREG_DATE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //bring special enum values into the namespace + using date_time::special_values; + using date_time::not_special; + using date_time::neg_infin; + using date_time::pos_infin; + using date_time::not_a_date_time; + using date_time::max_date_time; + using date_time::min_date_time; + + //! A date type based on gregorian_calendar + /*! This class is the primary interface for programming with + greogorian dates. The is a lightweight type that can be + freely passed by value. All comparison operators are + supported. + \ingroup date_basics + */ + class BOOST_SYMBOL_VISIBLE date : public date_time::date + { + public: + typedef gregorian_calendar::year_type year_type; + typedef gregorian_calendar::month_type month_type; + typedef gregorian_calendar::day_type day_type; + typedef gregorian_calendar::day_of_year_type day_of_year_type; + typedef gregorian_calendar::ymd_type ymd_type; + typedef gregorian_calendar::date_rep_type date_rep_type; + typedef gregorian_calendar::date_int_type date_int_type; + typedef date_duration duration_type; +#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR) + //! Default constructor constructs with not_a_date_time + date(): + date_time::date(date_rep_type::from_special(not_a_date_time)) + {} +#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR + //! Main constructor with year, month, day + date(year_type y, month_type m, day_type d) + : date_time::date(y, m, d) + { + if (gregorian_calendar::end_of_month_day(y, m) < d) { + boost::throw_exception(bad_day_of_month(std::string("Day of month is not valid for year"))); + } + } + //! Constructor from a ymd_type structure + explicit date(const ymd_type& ymd) + : date_time::date(ymd) + {} + //! Needed copy constructor + explicit date(const date_int_type& rhs): + date_time::date(rhs) + {} + //! Needed copy constructor + explicit date(date_rep_type rhs): + date_time::date(rhs) + {} + //! Constructor for infinities, not a date, max and min date + explicit date(special_values sv): + date_time::date(date_rep_type::from_special(sv)) + { + if (sv == min_date_time) + { + *this = date(1400, 1, 1); + } + if (sv == max_date_time) + { + *this = date(9999, 12, 31); + } + + } + //!Return the Julian Day number for the date. + date_int_type julian_day() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::julian_day_number(ymd); + } + //!Return the day of year 1..365 or 1..366 (for leap year) + day_of_year_type day_of_year() const + { + date start_of_year(year(), 1, 1); + unsigned short doy = static_cast((*this-start_of_year).days() + 1); + return day_of_year_type(doy); + } + //!Return the Modified Julian Day number for the date. + date_int_type modjulian_day() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::modjulian_day_number(ymd); + } + //!Return the iso 8601 week number 1..53 + int week_number() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::week_number(ymd); + } + //! Return the day number from the calendar + date_int_type day_number() const + { + return days_; + } + //! Return the last day of the current month + date end_of_month() const + { + ymd_type ymd = year_month_day(); + short eom_day = gregorian_calendar::end_of_month_day(ymd.year, ymd.month); + return date(ymd.year, ymd.month, eom_day); + } + + private: + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/boost/date_time/gregorian/greg_day.hpp b/boost/date_time/gregorian/greg_day.hpp new file mode 100644 index 00000000..014abfbd --- /dev/null +++ b/boost/date_time/gregorian/greg_day.hpp @@ -0,0 +1,58 @@ +#ifndef GREG_DAY_HPP___ +#define GREG_DAY_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for gregorian day of month (1..31) + struct BOOST_SYMBOL_VISIBLE bad_day_of_month : public std::out_of_range + { + bad_day_of_month() : + std::out_of_range(std::string("Day of month value is out of range 1..31")) + {} + //! Allow other classes to throw with unique string for bad day like Feb 29 + bad_day_of_month(const std::string& s) : + std::out_of_range(s) + {} + }; + //! Policy class that declares error handling and day of month ranges + typedef CV::simple_exception_policy greg_day_policies; + + //! Generated represetation for gregorian day of month + typedef CV::constrained_value greg_day_rep; + + //! Represent a day of the month (range 1 - 31) + /*! This small class allows for simple conversion an integer value into + a day of the month for a standard gregorian calendar. The type + is automatically range checked so values outside of the range 1-31 + will cause a bad_day_of_month exception + */ + class BOOST_SYMBOL_VISIBLE greg_day : public greg_day_rep { + public: + greg_day(value_type day_of_month) : greg_day_rep(day_of_month) {} + value_type as_number() const {return value_;} + operator value_type() const {return value_;} + private: + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/boost/date_time/gregorian/greg_day_of_year.hpp b/boost/date_time/gregorian/greg_day_of_year.hpp new file mode 100644 index 00000000..3f753e1d --- /dev/null +++ b/boost/date_time/gregorian/greg_day_of_year.hpp @@ -0,0 +1,39 @@ +#ifndef GREG_DAY_OF_YEAR_HPP___ +#define GREG_DAY_OF_YEAR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for day of year (1..366) + struct BOOST_SYMBOL_VISIBLE bad_day_of_year : public std::out_of_range + { + bad_day_of_year() : + std::out_of_range(std::string("Day of year value is out of range 1..366")) + {} + }; + + //! A day of the year range (1..366) + typedef CV::simple_exception_policy greg_day_of_year_policies; + + //! Define a range representation type for the day of the year 1..366 + typedef CV::constrained_value greg_day_of_year_rep; + + +} } //namespace gregorian + + + +#endif diff --git a/boost/date_time/gregorian/greg_duration.hpp b/boost/date_time/gregorian/greg_duration.hpp new file mode 100644 index 00000000..3b1a4978 --- /dev/null +++ b/boost/date_time/gregorian/greg_duration.hpp @@ -0,0 +1,135 @@ +#ifndef GREG_DURATION_HPP___ +#define GREG_DURATION_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //!An internal date representation that includes infinities, not a date + typedef boost::date_time::duration_traits_adapted date_duration_rep; + + //! Durations in days for gregorian system + /*! \ingroup date_basics + */ + class BOOST_SYMBOL_VISIBLE date_duration : + public boost::date_time::date_duration< date_duration_rep > + { + typedef boost::date_time::date_duration< date_duration_rep > base_type; + + public: + typedef base_type::duration_rep duration_rep; + + //! Construct from a day count + explicit date_duration(duration_rep day_count = 0) : base_type(day_count) {} + + //! construct from special_values + date_duration(date_time::special_values sv) : base_type(sv) {} + + //! Copy constructor + date_duration(const date_duration& other) : base_type(static_cast< base_type const& >(other)) + {} + + //! Construct from another date_duration + date_duration(const base_type& other) : base_type(other) + {} + + // Relational operators + // NOTE: Because of date_time::date_duration< T > design choice we don't use Boost.Operators here, + // because we need the class to be a direct base. Either lose EBO, or define operators by hand. + // The latter is more effecient. + bool operator== (const date_duration& rhs) const + { + return base_type::operator== (rhs); + } + bool operator!= (const date_duration& rhs) const + { + return !operator== (rhs); + } + bool operator< (const date_duration& rhs) const + { + return base_type::operator< (rhs); + } + bool operator> (const date_duration& rhs) const + { + return !(base_type::operator< (rhs) || base_type::operator== (rhs)); + } + bool operator<= (const date_duration& rhs) const + { + return (base_type::operator< (rhs) || base_type::operator== (rhs)); + } + bool operator>= (const date_duration& rhs) const + { + return !base_type::operator< (rhs); + } + + //! Subtract another duration -- result is signed + date_duration& operator-= (const date_duration& rhs) + { + base_type::operator-= (rhs); + return *this; + } + friend date_duration operator- (date_duration rhs, date_duration const& lhs) + { + rhs -= lhs; + return rhs; + } + + //! Add a duration -- result is signed + date_duration& operator+= (const date_duration& rhs) + { + base_type::operator+= (rhs); + return *this; + } + friend date_duration operator+ (date_duration rhs, date_duration const& lhs) + { + rhs += lhs; + return rhs; + } + + //! unary- Allows for dd = -date_duration(2); -> dd == -2 + date_duration operator- ()const + { + return date_duration(get_rep() * (-1)); + } + + //! Division operations on a duration with an integer. + date_duration& operator/= (int divisor) + { + base_type::operator/= (divisor); + return *this; + } + friend date_duration operator/ (date_duration rhs, int lhs) + { + rhs /= lhs; + return rhs; + } + + //! Returns the smallest duration -- used by to calculate 'end' + static date_duration unit() + { + return date_duration(base_type::unit().get_rep()); + } + }; + + //! Shorthand for date_duration + typedef date_duration days; + +} } //namespace gregorian + +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include +#endif + +#endif diff --git a/boost/date_time/gregorian/greg_duration_types.hpp b/boost/date_time/gregorian/greg_duration_types.hpp new file mode 100644 index 00000000..e6611e68 --- /dev/null +++ b/boost/date_time/gregorian/greg_duration_types.hpp @@ -0,0 +1,44 @@ +#ifndef GREG_DURATION_TYPES_HPP___ +#define GREG_DURATION_TYPES_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! config struct for additional duration types (ie months_duration<> & years_duration<>) + struct BOOST_SYMBOL_VISIBLE greg_durations_config { + typedef date date_type; + typedef date_time::int_adapter int_rep; + typedef date_time::month_functor month_adjustor_type; + }; + + typedef date_time::months_duration months; + typedef date_time::years_duration years; + + class BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration { + public: + weeks_duration(duration_rep w) + : date_duration(w * 7) {} + weeks_duration(date_time::special_values sv) + : date_duration(sv) {} + }; + + typedef weeks_duration weeks; + +}} // namespace boost::gregorian + +#endif // GREG_DURATION_TYPES_HPP___ diff --git a/boost/date_time/gregorian/greg_facet.hpp b/boost/date_time/gregorian/greg_facet.hpp new file mode 100644 index 00000000..5352df13 --- /dev/null +++ b/boost/date_time/gregorian/greg_facet.hpp @@ -0,0 +1,374 @@ +#ifndef GREGORIAN_FACET_HPP___ +#define GREGORIAN_FACET_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include // sets BOOST_DATE_TIME_NO_LOCALE +#include +#include + +//This file is basically commented out if locales are not supported +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Configuration of the output facet template + struct BOOST_SYMBOL_VISIBLE greg_facet_config + { + typedef boost::gregorian::greg_month month_type; + typedef boost::date_time::special_values special_value_enum; + typedef boost::gregorian::months_of_year month_enum; + typedef boost::date_time::weekdays weekday_enum; + }; + +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) + //! Create the base facet type for gregorian::date + typedef boost::date_time::date_names_put greg_base_facet; + + //! ostream operator for gregorian::date + /*! Uses the date facet to determine various output parameters including: + * - string values for the month (eg: Jan, Feb, Mar) (default: English) + * - string values for special values (eg: not-a-date-time) (default: English) + * - selection of long, short strings, or numerical month representation (default: short string) + * - month day year order (default yyyy-mmm-dd) + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const date& d) + { + typedef boost::date_time::date_names_put facet_def; + typedef boost::date_time::ostream_date_formatter greg_ostream_formatter; + greg_ostream_formatter::date_put(d, os); + return os; + } + + //! operator<< for gregorian::greg_month typically streaming: Jan, Feb, Mar... + /*! Uses the date facet to determine output string as well as selection of long or short strings. + * Default if no facet is installed is to output a 2 wide numeric value for the month + * eg: 01 == Jan, 02 == Feb, ... 12 == Dec. + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const greg_month& m) + { + typedef boost::date_time::date_names_put facet_def; + typedef boost::date_time::ostream_month_formatter greg_month_formatter; + std::locale locale = os.getloc(); + if (std::has_facet(locale)) { + const facet_def& f = std::use_facet(locale); + greg_month_formatter::format_month(m, os, f); + + } + else { // default to numeric + boost::io::basic_ios_fill_saver ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << m.as_number(); + } + + return os; + } + + //! operator<< for gregorian::greg_weekday typically streaming: Sun, Mon, Tue, ... + /*! Uses the date facet to determine output string as well as selection of long or short string. + * Default if no facet is installed is to output a 3 char english string for the + * day of the week. + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const greg_weekday& wd) + { + typedef boost::date_time::date_names_put facet_def; + typedef boost::date_time::ostream_weekday_formatter greg_weekday_formatter; + std::locale locale = os.getloc(); + if (std::has_facet(locale)) { + const facet_def& f = std::use_facet(locale); + greg_weekday_formatter::format_weekday(wd, os, f, true); + } + else { //default to short English string eg: Sun, Mon, Tue, Wed... + os << wd.as_short_string(); + } + + return os; + } + + //! operator<< for gregorian::date_period typical output: [2002-Jan-01/2002-Jan-31] + /*! Uses the date facet to determine output string as well as selection of long + * or short string fr dates. + * Default if no facet is installed is to output a 3 char english string for the + * day of the week. + */ + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const date_period& dp) + { + os << '['; //TODO: facet or manipulator for periods? + os << dp.begin(); + os << '/'; //TODO: facet or manipulator for periods? + os << dp.last(); + os << ']'; + return os; + } + + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const date_duration& dd) + { + //os << dd.days(); + os << dd.get_rep(); + return os; + } + + //! operator<< for gregorian::partial_date. Output: "Jan 1" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const partial_date& pd) + { + boost::io::basic_ios_fill_saver ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << pd.day() << ' ' + << pd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::nth_kday_of_month. Output: "first Mon of Jun" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const nth_kday_of_month& nkd) + { + os << nkd.nth_week_as_str() << ' ' + << nkd.day_of_week() << " of " + << nkd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::first_kday_of_month. Output: "first Mon of Jun" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const first_kday_of_month& fkd) + { + os << "first " << fkd.day_of_week() << " of " + << fkd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::last_kday_of_month. Output: "last Mon of Jun" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const last_kday_of_month& lkd) + { + os << "last " << lkd.day_of_week() << " of " + << lkd.month().as_short_string() ; + return os; + } + + //! operator<< for gregorian::first_kday_after. Output: "first Mon after" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const first_kday_after& fka) + { + os << fka.day_of_week() << " after"; + return os; + } + + //! operator<< for gregorian::first_kday_before. Output: "first Mon before" + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const first_kday_before& fkb) + { + os << fkb.day_of_week() << " before"; + return os; + } +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + /**************** Input Streaming ******************/ + +#if !defined(BOOST_NO_STD_ITERATOR_TRAITS) + //! operator>> for gregorian::date + template + inline + std::basic_istream& operator>>(std::basic_istream& is, date& d) + { + std::istream_iterator, charT> beg(is), eos; + d = from_stream(beg, eos); + return is; + } +#endif // BOOST_NO_STD_ITERATOR_TRAITS + + //! operator>> for gregorian::date_duration + template + inline + std::basic_istream& operator>>(std::basic_istream& is, + date_duration& dd) + { + long v; + is >> v; + dd = date_duration(v); + return is; + } + + //! operator>> for gregorian::date_period + template + inline + std::basic_istream& operator>>(std::basic_istream& is, + date_period& dp) + { + std::basic_string s; + is >> s; + dp = date_time::from_simple_string_type(s); + return is; + } + + //! generates a locale with the set of gregorian name-strings of type char* + BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, char type); + + //! Returns a pointer to a facet with a default set of names (English) + /* Necessary in the event an exception is thrown from op>> for + * weekday or month. See comments in those functions for more info */ + BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put* create_facet_def(char type); + +#ifndef BOOST_NO_STD_WSTRING + //! generates a locale with the set of gregorian name-strings of type wchar_t* + BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, wchar_t type); + //! Returns a pointer to a facet with a default set of names (English) + /* Necessary in the event an exception is thrown from op>> for + * weekday or month. See comments in those functions for more info */ + BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put* create_facet_def(wchar_t type); +#endif // BOOST_NO_STD_WSTRING + + //! operator>> for gregorian::greg_month - throws exception if invalid month given + template + inline + std::basic_istream& operator>>(std::basic_istream& is,greg_month& m) + { + typedef boost::date_time::all_date_names_put facet_def; + + std::basic_string s; + is >> s; + + if(!std::has_facet(is.getloc())) { + std::locale loc = is.getloc(); + charT a = '\0'; + is.imbue(generate_locale(loc, a)); + } + + short num = 0; + + try{ + const facet_def& f = std::use_facet(is.getloc()); + num = date_time::find_match(f.get_short_month_names(), + f.get_long_month_names(), + (greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size, + // which is needed by find_match + } + /* bad_cast will be thrown if the desired facet is not accessible + * so we can generate the facet. This has the drawback of using english + * names as a default. */ + catch(std::bad_cast&){ + charT a = '\0'; + +#if defined(BOOST_NO_CXX11_SMART_PTR) + + std::auto_ptr< const facet_def > f(create_facet_def(a)); + +#else + + std::unique_ptr< const facet_def > f(create_facet_def(a)); + +#endif + + num = date_time::find_match(f->get_short_month_names(), + f->get_long_month_names(), + (greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size, + // which is needed by find_match + } + + ++num; // months numbered 1-12 + m = greg_month(num); + + return is; + } + + //! operator>> for gregorian::greg_weekday - throws exception if invalid weekday given + template + inline + std::basic_istream& operator>>(std::basic_istream& is,greg_weekday& wd) + { + typedef boost::date_time::all_date_names_put facet_def; + + std::basic_string s; + is >> s; + + if(!std::has_facet(is.getloc())) { + std::locale loc = is.getloc(); + charT a = '\0'; + is.imbue(generate_locale(loc, a)); + } + + short num = 0; + try{ + const facet_def& f = std::use_facet(is.getloc()); + num = date_time::find_match(f.get_short_weekday_names(), + f.get_long_weekday_names(), + (greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed + // to form the array size which is needed by find_match + } + /* bad_cast will be thrown if the desired facet is not accessible + * so we can generate the facet. This has the drawback of using english + * names as a default. */ + catch(std::bad_cast&){ + charT a = '\0'; + +#if defined(BOOST_NO_CXX11_SMART_PTR) + + std::auto_ptr< const facet_def > f(create_facet_def(a)); + +#else + + std::unique_ptr< const facet_def > f(create_facet_def(a)); + +#endif + + num = date_time::find_match(f->get_short_weekday_names(), + f->get_long_weekday_names(), + (greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed + // to form the array size which is needed by find_match + } + + wd = greg_weekday(num); // weekdays numbered 0-6 + return is; + } + +} } //namespace gregorian + +#endif + +#endif + diff --git a/boost/date_time/gregorian/greg_month.hpp b/boost/date_time/gregorian/greg_month.hpp new file mode 100644 index 00000000..be0f93e1 --- /dev/null +++ b/boost/date_time/gregorian/greg_month.hpp @@ -0,0 +1,105 @@ +#ifndef GREG_MONTH_HPP___ +#define GREG_MONTH_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + typedef date_time::months_of_year months_of_year; + + //bring enum values into the namespace + using date_time::Jan; + using date_time::Feb; + using date_time::Mar; + using date_time::Apr; + using date_time::May; + using date_time::Jun; + using date_time::Jul; + using date_time::Aug; + using date_time::Sep; + using date_time::Oct; + using date_time::Nov; + using date_time::Dec; + using date_time::NotAMonth; + using date_time::NumMonths; + + //! Exception thrown if a greg_month is constructed with a value out of range + struct BOOST_SYMBOL_VISIBLE bad_month : public std::out_of_range + { + bad_month() : std::out_of_range(std::string("Month number is out of range 1..12")) {} + }; + //! Build a policy class for the greg_month_rep + typedef CV::simple_exception_policy greg_month_policies; + //! A constrained range that implements the gregorian_month rules + typedef CV::constrained_value greg_month_rep; + + + //! Wrapper class to represent months in gregorian based calendar + class BOOST_DATE_TIME_DECL greg_month : public greg_month_rep { + public: + typedef date_time::months_of_year month_enum; + typedef std::map month_map_type; + typedef boost::shared_ptr month_map_ptr_type; + //! Construct a month from the months_of_year enumeration + greg_month(month_enum theMonth) : + greg_month_rep(static_cast(theMonth)) {} + //! Construct from a short value + greg_month(value_type theMonth) : greg_month_rep(theMonth) {} + //! Convert the value back to a short + operator value_type() const {return value_;} + //! Returns month as number from 1 to 12 + value_type as_number() const {return value_;} + month_enum as_enum() const {return static_cast(value_);} + const char* as_short_string() const; + const char* as_long_string() const; +#ifndef BOOST_NO_STD_WSTRING + const wchar_t* as_short_wstring() const; + const wchar_t* as_long_wstring() const; +#endif // BOOST_NO_STD_WSTRING + //! Shared pointer to a map of Month strings (Names & Abbrev) & numbers + static month_map_ptr_type get_month_map_ptr(); + + /* parameterized as_*_string functions are intended to be called + * from a template function: "... as_short_string(charT c='\0');" */ + const char* as_short_string(char) const + { + return as_short_string(); + } + const char* as_long_string(char) const + { + return as_long_string(); + } +#ifndef BOOST_NO_STD_WSTRING + const wchar_t* as_short_string(wchar_t) const + { + return as_short_wstring(); + } + const wchar_t* as_long_string(wchar_t) const + { + return as_long_wstring(); + } +#endif // BOOST_NO_STD_WSTRING + }; + +} } //namespace gregorian + + + +#endif diff --git a/boost/date_time/gregorian/greg_weekday.hpp b/boost/date_time/gregorian/greg_weekday.hpp new file mode 100644 index 00000000..815051ed --- /dev/null +++ b/boost/date_time/gregorian/greg_weekday.hpp @@ -0,0 +1,66 @@ +#ifndef GREG_WEEKDAY_HPP___ +#define GREG_WEEKDAY_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //bring enum values into the namespace + using date_time::Sunday; + using date_time::Monday; + using date_time::Tuesday; + using date_time::Wednesday; + using date_time::Thursday; + using date_time::Friday; + using date_time::Saturday; + + + //! Exception that flags that a weekday number is incorrect + struct BOOST_SYMBOL_VISIBLE bad_weekday : public std::out_of_range + { + bad_weekday() : std::out_of_range(std::string("Weekday is out of range 0..6")) {} + }; + typedef CV::simple_exception_policy greg_weekday_policies; + typedef CV::constrained_value greg_weekday_rep; + + + //! Represent a day within a week (range 0==Sun to 6==Sat) + class BOOST_DATE_TIME_DECL greg_weekday : public greg_weekday_rep { + public: + typedef boost::date_time::weekdays weekday_enum; + greg_weekday(value_type day_of_week_num) : + greg_weekday_rep(day_of_week_num) + {} + + value_type as_number() const {return value_;} + const char* as_short_string() const; + const char* as_long_string() const; +#ifndef BOOST_NO_STD_WSTRING + const wchar_t* as_short_wstring() const; + const wchar_t* as_long_wstring() const; +#endif // BOOST_NO_STD_WSTRING + weekday_enum as_enum() const {return static_cast(value_);} + + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/boost/date_time/gregorian/greg_year.hpp b/boost/date_time/gregorian/greg_year.hpp new file mode 100644 index 00000000..a278bdaa --- /dev/null +++ b/boost/date_time/gregorian/greg_year.hpp @@ -0,0 +1,52 @@ +#ifndef GREG_YEAR_HPP___ +#define GREG_YEAR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for gregorian year + struct BOOST_SYMBOL_VISIBLE bad_year : public std::out_of_range + { + bad_year() : + std::out_of_range(std::string("Year is out of valid range: 1400..9999")) + {} + }; + //! Policy class that declares error handling gregorian year type + typedef CV::simple_exception_policy greg_year_policies; + + //! Generated representation for gregorian year + typedef CV::constrained_value greg_year_rep; + + //! Represent a year (range 1400 - 9999) + /*! This small class allows for simple conversion an integer value into + a year for the gregorian calendar. This currently only allows a + range of 1400 to 9999. Both ends of the range are a bit arbitrary + at the moment, but they are the limits of current testing of the + library. As such they may be increased in the future. + */ + class BOOST_SYMBOL_VISIBLE greg_year : public greg_year_rep { + public: + greg_year(value_type year) : greg_year_rep(year) {} + operator value_type() const {return value_;} + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/boost/date_time/gregorian/greg_ymd.hpp b/boost/date_time/gregorian/greg_ymd.hpp new file mode 100644 index 00000000..503666c3 --- /dev/null +++ b/boost/date_time/gregorian/greg_ymd.hpp @@ -0,0 +1,33 @@ +#ifndef DATE_TIME_GREG_YMD_HPP__ +#define DATE_TIME_GREG_YMD_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include "boost/date_time/year_month_day.hpp" +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/gregorian/greg_day.hpp" +#include "boost/date_time/gregorian/greg_year.hpp" +#include "boost/date_time/gregorian/greg_month.hpp" + +namespace boost { +namespace gregorian { + + typedef date_time::year_month_day_base greg_year_month_day; + + + +} } //namespace gregorian + + + + +#endif + diff --git a/boost/date_time/gregorian/gregorian_types.hpp b/boost/date_time/gregorian/gregorian_types.hpp new file mode 100644 index 00000000..d50e9cc7 --- /dev/null +++ b/boost/date_time/gregorian/gregorian_types.hpp @@ -0,0 +1,109 @@ +#ifndef _GREGORIAN_TYPES_HPP__ +#define _GREGORIAN_TYPES_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file gregorian_types.hpp + Single file header that defines most of the types for the gregorian + date-time system. +*/ + +#include "boost/date_time/date.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/gregorian/greg_calendar.hpp" +#include "boost/date_time/gregorian/greg_duration.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/gregorian/greg_duration_types.hpp" +#endif +#include "boost/date_time/gregorian/greg_date.hpp" +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/date_clock_device.hpp" +#include "boost/date_time/date_iterator.hpp" +#include "boost/date_time/adjust_functors.hpp" + +namespace boost { + +//! Gregorian date system based on date_time components +/*! This date system defines a full complement of types including + * a date, date_duration, date_period, day_clock, and a + * day_iterator. + */ +namespace gregorian { + //! Date periods for the gregorian system + /*!\ingroup date_basics + */ + typedef date_time::period date_period; + + //! A unifying date_generator base type + /*! A unifying date_generator base type for: + * partial_date, nth_day_of_the_week_in_month, + * first_day_of_the_week_in_month, and last_day_of_the_week_in_month + */ + typedef date_time::year_based_generator year_based_generator; + + //! A date generation object type + typedef date_time::partial_date partial_date; + + typedef date_time::nth_kday_of_month nth_kday_of_month; + typedef nth_kday_of_month nth_day_of_the_week_in_month; + + typedef date_time::first_kday_of_month first_kday_of_month; + typedef first_kday_of_month first_day_of_the_week_in_month; + + typedef date_time::last_kday_of_month last_kday_of_month; + typedef last_kday_of_month last_day_of_the_week_in_month; + + typedef date_time::first_kday_after first_kday_after; + typedef first_kday_after first_day_of_the_week_after; + + typedef date_time::first_kday_before first_kday_before; + typedef first_kday_before first_day_of_the_week_before; + + //! A clock to get the current day from the local computer + /*!\ingroup date_basics + */ + typedef date_time::day_clock day_clock; + + //! Base date_iterator type for gregorian types. + /*!\ingroup date_basics + */ + typedef date_time::date_itr_base date_iterator; + + //! A day level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> day_iterator; + //! A week level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> week_iterator; + //! A month level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> month_iterator; + //! A year level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> year_iterator; + + // bring in these date_generator functions from date_time namespace + using date_time::days_until_weekday; + using date_time::days_before_weekday; + using date_time::next_weekday; + using date_time::previous_weekday; + +} } //namespace gregorian + + + +#endif diff --git a/boost/date_time/gregorian/parsers.hpp b/boost/date_time/gregorian/parsers.hpp new file mode 100644 index 00000000..afc6537c --- /dev/null +++ b/boost/date_time/gregorian/parsers.hpp @@ -0,0 +1,91 @@ +#ifndef GREGORIAN_PARSERS_HPP___ +#define GREGORIAN_PARSERS_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/date_parsing.hpp" +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/parse_format_base.hpp" +#include +#include + +namespace boost { +namespace gregorian { + + //! Return special_value from string argument + /*! Return special_value from string argument. If argument is + * not one of the special value names (defined in src/gregorian/names.hpp), + * return 'not_special' */ + BOOST_DATE_TIME_DECL special_values special_value_from_string(const std::string& s); + + //! Deprecated: Use from_simple_string + inline date from_string(std::string s) { + return date_time::parse_date(s); + } + + //! From delimited date string where with order year-month-day eg: 2002-1-25 or 2003-Jan-25 (full month name is also accepted) + inline date from_simple_string(std::string s) { + return date_time::parse_date(s, date_time::ymd_order_iso); + } + + //! From delimited date string where with order year-month-day eg: 1-25-2003 or Jan-25-2003 (full month name is also accepted) + inline date from_us_string(std::string s) { + return date_time::parse_date(s, date_time::ymd_order_us); + } + + //! From delimited date string where with order day-month-year eg: 25-1-2002 or 25-Jan-2003 (full month name is also accepted) + inline date from_uk_string(std::string s) { + return date_time::parse_date(s, date_time::ymd_order_dmy); + } + + //! From iso type date string where with order year-month-day eg: 20020125 + inline date from_undelimited_string(std::string s) { + return date_time::parse_undelimited_date(s); + } + + //! From iso type date string where with order year-month-day eg: 20020125 + inline date date_from_iso_string(const std::string& s) { + return date_time::parse_undelimited_date(s); + } + +#if !(defined(BOOST_NO_STD_ITERATOR_TRAITS)) + //! Stream should hold a date in the form of: 2002-1-25. Month number, abbrev, or name are accepted + /* Arguments passed in by-value for convertability of char[] + * to iterator_type. Calls to from_stream_type are by-reference + * since conversion is already done */ + template + inline date from_stream(iterator_type beg, iterator_type end) { + if(beg == end) + { + return date(not_a_date_time); + } + typedef typename std::iterator_traits::value_type value_type; + return date_time::from_stream_type(beg, end, value_type()); + } +#endif //BOOST_NO_STD_ITERATOR_TRAITS + +#if (defined(_MSC_VER) && (_MSC_VER < 1300)) + // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings +#else + //! Function to parse a date_period from a string (eg: [2003-Oct-31/2003-Dec-25]) + inline date_period date_period_from_string(const std::string& s){ + return date_time::from_simple_string_type(s); + } +# if !defined(BOOST_NO_STD_WSTRING) + //! Function to parse a date_period from a wstring (eg: [2003-Oct-31/2003-Dec-25]) + inline date_period date_period_from_wstring(const std::wstring& s){ + return date_time::from_simple_string_type(s); + } +# endif // BOOST_NO_STD_WSTRING +#endif + +} } //namespace gregorian + +#endif diff --git a/boost/date_time/gregorian_calendar.hpp b/boost/date_time/gregorian_calendar.hpp new file mode 100644 index 00000000..04785929 --- /dev/null +++ b/boost/date_time/gregorian_calendar.hpp @@ -0,0 +1,71 @@ +#ifndef DATE_TIME_GREGORIAN_CALENDAR_HPP__ +#define DATE_TIME_GREGORIAN_CALENDAR_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include + +namespace boost { +namespace date_time { + + + //! An implementation of the Gregorian calendar + /*! This is a parameterized implementation of a proleptic Gregorian Calendar that + can be used in the creation of date systems or just to perform calculations. + All the methods of this class are static functions, so the intent is to + never create instances of this class. + @param ymd_type_ Struct type representing the year, month, day. The ymd_type must + define a of types for the year, month, and day. These types need to be + arithmetic types. + @param date_int_type_ Underlying type for the date count. Must be an arithmetic type. + */ + template + class BOOST_SYMBOL_VISIBLE gregorian_calendar_base { + public: + //! define a type a date split into components + typedef ymd_type_ ymd_type; + //! define a type for representing months + typedef typename ymd_type::month_type month_type; + //! define a type for representing days + typedef typename ymd_type::day_type day_type; + //! Type to hold a stand alone year value (eg: 2002) + typedef typename ymd_type::year_type year_type; + //! Define the integer type to use for internal calculations + typedef date_int_type_ date_int_type; + + + static unsigned short day_of_week(const ymd_type& ymd); + static int week_number(const ymd_type&ymd); + //static unsigned short day_of_year(date_int_type); + static date_int_type day_number(const ymd_type& ymd); + static date_int_type julian_day_number(const ymd_type& ymd); + static date_int_type modjulian_day_number(const ymd_type& ymd); + static ymd_type from_day_number(date_int_type); + static ymd_type from_julian_day_number(date_int_type); + static ymd_type from_modjulian_day_number(date_int_type); + static bool is_leap_year(year_type); + static unsigned short end_of_month_day(year_type y, month_type m); + static ymd_type epoch(); + static unsigned short days_in_week(); + + }; + + + +} } //namespace + +#ifndef NO_BOOST_DATE_TIME_INLINE +#include "boost/date_time/gregorian_calendar.ipp" +#endif + + + +#endif + + diff --git a/boost/date_time/gregorian_calendar.ipp b/boost/date_time/gregorian_calendar.ipp new file mode 100644 index 00000000..7b43ea85 --- /dev/null +++ b/boost/date_time/gregorian_calendar.ipp @@ -0,0 +1,219 @@ +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#ifndef NO_BOOST_DATE_TIME_INLINE + #undef BOOST_DATE_TIME_INLINE + #define BOOST_DATE_TIME_INLINE inline +#endif + +namespace boost { +namespace date_time { + //! Return the day of the week (0==Sunday, 1==Monday, etc) + /*! Converts a year-month-day into a day of the week number + */ + template + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base::day_of_week(const ymd_type& ymd) { + unsigned short a = static_cast((14-ymd.month)/12); + unsigned short y = static_cast(ymd.year - a); + unsigned short m = static_cast(ymd.month + 12*a - 2); + unsigned short d = static_cast((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7); + //std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n"; + return d; + } + + //!Return the iso week number for the date + /*!Implements the rules associated with the iso 8601 week number. + Basically the rule is that Week 1 of the year is the week that contains + January 4th or the week that contains the first Thursday in January. + Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000. + */ + template + BOOST_DATE_TIME_INLINE + int + gregorian_calendar_base::week_number(const ymd_type& ymd) { + unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1)); + unsigned long juliantoday = julian_day_number(ymd); + unsigned long day = (julianbegin + 3) % 7; + unsigned long week = (juliantoday + day - julianbegin + 4)/7; + + if ((week >= 1) && (week <= 52)) { + return static_cast(week); + } + + if (week == 53) { + if((day==6) ||(day == 5 && is_leap_year(ymd.year))) { + return static_cast(week); //under these circumstances week == 53. + } else { + return 1; //monday - wednesday is in week 1 of next year + } + } + //if the week is not in current year recalculate using the previous year as the beginning year + else if (week == 0) { + julianbegin = julian_day_number(ymd_type(static_cast(ymd.year-1),1,1)); + juliantoday = julian_day_number(ymd); + day = (julianbegin + 3) % 7; + week = (juliantoday + day - julianbegin + 4)/7; + return static_cast(week); + } + + return static_cast(week); //not reachable -- well except if day == 5 and is_leap_year != true + + } + + //! Convert a ymd_type into a day number + /*! The day number is an absolute number of days since the start of count + */ + template + BOOST_DATE_TIME_INLINE + date_int_type_ + gregorian_calendar_base::day_number(const ymd_type& ymd) + { + unsigned short a = static_cast((14-ymd.month)/12); + unsigned short y = static_cast(ymd.year + 4800 - a); + unsigned short m = static_cast(ymd.month + 12*a - 3); + unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045; + return static_cast(d); + } + + //! Convert a year-month-day into the julian day number + /*! Since this implementation uses julian day internally, this is the same as the day_number. + */ + template + BOOST_DATE_TIME_INLINE + date_int_type_ + gregorian_calendar_base::julian_day_number(const ymd_type& ymd) + { + return day_number(ymd); + } + + //! Convert year-month-day into a modified julian day number + /*! The day number is an absolute number of days. + * MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC + */ + template + BOOST_DATE_TIME_INLINE + date_int_type_ + gregorian_calendar_base::modjulian_day_number(const ymd_type& ymd) + { + return julian_day_number(ymd)-2400001; //prerounded + } + + //! Change a day number into a year-month-day + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::from_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a + 3)/146097; + date_int_type c = a-((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - (1461*d)/4; + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast(m + 3 - 12 * (m/10)); + year_type year = static_cast(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(static_cast(year),month,day); + } + + //! Change a day number into a year-month-day + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::from_julian_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a+3)/146097; + date_int_type c = a - ((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - ((1461*d)/4); + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast(m + 3 - 12 * (m/10)); + year_type year = static_cast(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(year,month,day); + } + + //! Change a modified julian day number into a year-month-day + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::from_modjulian_day_number(date_int_type dayNumber) { + date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded + return from_julian_day_number(jd); + } + + //! Determine if the provided year is a leap year + /*! + *@return true if year is a leap year, false otherwise + */ + template + BOOST_DATE_TIME_INLINE + bool + gregorian_calendar_base::is_leap_year(year_type year) + { + //divisible by 4, not if divisible by 100, but true if divisible by 400 + return (!(year % 4)) && ((year % 100) || (!(year % 400))); + } + + //! Calculate the last day of the month + /*! Find the day which is the end of the month given year and month + * No error checking is performed. + */ + template + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base::end_of_month_day(year_type year, + month_type month) + { + switch (month) { + case 2: + if (is_leap_year(year)) { + return 29; + } else { + return 28; + }; + case 4: + case 6: + case 9: + case 11: + return 30; + default: + return 31; + }; + + } + + //! Provide the ymd_type specification for the calandar start + template + BOOST_DATE_TIME_INLINE + ymd_type_ + gregorian_calendar_base::epoch() + { + return ymd_type(1400,1,1); + } + + //! Defines length of a week for week calculations + template + BOOST_DATE_TIME_INLINE + unsigned short + gregorian_calendar_base::days_in_week() + { + return 7; + } + + +} } //namespace gregorian + + diff --git a/boost/date_time/int_adapter.hpp b/boost/date_time/int_adapter.hpp new file mode 100644 index 00000000..6ee7712f --- /dev/null +++ b/boost/date_time/int_adapter.hpp @@ -0,0 +1,496 @@ +#ifndef _DATE_TIME_INT_ADAPTER_HPP__ +#define _DATE_TIME_INT_ADAPTER_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include "boost/config.hpp" +#include "boost/limits.hpp" //work around compilers without limits +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/locale_config.hpp" +#ifndef BOOST_DATE_TIME_NO_LOCALE +# include +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +// conditional expression is constant +#pragma warning(disable: 4127) +#endif + +namespace boost { +namespace date_time { + + +//! Adapter to create integer types with +-infinity, and not a value +/*! This class is used internally in counted date/time representations. + * It adds the floating point like features of infinities and + * not a number. It also provides mathmatical operations with + * consideration to special values following these rules: + *@code + * +infinity - infinity == Not A Number (NAN) + * infinity * non-zero == infinity + * infinity * zero == NAN + * +infinity * -integer == -infinity + * infinity / infinity == NAN + * infinity * infinity == infinity + *@endcode + */ +template +class int_adapter { +public: + typedef int_type_ int_type; + int_adapter(int_type v) : + value_(v) + {} + static bool has_infinity() + { + return true; + } + static const int_adapter pos_infinity() + { + return (::std::numeric_limits::max)(); + } + static const int_adapter neg_infinity() + { + return (::std::numeric_limits::min)(); + } + static const int_adapter not_a_number() + { + return (::std::numeric_limits::max)()-1; + } + static int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (::std::numeric_limits::max)()-2; + } + static int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (::std::numeric_limits::min)()+1; + } + static int_adapter from_special(special_values sv) + { + switch (sv) { + case not_a_date_time: return not_a_number(); + case neg_infin: return neg_infinity(); + case pos_infin: return pos_infinity(); + case max_date_time: return (max)(); + case min_date_time: return (min)(); + default: return not_a_number(); + } + } + static bool is_inf(int_type v) + { + return (v == neg_infinity().as_number() || + v == pos_infinity().as_number()); + } + static bool is_neg_inf(int_type v) + { + return (v == neg_infinity().as_number()); + } + static bool is_pos_inf(int_type v) + { + return (v == pos_infinity().as_number()); + } + static bool is_not_a_number(int_type v) + { + return (v == not_a_number().as_number()); + } + //! Returns either special value type or is_not_special + static special_values to_special(int_type v) + { + if (is_not_a_number(v)) return not_a_date_time; + if (is_neg_inf(v)) return neg_infin; + if (is_pos_inf(v)) return pos_infin; + return not_special; + } + + //-3 leaves room for representations of infinity and not a date + static int_type maxcount() + { + return (::std::numeric_limits::max)()-3; + } + bool is_infinity() const + { + return (value_ == neg_infinity().as_number() || + value_ == pos_infinity().as_number()); + } + bool is_pos_infinity()const + { + return(value_ == pos_infinity().as_number()); + } + bool is_neg_infinity()const + { + return(value_ == neg_infinity().as_number()); + } + bool is_nan() const + { + return (value_ == not_a_number().as_number()); + } + bool is_special() const + { + return(is_infinity() || is_nan()); + } + bool operator==(const int_adapter& rhs) const + { + return (compare(rhs) == 0); + } + bool operator==(const int& rhs) const + { + if(!std::numeric_limits::is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return false; + } + } + return (compare(rhs) == 0); + } + bool operator!=(const int_adapter& rhs) const + { + return (compare(rhs) != 0); + } + bool operator!=(const int& rhs) const + { + if(!std::numeric_limits::is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return true; + } + } + return (compare(rhs) != 0); + } + bool operator<(const int_adapter& rhs) const + { + return (compare(rhs) == -1); + } + bool operator<(const int& rhs) const + { + // quiets compiler warnings + if(!std::numeric_limits::is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return true; + } + } + return (compare(rhs) == -1); + } + bool operator>(const int_adapter& rhs) const + { + return (compare(rhs) == 1); + } + int_type as_number() const + { + return value_; + } + //! Returns either special value type or is_not_special + special_values as_special() const + { + return int_adapter::to_special(value_); + } + //creates nasty ambiguities +// operator int_type() const +// { +// return value_; +// } + + /*! Operator allows for adding dissimilar int_adapter types. + * The return type will match that of the the calling object's type */ + template + inline + int_adapter operator+(const int_adapter& rhs) const + { + if(is_special() || rhs.is_special()) + { + if (is_nan() || rhs.is_nan()) + { + return int_adapter::not_a_number(); + } + if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) || + (is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ) + { + return int_adapter::not_a_number(); + } + if (is_infinity()) + { + return *this; + } + if (rhs.is_pos_inf(rhs.as_number())) + { + return int_adapter::pos_infinity(); + } + if (rhs.is_neg_inf(rhs.as_number())) + { + return int_adapter::neg_infinity(); + } + } + return int_adapter(value_ + static_cast(rhs.as_number())); + } + + int_adapter operator+(const int_type rhs) const + { + if(is_special()) + { + if (is_nan()) + { + return int_adapter(not_a_number()); + } + if (is_infinity()) + { + return *this; + } + } + return int_adapter(value_ + rhs); + } + + /*! Operator allows for subtracting dissimilar int_adapter types. + * The return type will match that of the the calling object's type */ + template + inline + int_adapter operator-(const int_adapter& rhs)const + { + if(is_special() || rhs.is_special()) + { + if (is_nan() || rhs.is_nan()) + { + return int_adapter::not_a_number(); + } + if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) || + (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ) + { + return int_adapter::not_a_number(); + } + if (is_infinity()) + { + return *this; + } + if (rhs.is_pos_inf(rhs.as_number())) + { + return int_adapter::neg_infinity(); + } + if (rhs.is_neg_inf(rhs.as_number())) + { + return int_adapter::pos_infinity(); + } + } + return int_adapter(value_ - static_cast(rhs.as_number())); + } + int_adapter operator-(const int_type rhs) const + { + if(is_special()) + { + if (is_nan()) + { + return int_adapter(not_a_number()); + } + if (is_infinity()) + { + return *this; + } + } + return int_adapter(value_ - rhs); + } + + // should templatize this to be consistant with op +- + int_adapter operator*(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ * rhs.value_); + } + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + int_adapter operator*(const int rhs) const + { + if(is_special()) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ * rhs); + } + + // should templatize this to be consistant with op +- + int_adapter operator/(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(is_infinity() && rhs.is_infinity()) + { + return int_adapter(not_a_number()); + } + if(rhs != 0) + { + return mult_div_specials(rhs); + } + else { // let divide by zero blow itself up + return int_adapter(value_ / rhs.value_); + } + } + return int_adapter(value_ / rhs.value_); + } + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + int_adapter operator/(const int rhs) const + { + if(is_special() && rhs != 0) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ / rhs); + } + + // should templatize this to be consistant with op +- + int_adapter operator%(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(is_infinity() && rhs.is_infinity()) + { + return int_adapter(not_a_number()); + } + if(rhs != 0) + { + return mult_div_specials(rhs); + } + else { // let divide by zero blow itself up + return int_adapter(value_ % rhs.value_); + } + } + return int_adapter(value_ % rhs.value_); + } + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + int_adapter operator%(const int rhs) const + { + if(is_special() && rhs != 0) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ % rhs); + } +private: + int_type value_; + + //! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs + int compare(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(this->is_nan() || rhs.is_nan()) { + if(this->is_nan() && rhs.is_nan()) { + return 0; // equal + } + else { + return 2; // nan + } + } + if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) || + (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) ) + { + return -1; // less than + } + if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) || + (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) { + return 1; // greater than + } + } + if(value_ < rhs.value_) return -1; + if(value_ > rhs.value_) return 1; + // implied-> if(value_ == rhs.value_) + return 0; + } + /* When multiplying and dividing with at least 1 special value + * very simmilar rules apply. In those cases where the rules + * are different, they are handled in the respective operator + * function. */ + //! Assumes at least 'this' or 'rhs' is a special value + int_adapter mult_div_specials(const int_adapter& rhs)const + { + if(this->is_nan() || rhs.is_nan()) { + return int_adapter(not_a_number()); + } + BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits::is_signed ? 0 : 1; + if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) { + return int_adapter(pos_infinity()); + } + if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) { + return int_adapter(neg_infinity()); + } + //implied -> if(this->value_ == 0 || rhs.value_ == 0) + return int_adapter(not_a_number()); + } + /* Overloaded function necessary because of special + * situation where int_adapter is instantiated with + * 'unsigned' and func is called with negative int. + * It would produce incorrect results since 'unsigned' + * wraps around when initialized with a negative value */ + //! Assumes 'this' is a special value + int_adapter mult_div_specials(const int& rhs) const + { + if(this->is_nan()) { + return int_adapter(not_a_number()); + } + BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits::is_signed ? 0 : 1; + if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) { + return int_adapter(pos_infinity()); + } + if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) { + return int_adapter(neg_infinity()); + } + //implied -> if(this->value_ == 0 || rhs.value_ == 0) + return int_adapter(not_a_number()); + } + +}; + +#ifndef BOOST_DATE_TIME_NO_LOCALE + /*! Expected output is either a numeric representation + * or a special values representation.
+ * Ex. "12", "+infinity", "not-a-number", etc. */ + //template, typename int_type> + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const int_adapter& ia) + { + if(ia.is_special()) { + // switch copied from date_names_put.hpp + switch(ia.as_special()) + { + case not_a_date_time: + os << "not-a-number"; + break; + case pos_infin: + os << "+infinity"; + break; + case neg_infin: + os << "-infinity"; + break; + default: + os << ""; + } + } + else { + os << ia.as_number(); + } + return os; + } +#endif + + +} } //namespace date_time + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif diff --git a/boost/date_time/iso_format.hpp b/boost/date_time/iso_format.hpp new file mode 100644 index 00000000..2e7942d8 --- /dev/null +++ b/boost/date_time/iso_format.hpp @@ -0,0 +1,303 @@ +#ifndef ISO_FORMAT_HPP___ +#define ISO_FORMAT_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/parse_format_base.hpp" + +namespace boost { +namespace date_time { + +//! Class to provide common iso formatting spec +template +class iso_format_base { +public: + //! Describe month format -- its an integer in iso format + static month_format_spec month_format() + { + return month_as_integer; + } + + //! String used printed is date is invalid + static const charT* not_a_date() + { + return "not-a-date-time"; + } + //! String used to for positive infinity value + static const charT* pos_infinity() + { + return "+infinity"; + } + //! String used to for positive infinity value + static const charT* neg_infinity() + { + return "-infinity"; + } + + //! ISO char for a year -- used in durations + static charT year_sep_char() + { + return 'Y'; + } + //! ISO char for a month + static charT month_sep_char() + { + return '-'; + } + //! ISO char for a day + static charT day_sep_char() + { + return '-'; + } + //! char for minute + static charT hour_sep_char() + { + return ':'; + } + //! char for minute + static charT minute_sep_char() + { + return ':'; + } + //! char for second + static charT second_sep_char() + { + return ':'; + } + //! ISO char for a period + static charT period_start_char() + { + return 'P'; + } + //! Used in time in mixed strings to set start of time + static charT time_start_char() + { + return 'T'; + } + + //! Used in mixed strings to identify start of a week number + static charT week_start_char() + { + return 'W'; + } + + //! Separators for periods + static charT period_sep_char() + { + return '/'; + } + //! Separator for hh:mm:ss + static charT time_sep_char() + { + return ':'; + } + //! Preferred Separator for hh:mm:ss,decimal_fraction + static charT fractional_time_sep_char() + { + return ','; + } + + static bool is_component_sep(charT sep) + { + switch(sep) { + case 'H': + case 'M': + case 'S': + case 'W': + case 'T': + case 'Y': + case 'D':return true; + default: + return false; + } + } + + static bool is_fractional_time_sep(charT sep) + { + switch(sep) { + case ',': + case '.': return true; + default: return false; + } + } + static bool is_timezone_sep(charT sep) + { + switch(sep) { + case '+': + case '-': return true; + default: return false; + } + } + static charT element_sep_char() + { + return '-'; + } + +}; + +#ifndef BOOST_NO_STD_WSTRING + +//! Class to provide common iso formatting spec +template<> +class iso_format_base { +public: + //! Describe month format -- its an integer in iso format + static month_format_spec month_format() + { + return month_as_integer; + } + + //! String used printed is date is invalid + static const wchar_t* not_a_date() + { + return L"not-a-date-time"; + } + //! String used to for positive infinity value + static const wchar_t* pos_infinity() + { + return L"+infinity"; + } + //! String used to for positive infinity value + static const wchar_t* neg_infinity() + { + return L"-infinity"; + } + + //! ISO char for a year -- used in durations + static wchar_t year_sep_char() + { + return 'Y'; + } + //! ISO char for a month + static wchar_t month_sep_char() + { + return '-'; + } + //! ISO char for a day + static wchar_t day_sep_char() + { + return '-'; + } + //! char for minute + static wchar_t hour_sep_char() + { + return ':'; + } + //! char for minute + static wchar_t minute_sep_char() + { + return ':'; + } + //! char for second + static wchar_t second_sep_char() + { + return ':'; + } + //! ISO char for a period + static wchar_t period_start_char() + { + return 'P'; + } + //! Used in time in mixed strings to set start of time + static wchar_t time_start_char() + { + return 'T'; + } + + //! Used in mixed strings to identify start of a week number + static wchar_t week_start_char() + { + return 'W'; + } + + //! Separators for periods + static wchar_t period_sep_char() + { + return '/'; + } + //! Separator for hh:mm:ss + static wchar_t time_sep_char() + { + return ':'; + } + //! Preferred Separator for hh:mm:ss,decimal_fraction + static wchar_t fractional_time_sep_char() + { + return ','; + } + + static bool is_component_sep(wchar_t sep) + { + switch(sep) { + case 'H': + case 'M': + case 'S': + case 'W': + case 'T': + case 'Y': + case 'D':return true; + default: + return false; + } + } + + static bool is_fractional_time_sep(wchar_t sep) + { + switch(sep) { + case ',': + case '.': return true; + default: return false; + } + } + static bool is_timezone_sep(wchar_t sep) + { + switch(sep) { + case '+': + case '-': return true; + default: return false; + } + } + static wchar_t element_sep_char() + { + return '-'; + } + +}; + +#endif // BOOST_NO_STD_WSTRING + +//! Format description for iso normal YYYYMMDD +template +class iso_format : public iso_format_base { +public: + //! The ios standard format doesn't use char separators + static bool has_date_sep_chars() + { + return false; + } +}; + +//! Extended format uses seperators YYYY-MM-DD +template +class iso_extended_format : public iso_format_base { +public: + //! Extended format needs char separators + static bool has_date_sep_chars() + { + return true; + } + +}; + +} } //namespace date_time + + + + +#endif diff --git a/boost/date_time/locale_config.hpp b/boost/date_time/locale_config.hpp new file mode 100644 index 00000000..26a928f7 --- /dev/null +++ b/boost/date_time/locale_config.hpp @@ -0,0 +1,33 @@ +#ifndef DATE_TIME_LOCALE_CONFIG_HPP___ +#define DATE_TIME_LOCALE_CONFIG_HPP___ + +/* Copyright (c) 2002-2006 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +// This file configures whether the library will support locales and hence +// iostream based i/o. Even if a compiler has some support for locales, +// any failure to be compatible gets the compiler on the exclusion list. +// +// At the moment this is defined for MSVC 6 and any compiler that +// defines BOOST_NO_STD_LOCALE (gcc 2.95.x) + +#include "boost/config.hpp" //sets BOOST_NO_STD_LOCALE +#include "boost/detail/workaround.hpp" + +//This file basically becomes a noop if locales are not properly supported +#if (defined(BOOST_NO_STD_LOCALE) \ + || (BOOST_WORKAROUND( BOOST_MSVC, < 1300)) \ + || (BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x581 )) ) \ + || (BOOST_WORKAROUND( BOOST_XLCPP_ZOS, BOOST_TESTED_AT( 0x42010000 )) ) /* "shadows" the locale enabled overloads from */ \ + ) +#define BOOST_DATE_TIME_NO_LOCALE +#endif + + +#endif + diff --git a/boost/date_time/microsec_time_clock.hpp b/boost/date_time/microsec_time_clock.hpp new file mode 100644 index 00000000..42a918b5 --- /dev/null +++ b/boost/date_time/microsec_time_clock.hpp @@ -0,0 +1,158 @@ +#ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___ +#define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +/*! @file microsec_time_clock.hpp + This file contains a high resolution time clock implementation. +*/ + +#include +#include +#include +#include +#include +#include +#if defined(BOOST_HAS_FTIME) +#include +#endif + +#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + +namespace boost { +namespace date_time { + + //! A clock providing microsecond level resolution + /*! A high precision clock that measures the local time + * at a resolution up to microseconds and adjusts to the + * resolution of the time system. For example, for the + * a library configuration with nano second resolution, + * the last 3 places of the fractional seconds will always + * be 000 since there are 1000 nano-seconds in a micro second. + */ + template + class microsec_clock + { + private: + //! Type for the function used to convert time_t to tm + typedef std::tm* (*time_converter)(const std::time_t*, std::tm*); + + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_duration_type::rep_type resolution_traits_type; + + //! return a local time object for the given zone, based on computer clock + //JKG -- looks like we could rewrite this against universal_time + template + static time_type local_time(shared_ptr tz_ptr) + { + typedef typename time_type::utc_time_type utc_time_type; + typedef second_clock second_clock; + // we'll need to know the utc_offset this machine has + // in order to get a utc_time_type set to utc + utc_time_type utc_time = second_clock::universal_time(); + time_duration_type utc_offset = second_clock::local_time() - utc_time; + // use micro clock to get a local time with sub seconds + // and adjust it to get a true utc time reading with sub seconds + utc_time = microsec_clock::local_time() - utc_offset; + return time_type(utc_time, tz_ptr); + } + + //! Returns the local time based on computer clock settings + static time_type local_time() + { + return create_time(&c_time::localtime); + } + + //! Returns the UTC time based on computer settings + static time_type universal_time() + { + return create_time(&c_time::gmtime); + } + + private: + static time_type create_time(time_converter converter) + { +#ifdef BOOST_HAS_GETTIMEOFDAY + timeval tv; + gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux. + std::time_t t = tv.tv_sec; + boost::uint32_t sub_sec = tv.tv_usec; +#elif defined(BOOST_HAS_FTIME) + boost::winapi::FILETIME_ ft; + boost::winapi::GetSystemTimeAsFileTime(&ft); +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + // Some runtime library implementations expect local times as the norm for ctime functions. + { + boost::winapi::FILETIME_ local_ft; + boost::winapi::FileTimeToLocalFileTime(&ft, &local_ft); + ft = local_ft; + } +#endif + + boost::uint64_t micros = file_time_to_microseconds(ft); // it will not wrap, since ft is the current time + // and cannot be before 1970-Jan-01 + std::time_t t = static_cast(micros / 1000000UL); // seconds since epoch + // microseconds -- static casts suppress warnings + boost::uint32_t sub_sec = static_cast(micros % 1000000UL); +#else +#error Internal Boost.DateTime error: BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is defined, however neither gettimeofday nor FILETIME support is detected. +#endif + + std::tm curr; + std::tm* curr_ptr = converter(&t, &curr); + date_type d(static_cast< typename date_type::year_type::value_type >(curr_ptr->tm_year + 1900), + static_cast< typename date_type::month_type::value_type >(curr_ptr->tm_mon + 1), + static_cast< typename date_type::day_type::value_type >(curr_ptr->tm_mday)); + + //The following line will adjust the fractional second tick in terms + //of the current time system. For example, if the time system + //doesn't support fractional seconds then res_adjust returns 0 + //and all the fractional seconds return 0. + int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000); + + time_duration_type td(static_cast< typename time_duration_type::hour_type >(curr_ptr->tm_hour), + static_cast< typename time_duration_type::min_type >(curr_ptr->tm_min), + static_cast< typename time_duration_type::sec_type >(curr_ptr->tm_sec), + sub_sec * adjust); + + return time_type(d,td); + } + +#if defined(BOOST_HAS_FTIME) + /*! + * The function converts file_time into number of microseconds elapsed since 1970-Jan-01 + * + * \note Only dates after 1970-Jan-01 are supported. Dates before will be wrapped. + */ + static boost::uint64_t file_time_to_microseconds(boost::winapi::FILETIME_ const& ft) + { + // shift is difference between 1970-Jan-01 & 1601-Jan-01 + // in 100-nanosecond units + const boost::uint64_t shift = 116444736000000000ULL; // (27111902 << 32) + 3577643008 + + // 100-nanos since 1601-Jan-01 + boost::uint64_t ft_as_integer = (static_cast< boost::uint64_t >(ft.dwHighDateTime) << 32) | static_cast< boost::uint64_t >(ft.dwLowDateTime); + + ft_as_integer -= shift; // filetime is now 100-nanos since 1970-Jan-01 + return (ft_as_integer / 10U); // truncate to microseconds + } +#endif + }; + + +} } //namespace date_time + +#endif //BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + + +#endif + diff --git a/boost/date_time/parse_format_base.hpp b/boost/date_time/parse_format_base.hpp new file mode 100644 index 00000000..d4b2f597 --- /dev/null +++ b/boost/date_time/parse_format_base.hpp @@ -0,0 +1,29 @@ +#ifndef DATE_TIME_PARSE_FORMAT_BASE__ +#define DATE_TIME_PARSE_FORMAT_BASE__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +namespace boost { +namespace date_time { + + //! Enum for distinguishing parsing and formatting options + enum month_format_spec {month_as_integer, month_as_short_string, + month_as_long_string}; + + //! Enum for distinguishing the order of Month, Day, & Year. + /*! Enum for distinguishing the order in which Month, Day, & Year + * will appear in a date string */ + enum ymd_order_spec {ymd_order_iso, //order is year-month-day + ymd_order_dmy, //day-month-year + ymd_order_us}; //order is month-day-year + + +} }//namespace date_time + +#endif diff --git a/boost/date_time/period.hpp b/boost/date_time/period.hpp new file mode 100644 index 00000000..13011af2 --- /dev/null +++ b/boost/date_time/period.hpp @@ -0,0 +1,378 @@ +#ifndef DATE_TIME_PERIOD_HPP___ +#define DATE_TIME_PERIOD_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! \file period.hpp + This file contain the implementation of the period abstraction. This is + basically the same idea as a range. Although this class is intended for + use in the time library, it is pretty close to general enough for other + numeric uses. + +*/ + +#include +#include + + +namespace boost { +namespace date_time { + //!Provides generalized period type useful in date-time systems + /*!This template uses a class to represent a time point within the period + and another class to represent a duration. As a result, this class is + not appropriate for use when the number and duration representation + are the same (eg: in the regular number domain). + + A period can be specified by providing either the begining point and + a duration or the begining point and the end point( end is NOT part + of the period but 1 unit past it. A period will be "invalid" if either + end_point <= begin_point or the given duration is <= 0. Any valid period + will return false for is_null(). + + Zero length periods are also considered invalid. Zero length periods are + periods where the begining and end points are the same, or, the given + duration is zero. For a zero length period, the last point will be one + unit less than the begining point. + + In the case that the begin and last are the same, the period has a + length of one unit. + + The best way to handle periods is usually to provide a begining point and + a duration. So, day1 + 7 days is a week period which includes all of the + first day and 6 more days (eg: Sun to Sat). + + */ + template + class BOOST_SYMBOL_VISIBLE period : private + boost::less_than_comparable + , boost::equality_comparable< period + > > + { + public: + typedef point_rep point_type; + typedef duration_rep duration_type; + + period(point_rep first_point, point_rep end_point); + period(point_rep first_point, duration_rep len); + point_rep begin() const; + point_rep end() const; + point_rep last() const; + duration_rep length() const; + bool is_null() const; + bool operator==(const period& rhs) const; + bool operator<(const period& rhs) const; + void shift(const duration_rep& d); + void expand(const duration_rep& d); + bool contains(const point_rep& point) const; + bool contains(const period& other) const; + bool intersects(const period& other) const; + bool is_adjacent(const period& other) const; + bool is_before(const point_rep& point) const; + bool is_after(const point_rep& point) const; + period intersection(const period& other) const; + period merge(const period& other) const; + period span(const period& other) const; + private: + point_rep begin_; + point_rep last_; + }; + + //! create a period from begin to last eg: [begin,end) + /*! If end <= begin then the period will be invalid + */ + template + inline + period::period(point_rep first_point, + point_rep end_point) : + begin_(first_point), + last_(end_point - duration_rep::unit()) + {} + + //! create a period as [begin, begin+len) + /*! If len is <= 0 then the period will be invalid + */ + template + inline + period::period(point_rep first_point, duration_rep len) : + begin_(first_point), + last_(first_point + len-duration_rep::unit()) + { } + + + //! Return the first element in the period + template + inline + point_rep period::begin() const + { + return begin_; + } + + //! Return one past the last element + template + inline + point_rep period::end() const + { + return last_ + duration_rep::unit(); + } + + //! Return the last item in the period + template + inline + point_rep period::last() const + { + return last_; + } + + //! True if period is ill formed (length is zero or less) + template + inline + bool period::is_null() const + { + return end() <= begin_; + } + + //! Return the length of the period + template + inline + duration_rep period::length() const + { + if(last_ < begin_){ // invalid period + return last_+duration_rep::unit() - begin_; + } + else{ + return end() - begin_; // normal case + } + } + + //! Equality operator + template + inline + bool period::operator==(const period& rhs) const + { + return ((begin_ == rhs.begin_) && + (last_ == rhs.last_)); + } + + //! Strict as defined by rhs.last <= lhs.last + template + inline + bool period::operator<(const period& rhs) const + { + return (last_ < rhs.begin_); + } + + + //! Shift the start and end by the specified amount + template + inline + void period::shift(const duration_rep& d) + { + begin_ = begin_ + d; + last_ = last_ + d; + } + + /** Expands the size of the period by the duration on both ends. + * + *So before expand + *@code + * + * [-------] + * ^ ^ ^ ^ ^ ^ ^ + * 1 2 3 4 5 6 7 + * + *@endcode + * After expand(2) + *@code + * + * [----------------------] + * ^ ^ ^ ^ ^ ^ ^ + * 1 2 3 4 5 6 7 + * + *@endcode + */ + template + inline + void period::expand(const duration_rep& d) + { + begin_ = begin_ - d; + last_ = last_ + d; + } + + //! True if the point is inside the period, zero length periods contain no points + template + inline + bool period::contains(const point_rep& point) const + { + return ((point >= begin_) && + (point <= last_)); + } + + + //! True if this period fully contains (or equals) the other period + template + inline + bool period::contains(const period& other) const + { + return ((begin_ <= other.begin_) && (last_ >= other.last_)); + } + + + //! True if periods are next to each other without a gap. + /* In the example below, p1 and p2 are adjacent, but p3 is not adjacent + * with either of p1 or p2. + *@code + * [-p1-) + * [-p2-) + * [-p3-) + *@endcode + */ + template + inline + bool + period::is_adjacent(const period& other) const + { + return (other.begin() == end() || + begin_ == other.end()); + } + + + //! True if all of the period is prior or t < start + /* In the example below only point 1 would evaluate to true. + *@code + * [---------]) + * ^ ^ ^ ^ ^ + * 1 2 3 4 5 + * + *@endcode + */ + template + inline + bool + period::is_after(const point_rep& t) const + { + if (is_null()) + { + return false; //null period isn't after + } + + return t < begin_; + } + + //! True if all of the period is prior to the passed point or end <= t + /* In the example below points 4 and 5 return true. + *@code + * [---------]) + * ^ ^ ^ ^ ^ + * 1 2 3 4 5 + * + *@endcode + */ + template + inline + bool + period::is_before(const point_rep& t) const + { + if (is_null()) + { + return false; //null period isn't before anything + } + + return last_ < t; + } + + + //! True if the periods overlap in any way + /* In the example below p1 intersects with p2, p4, and p6. + *@code + * [---p1---) + * [---p2---) + * [---p3---) + * [---p4---) + * [-p5-) + * [-p6-) + *@endcode + */ + template + inline + bool period::intersects(const period& other) const + { + return ( contains(other.begin_) || + other.contains(begin_) || + ((other.begin_ < begin_) && (other.last_ >= begin_))); + } + + //! Returns the period of intersection or invalid range no intersection + template + inline + period + period::intersection(const period& other) const + { + if (begin_ > other.begin_) { + if (last_ <= other.last_) { //case2 + return *this; + } + //case 1 + return period(begin_, other.end()); + } + else { + if (last_ <= other.last_) { //case3 + return period(other.begin_, this->end()); + } + //case4 + return other; + } + //unreachable + } + + //! Returns the union of intersecting periods -- or null period + /*! + */ + template + inline + period + period::merge(const period& other) const + { + if (this->intersects(other)) { + if (begin_ < other.begin_) { + return period(begin_, last_ > other.last_ ? this->end() : other.end()); + } + + return period(other.begin_, last_ > other.last_ ? this->end() : other.end()); + + } + return period(begin_,begin_); // no intersect return null + } + + //! Combine two periods with earliest start and latest end. + /*! Combines two periods and any gap between them such that + * start = min(p1.start, p2.start) + * end = max(p1.end , p2.end) + *@code + * [---p1---) + * [---p2---) + * result: + * [-----------p3----------) + *@endcode + */ + template + inline + period + period::span(const period& other) const + { + point_rep start((begin_ < other.begin_) ? begin() : other.begin()); + point_rep newend((last_ < other.last_) ? other.end() : this->end()); + return period(start, newend); + } + + +} } //namespace date_time + + + +#endif diff --git a/boost/date_time/posix_time/conversion.hpp b/boost/date_time/posix_time/conversion.hpp new file mode 100644 index 00000000..cdff4b76 --- /dev/null +++ b/boost/date_time/posix_time/conversion.hpp @@ -0,0 +1,100 @@ +#ifndef POSIX_TIME_CONVERSION_HPP___ +#define POSIX_TIME_CONVERSION_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include // absolute_value +#include + +namespace boost { + +namespace posix_time { + + //! Function that converts a time_t into a ptime. + inline + ptime from_time_t(std::time_t t) + { + return ptime(gregorian::date(1970,1,1)) + seconds(static_cast(t)); + } + + //! Function that converts a ptime into a time_t + inline + std::time_t to_time_t(ptime pt) + { + return (pt - ptime(gregorian::date(1970,1,1))).total_seconds(); + } + + //! Convert a time to a tm structure truncating any fractional seconds + inline + std::tm to_tm(const boost::posix_time::ptime& t) { + std::tm timetm = boost::gregorian::to_tm(t.date()); + boost::posix_time::time_duration td = t.time_of_day(); + timetm.tm_hour = static_cast(td.hours()); + timetm.tm_min = static_cast(td.minutes()); + timetm.tm_sec = static_cast(td.seconds()); + timetm.tm_isdst = -1; // -1 used when dst info is unknown + return timetm; + } + //! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components + inline + std::tm to_tm(const boost::posix_time::time_duration& td) { + std::tm timetm; + std::memset(&timetm, 0, sizeof(timetm)); + timetm.tm_hour = static_cast(date_time::absolute_value(td.hours())); + timetm.tm_min = static_cast(date_time::absolute_value(td.minutes())); + timetm.tm_sec = static_cast(date_time::absolute_value(td.seconds())); + timetm.tm_isdst = -1; // -1 used when dst info is unknown + return timetm; + } + + //! Convert a tm struct to a ptime ignoring is_dst flag + inline + ptime ptime_from_tm(const std::tm& timetm) { + boost::gregorian::date d = boost::gregorian::date_from_tm(timetm); + return ptime(d, time_duration(timetm.tm_hour, timetm.tm_min, timetm.tm_sec)); + } + + +#if defined(BOOST_HAS_FTIME) + + //! Function to create a time object from an initialized FILETIME struct. + /*! Function to create a time object from an initialized FILETIME struct. + * A FILETIME struct holds 100-nanosecond units (0.0000001). When + * built with microsecond resolution the FILETIME's sub second value + * will be truncated. Nanosecond resolution has no truncation. + * + * \note FILETIME is part of the Win32 API, so it is not portable to non-windows + * platforms. + * + * \note The function is templated on the FILETIME type, so that + * it can be used with both native FILETIME and the ad-hoc + * boost::detail::winapi::FILETIME_ type. + */ + template< typename TimeT, typename FileTimeT > + inline + TimeT from_ftime(const FileTimeT& ft) + { + return boost::date_time::time_from_ftime(ft); + } + +#endif // BOOST_HAS_FTIME + +} } //namespace boost::posix_time + + + + +#endif + diff --git a/boost/date_time/posix_time/date_duration_operators.hpp b/boost/date_time/posix_time/date_duration_operators.hpp new file mode 100644 index 00000000..f3c61d7a --- /dev/null +++ b/boost/date_time/posix_time/date_duration_operators.hpp @@ -0,0 +1,114 @@ +#ifndef DATE_DURATION_OPERATORS_HPP___ +#define DATE_DURATION_OPERATORS_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or + * http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/gregorian/greg_duration_types.hpp" +#include "boost/date_time/posix_time/ptime.hpp" + +namespace boost { +namespace posix_time { + + /*!@file date_duration_operators.hpp Operators for ptime and + * optional gregorian types. Operators use snap-to-end-of-month behavior. + * Further details on this behavior can be found in reference for + * date_time/date_duration_types.hpp and documentation for + * month and year iterators. + */ + + + /*! Adds a months object and a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator+(const ptime& t, const boost::gregorian::months& m) + { + return t + m.get_offset(t.date()); + } + + /*! Adds a months object to a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator+=(ptime& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t += m.get_offset(t.date()); + } + + /*! Subtracts a months object and a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator-(const ptime& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t + m.get_neg_offset(t.date()); + } + + /*! Subtracts a months object from a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline + ptime + operator-=(ptime& t, const boost::gregorian::months& m) + { + return t += m.get_neg_offset(t.date()); + } + + // ptime & years + + /*! Adds a years object and a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator+(const ptime& t, const boost::gregorian::years& y) + { + return t + y.get_offset(t.date()); + } + + /*! Adds a years object to a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator+=(ptime& t, const boost::gregorian::years& y) + { + return t += y.get_offset(t.date()); + } + + /*! Subtracts a years object and a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator-(const ptime& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t + y.get_neg_offset(t.date()); + } + + /*! Subtracts a years object from a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline + ptime + operator-=(ptime& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t += y.get_neg_offset(t.date()); + } + +}} // namespaces + +#endif // DATE_DURATION_OPERATORS_HPP___ diff --git a/boost/date_time/posix_time/posix_time_config.hpp b/boost/date_time/posix_time/posix_time_config.hpp new file mode 100644 index 00000000..996afcae --- /dev/null +++ b/boost/date_time/posix_time/posix_time_config.hpp @@ -0,0 +1,178 @@ +#ifndef POSIX_TIME_CONFIG_HPP___ +#define POSIX_TIME_CONFIG_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include //for MCW 7.2 std::abs(long long) +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace posix_time { + +//Remove the following line if you want 64 bit millisecond resolution time +//#define BOOST_GDTL_POSIX_TIME_STD_CONFIG + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + // set up conditional test compilations +#define BOOST_DATE_TIME_HAS_MILLISECONDS +#define BOOST_DATE_TIME_HAS_MICROSECONDS +#define BOOST_DATE_TIME_HAS_NANOSECONDS + typedef date_time::time_resolution_traits time_res_traits; +#else + // set up conditional test compilations +#define BOOST_DATE_TIME_HAS_MILLISECONDS +#define BOOST_DATE_TIME_HAS_MICROSECONDS +#undef BOOST_DATE_TIME_HAS_NANOSECONDS + typedef date_time::time_resolution_traits< + boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::micro, + 1000000, 6 > time_res_traits; + + +// #undef BOOST_DATE_TIME_HAS_MILLISECONDS +// #undef BOOST_DATE_TIME_HAS_MICROSECONDS +// #undef BOOST_DATE_TIME_HAS_NANOSECONDS +// typedef date_time::time_resolution_traits time_res_traits; + +#endif + + + //! Base time duration type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE time_duration : + public date_time::time_duration + { + public: + typedef time_res_traits rep_type; + typedef time_res_traits::day_type day_type; + typedef time_res_traits::hour_type hour_type; + typedef time_res_traits::min_type min_type; + typedef time_res_traits::sec_type sec_type; + typedef time_res_traits::fractional_seconds_type fractional_seconds_type; + typedef time_res_traits::tick_type tick_type; + typedef time_res_traits::impl_type impl_type; + time_duration(hour_type hour, + min_type min, + sec_type sec, + fractional_seconds_type fs=0) : + date_time::time_duration(hour,min,sec,fs) + {} + time_duration() : + date_time::time_duration(0,0,0) + {} + //! Construct from special_values + time_duration(boost::date_time::special_values sv) : + date_time::time_duration(sv) + {} + //Give duration access to ticks constructor -- hide from users + friend class date_time::time_duration; + protected: + explicit time_duration(impl_type tick_count) : + date_time::time_duration(tick_count) + {} + }; + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + + //! Simple implementation for the time rep + struct simple_time_rep + { + typedef gregorian::date date_type; + typedef time_duration time_duration_type; + simple_time_rep(date_type d, time_duration_type tod) : + day(d), + time_of_day(tod) + { + // make sure we have sane values for date & time + if(!day.is_special() && !time_of_day.is_special()){ + if(time_of_day >= time_duration_type(24,0,0)) { + while(time_of_day >= time_duration_type(24,0,0)) { + day += date_type::duration_type(1); + time_of_day -= time_duration_type(24,0,0); + } + } + else if(time_of_day.is_negative()) { + while(time_of_day.is_negative()) { + day -= date_type::duration_type(1); + time_of_day += time_duration_type(24,0,0); + } + } + } + } + date_type day; + time_duration_type time_of_day; + bool is_special()const + { + return(is_pos_infinity() || is_neg_infinity() || is_not_a_date_time()); + } + bool is_pos_infinity()const + { + return(day.is_pos_infinity() || time_of_day.is_pos_infinity()); + } + bool is_neg_infinity()const + { + return(day.is_neg_infinity() || time_of_day.is_neg_infinity()); + } + bool is_not_a_date_time()const + { + return(day.is_not_a_date() || time_of_day.is_not_a_date_time()); + } + }; + + class BOOST_SYMBOL_VISIBLE posix_time_system_config + { + public: + typedef simple_time_rep time_rep_type; + typedef gregorian::date date_type; + typedef gregorian::date_duration date_duration_type; + typedef time_duration time_duration_type; + typedef time_res_traits::tick_type int_type; + typedef time_res_traits resolution_traits; +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers +#else + BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000000); +#endif + }; + +#else + + class millisec_posix_time_system_config + { + public: + typedef boost::int64_t time_rep_type; + //typedef time_res_traits::tick_type time_rep_type; + typedef gregorian::date date_type; + typedef gregorian::date_duration date_duration_type; + typedef time_duration time_duration_type; + typedef time_res_traits::tick_type int_type; + typedef time_res_traits::impl_type impl_type; + typedef time_res_traits resolution_traits; +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers +#else + BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000); +#endif + }; + +#endif + +} }//namespace posix_time + + +#endif + + diff --git a/boost/date_time/posix_time/posix_time_duration.hpp b/boost/date_time/posix_time/posix_time_duration.hpp new file mode 100644 index 00000000..c7ec57e8 --- /dev/null +++ b/boost/date_time/posix_time/posix_time_duration.hpp @@ -0,0 +1,91 @@ +#ifndef POSIX_TIME_DURATION_HPP___ +#define POSIX_TIME_DURATION_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include + +namespace boost { +namespace posix_time { + + //! Allows expression of durations as an hour count + //! The argument must be an integral type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE hours : public time_duration + { + public: + template + explicit hours(T const& h, + typename boost::enable_if, void>::type* = 0) : + time_duration(numeric_cast(h), 0, 0) + {} + }; + + //! Allows expression of durations as a minute count + //! The argument must be an integral type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE minutes : public time_duration + { + public: + template + explicit minutes(T const& m, + typename boost::enable_if, void>::type* = 0) : + time_duration(0, numeric_cast(m),0) + {} + }; + + //! Allows expression of durations as a seconds count + //! The argument must be an integral type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE seconds : public time_duration + { + public: + template + explicit seconds(T const& s, + typename boost::enable_if, void>::type* = 0) : + time_duration(0,0, numeric_cast(s)) + {} + }; + + + //! Allows expression of durations as milli seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration millisec; + typedef date_time::subsecond_duration milliseconds; + + //! Allows expression of durations as micro seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration microsec; + typedef date_time::subsecond_duration microseconds; + + //This is probably not needed anymore... +#if defined(BOOST_DATE_TIME_HAS_NANOSECONDS) + + //! Allows expression of durations as nano seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration nanosec; + typedef date_time::subsecond_duration nanoseconds; + +#endif + +} }//namespace posix_time + + +#endif + diff --git a/boost/date_time/posix_time/posix_time_system.hpp b/boost/date_time/posix_time/posix_time_system.hpp new file mode 100644 index 00000000..84c21ca0 --- /dev/null +++ b/boost/date_time/posix_time/posix_time_system.hpp @@ -0,0 +1,68 @@ +#ifndef POSIX_TIME_SYSTEM_HPP___ +#define POSIX_TIME_SYSTEM_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + + +#include "boost/date_time/posix_time/posix_time_config.hpp" +#include "boost/date_time/time_system_split.hpp" +#include "boost/date_time/time_system_counted.hpp" +#include "boost/date_time/compiler_config.hpp" + + +namespace boost { +namespace posix_time { + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers + typedef date_time::split_timedate_system posix_time_system; +#else + typedef date_time::split_timedate_system posix_time_system; +#endif + +#else + + typedef date_time::counted_time_rep int64_time_rep; + typedef date_time::counted_time_system posix_time_system; + +#endif + +} }//namespace posix_time + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/boost/date_time/posix_time/posix_time_types.hpp b/boost/date_time/posix_time/posix_time_types.hpp new file mode 100644 index 00000000..f2488f8b --- /dev/null +++ b/boost/date_time/posix_time/posix_time_types.hpp @@ -0,0 +1,55 @@ +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + */ +#ifndef POSIX_TIME_TYPES_HPP___ +#define POSIX_TIME_TYPES_HPP___ + +#include "boost/date_time/time_clock.hpp" +#include "boost/date_time/microsec_time_clock.hpp" +#include "boost/date_time/posix_time/ptime.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/posix_time/date_duration_operators.hpp" +#endif +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/posix_time/posix_time_system.hpp" +#include "boost/date_time/posix_time/time_period.hpp" +#include "boost/date_time/time_iterator.hpp" +#include "boost/date_time/dst_rules.hpp" + +namespace boost { + +//!Defines a non-adjusted time system with nano-second resolution and stable calculation properties +namespace posix_time { + + //! Iterator over a defined time duration + /*! \ingroup time_basics + */ + typedef date_time::time_itr time_iterator; + //! A time clock that has a resolution of one second + /*! \ingroup time_basics + */ + typedef date_time::second_clock second_clock; + +#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + //! A time clock that has a resolution of one microsecond + /*! \ingroup time_basics + */ + typedef date_time::microsec_clock microsec_clock; +#endif + + //! Define a dst null dst rule for the posix_time system + typedef date_time::null_dst_rules no_dst; + //! Define US dst rule calculator for the posix_time system + typedef date_time::us_dst_rules us_dst; + + +} } //namespace posix_time + + + + +#endif + diff --git a/boost/date_time/posix_time/ptime.hpp b/boost/date_time/posix_time/ptime.hpp new file mode 100644 index 00000000..c97edf9c --- /dev/null +++ b/boost/date_time/posix_time/ptime.hpp @@ -0,0 +1,66 @@ +#ifndef POSIX_PTIME_HPP___ +#define POSIX_PTIME_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include + +namespace boost { + +namespace posix_time { + + //bring special enum values into the namespace + using date_time::special_values; + using date_time::not_special; + using date_time::neg_infin; + using date_time::pos_infin; + using date_time::not_a_date_time; + using date_time::max_date_time; + using date_time::min_date_time; + + //! Time type with no timezone or other adjustments + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE ptime : public date_time::base_time + { + public: + typedef posix_time_system time_system_type; + typedef time_system_type::time_rep_type time_rep_type; + typedef time_system_type::time_duration_type time_duration_type; + typedef ptime time_type; + //! Construct with date and offset in day + ptime(gregorian::date d,time_duration_type td) : date_time::base_time(d,td) + {} + //! Construct a time at start of the given day (midnight) + explicit ptime(gregorian::date d) : date_time::base_time(d,time_duration_type(0,0,0)) + {} + //! Copy from time_rep + ptime(const time_rep_type& rhs): + date_time::base_time(rhs) + {} + //! Construct from special value + ptime(const special_values sv) : date_time::base_time(sv) + {} +#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR) + // Default constructor constructs to not_a_date_time + ptime() : date_time::base_time(gregorian::date(not_a_date_time), time_duration_type(not_a_date_time)) + {} +#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR + + }; + + + +} }//namespace posix_time + + +#endif + diff --git a/boost/date_time/posix_time/time_period.hpp b/boost/date_time/posix_time/time_period.hpp new file mode 100644 index 00000000..7c6095b8 --- /dev/null +++ b/boost/date_time/posix_time/time_period.hpp @@ -0,0 +1,29 @@ +#ifndef POSIX_TIME_PERIOD_HPP___ +#define POSIX_TIME_PERIOD_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include "boost/date_time/period.hpp" +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/posix_time/ptime.hpp" + +namespace boost { +namespace posix_time { + + //! Time period type + /*! \ingroup time_basics + */ + typedef date_time::period time_period; + + +} }//namespace posix_time + + +#endif + diff --git a/boost/date_time/special_defs.hpp b/boost/date_time/special_defs.hpp new file mode 100644 index 00000000..5a757be1 --- /dev/null +++ b/boost/date_time/special_defs.hpp @@ -0,0 +1,25 @@ +#ifndef DATE_TIME_SPECIAL_DEFS_HPP__ +#define DATE_TIME_SPECIAL_DEFS_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +namespace boost { +namespace date_time { + + enum special_values {not_a_date_time, + neg_infin, pos_infin, + min_date_time, max_date_time, + not_special, NumSpecialValues}; + + +} } //namespace date_time + + +#endif + diff --git a/boost/date_time/time.hpp b/boost/date_time/time.hpp new file mode 100644 index 00000000..632f10d7 --- /dev/null +++ b/boost/date_time/time.hpp @@ -0,0 +1,193 @@ +#ifndef DATE_TIME_TIME_HPP___ +#define DATE_TIME_TIME_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +/*! @file time.hpp + This file contains the interface for the time associated classes. +*/ +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //! Representation of a precise moment in time, including the date. + /*! + This class is a skeleton for the interface of a temporal type + with a resolution that is higher than a day. It is intended that + this class be the base class and that the actual time + class be derived using the BN pattern. In this way, the derived + class can make decisions such as 'should there be a default constructor' + and what should it set its value to, should there be optional constructors + say allowing only an time_durations that generate a time from a clock,etc. + So, in fact multiple time types can be created for a time_system with + different construction policies, and all of them can perform basic + operations by only writing a copy constructor. Finally, compiler + errors are also shorter. + + The real behavior of the time class is provided by the time_system + template parameter. This class must provide all the logic + for addition, subtraction, as well as define all the interface + types. + + */ + + template + class base_time : private + boost::less_than_comparable > + { + public: + // A tag for type categorization. Can be used to detect Boost.DateTime time points in generic code. + typedef void _is_boost_date_time_time_point; + typedef T time_type; + typedef typename time_system::time_rep_type time_rep_type; + typedef typename time_system::date_type date_type; + typedef typename time_system::date_duration_type date_duration_type; + typedef typename time_system::time_duration_type time_duration_type; + //typedef typename time_system::hms_type hms_type; + + base_time(const date_type& day, + const time_duration_type& td, + dst_flags dst=not_dst) : + time_(time_system::get_time_rep(day, td, dst)) + {} + base_time(special_values sv) : + time_(time_system::get_time_rep(sv)) + {} + base_time(const time_rep_type& rhs) : + time_(rhs) + {} + date_type date() const + { + return time_system::get_date(time_); + } + time_duration_type time_of_day() const + { + return time_system::get_time_of_day(time_); + } + /*! Optional bool parameter will return time zone as an offset + * (ie "+07:00"). Empty string is returned for classes that do + * not use a time_zone */ + std::string zone_name(bool /*as_offset*/=false) const + { + return time_system::zone_name(time_); + } + /*! Optional bool parameter will return time zone as an offset + * (ie "+07:00"). Empty string is returned for classes that do + * not use a time_zone */ + std::string zone_abbrev(bool /*as_offset*/=false) const + { + return time_system::zone_name(time_); + } + //! An empty string is returned for classes that do not use a time_zone + std::string zone_as_posix_string() const + { + return std::string(); + } + + //! check to see if date is not a value + bool is_not_a_date_time() const + { + return time_.is_not_a_date_time(); + } + //! check to see if date is one of the infinity values + bool is_infinity() const + { + return (is_pos_infinity() || is_neg_infinity()); + } + //! check to see if date is greater than all possible dates + bool is_pos_infinity() const + { + return time_.is_pos_infinity(); + } + //! check to see if date is greater than all possible dates + bool is_neg_infinity() const + { + return time_.is_neg_infinity(); + } + //! check to see if time is a special value + bool is_special() const + { + return(is_not_a_date_time() || is_infinity()); + } + //!Equality operator -- others generated by boost::equality_comparable + bool operator==(const time_type& rhs) const + { + return time_system::is_equal(time_,rhs.time_); + } + //!Equality operator -- others generated by boost::less_than_comparable + bool operator<(const time_type& rhs) const + { + return time_system::is_less(time_,rhs.time_); + } + //! difference between two times + time_duration_type operator-(const time_type& rhs) const + { + return time_system::subtract_times(time_, rhs.time_); + } + //! add date durations + time_type operator+(const date_duration_type& dd) const + { + return time_system::add_days(time_, dd); + } + time_type operator+=(const date_duration_type& dd) + { + time_ = (time_system::get_time_rep(date() + dd, time_of_day())); + return time_type(time_); + } + //! subtract date durations + time_type operator-(const date_duration_type& dd) const + { + return time_system::subtract_days(time_, dd); + } + time_type operator-=(const date_duration_type& dd) + { + time_ = (time_system::get_time_rep(date() - dd, time_of_day())); + return time_type(time_); + } + //! add time durations + time_type operator+(const time_duration_type& td) const + { + return time_type(time_system::add_time_duration(time_, td)); + } + time_type operator+=(const time_duration_type& td) + { + time_ = (time_system::get_time_rep(date(), time_of_day() + td)); + return time_type(time_); + } + //! subtract time durations + time_type operator-(const time_duration_type& rhs) const + { + return time_system::subtract_time_duration(time_, rhs); + } + time_type operator-=(const time_duration_type& td) + { + time_ = (time_system::get_time_rep(date(), time_of_day() - td)); + return time_type(time_); + } + + protected: + time_rep_type time_; + }; + + + + + +} } //namespace date_time::boost + + +#endif + diff --git a/boost/date_time/time_clock.hpp b/boost/date_time/time_clock.hpp new file mode 100644 index 00000000..a64a5b81 --- /dev/null +++ b/boost/date_time/time_clock.hpp @@ -0,0 +1,83 @@ +#ifndef DATE_TIME_TIME_CLOCK_HPP___ +#define DATE_TIME_TIME_CLOCK_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file time_clock.hpp + This file contains the interface for clock devices. +*/ + +#include "boost/date_time/c_time.hpp" +#include "boost/shared_ptr.hpp" + +namespace boost { +namespace date_time { + + + //! A clock providing time level services based on C time_t capabilities + /*! This clock provides resolution to the 1 second level + */ + template + class second_clock + { + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + + static time_type local_time() + { + ::std::time_t t; + ::std::time(&t); + ::std::tm curr, *curr_ptr; + //curr_ptr = ::std::localtime(&t); + curr_ptr = c_time::localtime(&t, &curr); + return create_time(curr_ptr); + } + + + //! Get the current day in universal date as a ymd_type + static time_type universal_time() + { + + ::std::time_t t; + ::std::time(&t); + ::std::tm curr, *curr_ptr; + //curr_ptr = ::std::gmtime(&t); + curr_ptr = c_time::gmtime(&t, &curr); + return create_time(curr_ptr); + } + + template + static time_type local_time(boost::shared_ptr tz_ptr) + { + typedef typename time_type::utc_time_type utc_time_type; + utc_time_type utc_time = second_clock::universal_time(); + return time_type(utc_time, tz_ptr); + } + + + private: + static time_type create_time(::std::tm* current) + { + date_type d(static_cast(current->tm_year + 1900), + static_cast(current->tm_mon + 1), + static_cast(current->tm_mday)); + time_duration_type td(current->tm_hour, + current->tm_min, + current->tm_sec); + return time_type(d,td); + } + + }; + + +} } //namespace date_time + + +#endif diff --git a/boost/date_time/time_defs.hpp b/boost/date_time/time_defs.hpp new file mode 100644 index 00000000..852207e6 --- /dev/null +++ b/boost/date_time/time_defs.hpp @@ -0,0 +1,43 @@ +#ifndef DATE_TIME_TIME_PRECISION_LIMITS_HPP +#define DATE_TIME_TIME_PRECISION_LIMITS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + + + +/*! \file time_defs.hpp + This file contains nice definitions for handling the resoluion of various time + reprsentations. +*/ + +namespace boost { +namespace date_time { + + //!Defines some nice types for handling time level resolutions + enum time_resolutions { + sec, + tenth, + hundreth, // deprecated misspelled version of hundredth + hundredth = hundreth, + milli, + ten_thousandth, + micro, + nano, + NumResolutions + }; + + //! Flags for daylight savings or summer time + enum dst_flags {not_dst, is_dst, calculate}; + + +} } //namespace date_time + + + +#endif diff --git a/boost/date_time/time_duration.hpp b/boost/date_time/time_duration.hpp new file mode 100644 index 00000000..67930cf8 --- /dev/null +++ b/boost/date_time/time_duration.hpp @@ -0,0 +1,298 @@ +#ifndef DATE_TIME_TIME_DURATION_HPP___ +#define DATE_TIME_TIME_DURATION_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Represents some amount of elapsed time measure to a given resolution + /*! This class represents a standard set of capabilities for all + counted time durations. Time duration implementations should derive + from this class passing their type as the first template parameter. + This design allows the subclass duration types to provide custom + construction policies or other custom features not provided here. + + @param T The subclass type + @param rep_type The time resolution traits for this duration type. + */ + template + class BOOST_SYMBOL_VISIBLE time_duration : private + boost::less_than_comparable > + /* dividable, addable, and subtractable operator templates + * won't work with this class (MSVC++ 6.0). return type + * from '+=' is different than expected return type + * from '+'. multipliable probably wont work + * either (haven't tried) */ + { + public: + // A tag for type categorization. Can be used to detect Boost.DateTime duration types in generic code. + typedef void _is_boost_date_time_duration; + typedef T duration_type; //the subclass + typedef rep_type traits_type; + typedef typename rep_type::day_type day_type; + typedef typename rep_type::hour_type hour_type; + typedef typename rep_type::min_type min_type; + typedef typename rep_type::sec_type sec_type; + typedef typename rep_type::fractional_seconds_type fractional_seconds_type; + typedef typename rep_type::tick_type tick_type; + typedef typename rep_type::impl_type impl_type; + + time_duration() : ticks_(0) {} + time_duration(hour_type hours_in, + min_type minutes_in, + sec_type seconds_in=0, + fractional_seconds_type frac_sec_in = 0) : + ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in)) + {} + // copy constructor required for dividable<> + //! Construct from another time_duration (Copy constructor) + time_duration(const time_duration& other) + : ticks_(other.ticks_) + {} + //! Construct from special_values + time_duration(special_values sv) : ticks_(impl_type::from_special(sv)) + {} + //! Returns smallest representable duration + static duration_type unit() + { + return duration_type(0,0,0,1); + } + //! Return the number of ticks in a second + static tick_type ticks_per_second() + { + return rep_type::res_adjust(); + } + //! Provide the resolution of this duration type + static time_resolutions resolution() + { + return rep_type::resolution(); + } + //! Returns number of hours in the duration + hour_type hours() const + { + return static_cast(ticks() / (3600*ticks_per_second())); + } + //! Returns normalized number of minutes + min_type minutes() const + { + return static_cast((ticks() / (60*ticks_per_second())) % 60); + } + //! Returns normalized number of seconds (0..60) + sec_type seconds() const + { + return static_cast((ticks()/ticks_per_second()) % 60); + } + //! Returns total number of seconds truncating any fractional seconds + sec_type total_seconds() const + { + return static_cast(ticks() / ticks_per_second()); + } + //! Returns total number of milliseconds truncating any fractional seconds + tick_type total_milliseconds() const + { + if (ticks_per_second() < 1000) { + return ticks() * (static_cast(1000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000)) ; + } + //! Returns total number of nanoseconds truncating any sub millisecond values + tick_type total_nanoseconds() const + { + if (ticks_per_second() < 1000000000) { + return ticks() * (static_cast(1000000000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000000000)) ; + } + //! Returns total number of microseconds truncating any sub microsecond values + tick_type total_microseconds() const + { + if (ticks_per_second() < 1000000) { + return ticks() * (static_cast(1000000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000000)) ; + } + //! Returns count of fractional seconds at given resolution + fractional_seconds_type fractional_seconds() const + { + return (ticks() % ticks_per_second()); + } + //! Returns number of possible digits in fractional seconds + static unsigned short num_fractional_digits() + { + return rep_type::num_fractional_digits(); + } + duration_type invert_sign() const + { + return duration_type(ticks_ * (-1)); + } + bool is_negative() const + { + return ticks_ < 0; + } + bool operator<(const time_duration& rhs) const + { + return ticks_ < rhs.ticks_; + } + bool operator==(const time_duration& rhs) const + { + return ticks_ == rhs.ticks_; + } + //! unary- Allows for time_duration td = -td1 + duration_type operator-()const + { + return duration_type(ticks_ * (-1)); + } + duration_type operator-(const duration_type& d) const + { + return duration_type(ticks_ - d.ticks_); + } + duration_type operator+(const duration_type& d) const + { + return duration_type(ticks_ + d.ticks_); + } + duration_type operator/(int divisor) const + { + return duration_type(ticks_ / divisor); + } + duration_type operator-=(const duration_type& d) + { + ticks_ = ticks_ - d.ticks_; + return duration_type(ticks_); + } + duration_type operator+=(const duration_type& d) + { + ticks_ = ticks_ + d.ticks_; + return duration_type(ticks_); + } + //! Division operations on a duration with an integer. + duration_type operator/=(int divisor) + { + ticks_ = ticks_ / divisor; + return duration_type(ticks_); + } + //! Multiplication operations an a duration with an integer + duration_type operator*(int rhs) const + { + return duration_type(ticks_ * rhs); + } + duration_type operator*=(int divisor) + { + ticks_ = ticks_ * divisor; + return duration_type(ticks_); + } + tick_type ticks() const + { + return traits_type::as_number(ticks_); + } + + //! Is ticks_ a special value? + bool is_special()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_special(); + } + else{ + return false; + } + } + //! Is duration pos-infinity + bool is_pos_infinity()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_pos_infinity(); + } + else{ + return false; + } + } + //! Is duration neg-infinity + bool is_neg_infinity()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_neg_infinity(); + } + else{ + return false; + } + } + //! Is duration not-a-date-time + bool is_not_a_date_time()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_nan(); + } + else{ + return false; + } + } + + //! Used for special_values output + impl_type get_rep()const + { + return ticks_; + } + + protected: + explicit time_duration(impl_type in) : ticks_(in) {} + impl_type ticks_; + }; + + + + //! Template for instantiating derived adjusting durations + /* These templates are designed to work with multiples of + * 10 for frac_of_second and resolution adjustment + */ + template + class BOOST_SYMBOL_VISIBLE subsecond_duration : public base_duration + { + public: + typedef typename base_duration::impl_type impl_type; + typedef typename base_duration::traits_type traits_type; + + private: + // To avoid integer overflow we precompute the duration resolution conversion coefficient (ticket #3471) + BOOST_STATIC_ASSERT_MSG((traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second % frac_of_second : frac_of_second % traits_type::ticks_per_second) == 0,\ + "The base duration resolution must be a multiple of the subsecond duration resolution"); + BOOST_STATIC_CONSTANT(boost::int64_t, adjustment_ratio = (traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second / frac_of_second : frac_of_second / traits_type::ticks_per_second)); + + public: + // The argument (ss) must be an integral type + template + explicit subsecond_duration(T const& ss, + typename boost::enable_if, void>::type* = 0) : + base_duration(impl_type(traits_type::ticks_per_second >= frac_of_second ? ss * adjustment_ratio : ss / adjustment_ratio)) + { + } + }; + +} } //namespace date_time + + + + +#endif + diff --git a/boost/date_time/time_iterator.hpp b/boost/date_time/time_iterator.hpp new file mode 100644 index 00000000..64439363 --- /dev/null +++ b/boost/date_time/time_iterator.hpp @@ -0,0 +1,52 @@ +#ifndef DATE_TIME_TIME_ITERATOR_HPP___ +#define DATE_TIME_TIME_ITERATOR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +namespace boost { +namespace date_time { + + + //! Simple time iterator skeleton class + template + class time_itr { + public: + typedef typename time_type::time_duration_type time_duration_type; + time_itr(time_type t, time_duration_type d) : current_(t), offset_(d) {} + time_itr& operator++() + { + current_ = current_ + offset_; + return *this; + } + time_itr& operator--() + { + current_ = current_ - offset_; + return *this; + } + time_type operator*() {return current_;} + time_type* operator->() {return ¤t_;} + bool operator< (const time_type& t) {return current_ < t;} + bool operator<= (const time_type& t) {return current_ <= t;} + bool operator!= (const time_type& t) {return current_ != t;} + bool operator== (const time_type& t) {return current_ == t;} + bool operator> (const time_type& t) {return current_ > t;} + bool operator>= (const time_type& t) {return current_ >= t;} + + private: + time_type current_; + time_duration_type offset_; + }; + + + +} }//namespace date_time + + +#endif diff --git a/boost/date_time/time_resolution_traits.hpp b/boost/date_time/time_resolution_traits.hpp new file mode 100644 index 00000000..b6224880 --- /dev/null +++ b/boost/date_time/time_resolution_traits.hpp @@ -0,0 +1,167 @@ +#ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP +#define DATE_TIME_TIME_RESOLUTION_TRAITS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //! Simple function to calculate absolute value of a numeric type + template + // JDG [7/6/02 made a template], + // moved here from time_duration.hpp 2003-Sept-4. + inline T absolute_value(T x) + { + return x < 0 ? -x : x; + } + + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_bi32_impl { + typedef boost::int32_t int_type; + typedef boost::int32_t impl_type; + static int_type as_number(impl_type i){ return i;} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return false;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_adapted32_impl { + typedef boost::int32_t int_type; + typedef boost::date_time::int_adapter impl_type; + static int_type as_number(impl_type i){ return i.as_number();} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return true;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_bi64_impl { + typedef boost::int64_t int_type; + typedef boost::int64_t impl_type; + static int_type as_number(impl_type i){ return i;} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return false;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_adapted64_impl { + typedef boost::int64_t int_type; + typedef boost::date_time::int_adapter impl_type; + static int_type as_number(impl_type i){ return i.as_number();} + //! Used to determine if implemented type is int_adapter or int + static bool is_adapted() { return true;} + }; + + // + // Note about var_type, which is used to define the variable that + // stores hours, minutes, and seconds values: + // + // In Boost 1.65.1 and earlier var_type was boost::int32_t which suffers + // the year 2038 problem. Binary serialization of posix_time uses + // 32-bit values, and uses serialization version 0. + // + // In Boost 1.66.0 the var_type changed to std::time_t, however + // binary serialization was not properly versioned, so on platforms + // where std::time_t is 32-bits, it remains compatible, however on + // platforms where std::time_t is 64-bits, binary serialization ingest + // will be incompatible with previous versions. Furthermore, binary + // serialized output from 1.66.0 will not be compatible with future + // versions. Yes, it's a mess. Static assertions were not present + // in the serialization code to protect against this possibility. + // + // In Boost 1.67.0 the var_type was changed to boost::int64_t, + // ensuring the output size is 64 bits, and the serialization version + // was bumped. Static assertions were added as well, protecting + // future changes in this area. + // + + template // see note above + class time_resolution_traits { + public: + typedef typename frac_sec_type::int_type fractional_seconds_type; + typedef typename frac_sec_type::int_type tick_type; + typedef typename frac_sec_type::impl_type impl_type; + typedef var_type day_type; + typedef var_type hour_type; + typedef var_type min_type; + typedef var_type sec_type; + + // bring in function from frac_sec_type traits structs + static fractional_seconds_type as_number(impl_type i) + { + return frac_sec_type::as_number(i); + } + static bool is_adapted() + { + return frac_sec_type::is_adapted(); + } + + //Would like this to be frac_sec_type, but some compilers complain +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + BOOST_STATIC_CONSTANT(boost::int64_t, ticks_per_second = resolution_adjust); +#else + BOOST_STATIC_CONSTANT(fractional_seconds_type, ticks_per_second = resolution_adjust); +#endif + + static time_resolutions resolution() + { + return res; + } + static unsigned short num_fractional_digits() + { + return frac_digits; + } + static fractional_seconds_type res_adjust() + { + return resolution_adjust; + } + //! Any negative argument results in a negative tick_count + static tick_type to_tick_count(hour_type hours, + min_type minutes, + sec_type seconds, + fractional_seconds_type fs) + { + if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0) + { + hours = absolute_value(hours); + minutes = absolute_value(minutes); + seconds = absolute_value(seconds); + fs = absolute_value(fs); + return static_cast(((((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs) * -1); + } + + return static_cast((((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs); + } + + }; + + typedef time_resolution_traits milli_res; + typedef time_resolution_traits micro_res; + typedef time_resolution_traits nano_res; + + +} } //namespace date_time + + + +#endif diff --git a/boost/date_time/time_system_counted.hpp b/boost/date_time/time_system_counted.hpp new file mode 100644 index 00000000..af27aad3 --- /dev/null +++ b/boost/date_time/time_system_counted.hpp @@ -0,0 +1,254 @@ +#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP +#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + + +#include "boost/date_time/time_defs.hpp" +#include + + +namespace boost { +namespace date_time { + + //! Time representation that uses a single integer count + template + struct counted_time_rep + { + typedef typename config::int_type int_type; + typedef typename config::date_type date_type; + typedef typename config::impl_type impl_type; + typedef typename date_type::duration_type date_duration_type; + typedef typename date_type::calendar_type calendar_type; + typedef typename date_type::ymd_type ymd_type; + typedef typename config::time_duration_type time_duration_type; + typedef typename config::resolution_traits resolution_traits; + + counted_time_rep(const date_type& d, const time_duration_type& time_of_day) + : time_count_(1) + { + if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) { + time_count_ = time_of_day.get_rep() + d.day_count(); + //std::cout << time_count_ << std::endl; + } + else { + time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks(); + } + } + explicit counted_time_rep(int_type count) : + time_count_(count) + {} + explicit counted_time_rep(impl_type count) : + time_count_(count) + {} + date_type date() const + { + if(time_count_.is_special()) { + return date_type(time_count_.as_special()); + } + else { + typename calendar_type::date_int_type dc = static_cast(day_count()); + //std::cout << "time_rep here:" << dc << std::endl; + ymd_type ymd = calendar_type::from_day_number(dc); + return date_type(ymd); + } + } + //int_type day_count() const + unsigned long day_count() const + { + /* resolution_traits::as_number returns a boost::int64_t & + * frac_sec_per_day is also a boost::int64_t so, naturally, + * the division operation returns a boost::int64_t. + * The static_cast to an unsigned long is ok (results in no data loss) + * because frac_sec_per_day is either the number of + * microseconds per day, or the number of nanoseconds per day. + * Worst case scenario: resolution_traits::as_number returns the + * maximum value an int64_t can hold and frac_sec_per_day + * is microseconds per day (lowest possible value). + * The division operation will then return a value of 106751991 - + * easily fitting in an unsigned long. + */ + return static_cast(resolution_traits::as_number(time_count_) / frac_sec_per_day()); + } + int_type time_count() const + { + return resolution_traits::as_number(time_count_); + } + int_type tod() const + { + return resolution_traits::as_number(time_count_) % frac_sec_per_day(); + } + static int_type frac_sec_per_day() + { + int_type seconds_per_day = 60*60*24; + int_type fractional_sec_per_sec(resolution_traits::res_adjust()); + return seconds_per_day*fractional_sec_per_sec; + } + bool is_pos_infinity()const + { + return impl_type::is_pos_inf(time_count_.as_number()); + } + bool is_neg_infinity()const + { + return impl_type::is_neg_inf(time_count_.as_number()); + } + bool is_not_a_date_time()const + { + return impl_type::is_not_a_number(time_count_.as_number()); + } + bool is_special()const + { + return time_count_.is_special(); + } + impl_type get_rep()const + { + return time_count_; + } + private: + impl_type time_count_; + }; + + //! An unadjusted time system implementation. + template + class counted_time_system + { + public: + typedef time_rep time_rep_type; + typedef typename time_rep_type::impl_type impl_type; + typedef typename time_rep_type::time_duration_type time_duration_type; + typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type; + typedef typename time_rep_type::date_type date_type; + typedef typename time_rep_type::date_duration_type date_duration_type; + + + template static void unused_var(const T&) {} + + static time_rep_type get_time_rep(const date_type& day, + const time_duration_type& tod, + date_time::dst_flags dst=not_dst) + { + unused_var(dst); + return time_rep_type(day, tod); + } + + static time_rep_type get_time_rep(special_values sv) + { + switch (sv) { + case not_a_date_time: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + case pos_infin: + return time_rep_type(date_type(pos_infin), + time_duration_type(pos_infin)); + case neg_infin: + return time_rep_type(date_type(neg_infin), + time_duration_type(neg_infin)); + case max_date_time: { + time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); + return time_rep_type(date_type(max_date_time), td); + } + case min_date_time: + return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); + + default: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + + } + + } + + static date_type get_date(const time_rep_type& val) + { + return val.date(); + } + static time_duration_type get_time_of_day(const time_rep_type& val) + { + if(val.is_special()) { + return time_duration_type(val.get_rep().as_special()); + } + else{ + return time_duration_type(0,0,0,val.tod()); + } + } + static std::string zone_name(const time_rep_type&) + { + return ""; + } + static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) + { + return (lhs.time_count() == rhs.time_count()); + } + static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) + { + return (lhs.time_count() < rhs.time_count()); + } + static time_rep_type add_days(const time_rep_type& base, + const date_duration_type& dd) + { + if(base.is_special() || dd.is_special()) { + return(time_rep_type(base.get_rep() + dd.get_rep())); + } + else { + return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day())); + } + } + static time_rep_type subtract_days(const time_rep_type& base, + const date_duration_type& dd) + { + if(base.is_special() || dd.is_special()) { + return(time_rep_type(base.get_rep() - dd.get_rep())); + } + else{ + return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day())); + } + } + static time_rep_type subtract_time_duration(const time_rep_type& base, + const time_duration_type& td) + { + if(base.is_special() || td.is_special()) { + return(time_rep_type(base.get_rep() - td.get_rep())); + } + else { + return time_rep_type(base.time_count() - td.ticks()); + } + } + static time_rep_type add_time_duration(const time_rep_type& base, + time_duration_type td) + { + if(base.is_special() || td.is_special()) { + return(time_rep_type(base.get_rep() + td.get_rep())); + } + else { + return time_rep_type(base.time_count() + td.ticks()); + } + } + static time_duration_type subtract_times(const time_rep_type& lhs, + const time_rep_type& rhs) + { + if(lhs.is_special() || rhs.is_special()) { + return(time_duration_type( + impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number()))); + } + else { + fractional_seconds_type fs = lhs.time_count() - rhs.time_count(); + return time_duration_type(0,0,0,fs); + } + } + + }; + + +} } //namespace date_time + + + +#endif + diff --git a/boost/date_time/time_system_split.hpp b/boost/date_time/time_system_split.hpp new file mode 100644 index 00000000..8e1efbe4 --- /dev/null +++ b/boost/date_time/time_system_split.hpp @@ -0,0 +1,213 @@ +#ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP +#define DATE_TIME_TIME_SYSTEM_SPLIT_HPP + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/special_defs.hpp" + +namespace boost { +namespace date_time { + + //! An unadjusted time system implementation. +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) + template +#else + template +#endif + class split_timedate_system + { + public: + typedef typename config::time_rep_type time_rep_type; + typedef typename config::date_type date_type; + typedef typename config::time_duration_type time_duration_type; + typedef typename config::date_duration_type date_duration_type; + typedef typename config::int_type int_type; + typedef typename config::resolution_traits resolution_traits; + + //86400 is number of seconds in a day... +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) + typedef date_time::wrapping_int wrap_int_type; +#else + private: + BOOST_STATIC_CONSTANT(int_type, ticks_per_day = INT64_C(86400) * config::tick_per_second); + public: +# if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0X581) ) + typedef date_time::wrapping_int< split_timedate_system::int_type, split_timedate_system::ticks_per_day> wrap_int_type; +# else + typedef date_time::wrapping_int wrap_int_type; +#endif +#endif + + static time_rep_type get_time_rep(special_values sv) + { + switch (sv) { + case not_a_date_time: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + case pos_infin: + return time_rep_type(date_type(pos_infin), + time_duration_type(pos_infin)); + case neg_infin: + return time_rep_type(date_type(neg_infin), + time_duration_type(neg_infin)); + case max_date_time: { + time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); + return time_rep_type(date_type(max_date_time), td); + } + case min_date_time: + return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); + + default: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + + } + + } + + static time_rep_type get_time_rep(const date_type& day, + const time_duration_type& tod, + date_time::dst_flags /* dst */ = not_dst) + { + if(day.is_special() || tod.is_special()) { + if(day.is_not_a_date() || tod.is_not_a_date_time()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else if(day.is_pos_infinity()) { + if(tod.is_neg_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(day, time_duration_type(pos_infin)); + } + } + else if(day.is_neg_infinity()) { + if(tod.is_pos_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(day, time_duration_type(neg_infin)); + } + } + else if(tod.is_pos_infinity()) { + if(day.is_neg_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(date_type(pos_infin), tod); + } + } + else if(tod.is_neg_infinity()) { + if(day.is_pos_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(date_type(neg_infin), tod); + } + } + } + return time_rep_type(day, tod); + } + static date_type get_date(const time_rep_type& val) + { + return date_type(val.day); + } + static time_duration_type get_time_of_day(const time_rep_type& val) + { + return time_duration_type(val.time_of_day); + } + static std::string zone_name(const time_rep_type&) + { + return std::string(); + } + static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) + { + return ((lhs.day == rhs.day) && (lhs.time_of_day == rhs.time_of_day)); + } + static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) + { + if (lhs.day < rhs.day) return true; + if (lhs.day > rhs.day) return false; + return (lhs.time_of_day < rhs.time_of_day); + } + static time_rep_type add_days(const time_rep_type& base, + const date_duration_type& dd) + { + return time_rep_type(base.day+dd, base.time_of_day); + } + static time_rep_type subtract_days(const time_rep_type& base, + const date_duration_type& dd) + { + return split_timedate_system::get_time_rep(base.day-dd, base.time_of_day); + } + static time_rep_type subtract_time_duration(const time_rep_type& base, + const time_duration_type& td) + { + if(base.day.is_special() || td.is_special()) + { + return split_timedate_system::get_time_rep(base.day, -td); + } + if (td.is_negative()) { + time_duration_type td1 = td.invert_sign(); + return add_time_duration(base,td1); + } + + wrap_int_type day_offset(base.time_of_day.ticks()); + date_duration_type day_overflow(static_cast(day_offset.subtract(td.ticks()))); + + return time_rep_type(base.day-day_overflow, + time_duration_type(0,0,0,day_offset.as_int())); + } + static time_rep_type add_time_duration(const time_rep_type& base, + time_duration_type td) + { + if(base.day.is_special() || td.is_special()) { + return split_timedate_system::get_time_rep(base.day, td); + } + if (td.is_negative()) { + time_duration_type td1 = td.invert_sign(); + return subtract_time_duration(base,td1); + } + + wrap_int_type day_offset(base.time_of_day.ticks()); + date_duration_type day_overflow(static_cast< typename date_duration_type::duration_rep_type >(day_offset.add(td.ticks()))); + + return time_rep_type(base.day+day_overflow, + time_duration_type(0,0,0,day_offset.as_int())); + } + static time_duration_type subtract_times(const time_rep_type& lhs, + const time_rep_type& rhs) + { + date_duration_type dd = lhs.day - rhs.day; + if (BOOST_LIKELY(!dd.is_special())) { + time_duration_type td(dd.days()*24,0,0); // days * 24 hours + time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; + return td+td2; + } else { + time_duration_type td(dd.as_special()); + time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; + return td+td2; + } + } + + }; + +} } //namespace date_time + + +#endif diff --git a/boost/date_time/wrapping_int.hpp b/boost/date_time/wrapping_int.hpp new file mode 100644 index 00000000..6f869d30 --- /dev/null +++ b/boost/date_time/wrapping_int.hpp @@ -0,0 +1,169 @@ +#ifndef _DATE_TIME_WRAPPING_INT_HPP__ +#define _DATE_TIME_WRAPPING_INT_HPP__ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +namespace boost { +namespace date_time { + +//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type) +/*! In composite date and time types this type is used to + * wrap at the day boundary. + * Ex: + * A wrapping_int will roll over after nine, and + * roll under below zero. This gives a range of [0,9] + * + * NOTE: it is strongly recommended that wrapping_int2 be used + * instead of wrapping_int as wrapping_int is to be depricated + * at some point soon. + * + * Also Note that warnings will occur if instantiated with an + * unsigned type. Only a signed type should be used! + */ +template +class wrapping_int { +public: + typedef int_type_ int_type; + //typedef overflow_type_ overflow_type; + static int_type wrap_value() {return wrap_val;} + //!Add, return true if wrapped + wrapping_int(int_type v) : value_(v) {} + //! Explicit converion method + int_type as_int() const {return value_;} + operator int_type() const {return value_;} + //!Add, return number of wraps performed + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: add a negative number and wrapping under could occur, + * this would be indicated by a negative return value. If wrapping over + * took place, a positive value would be returned */ + template< typename IntT > + IntT add(IntT v) + { + int_type remainder = static_cast(v % (wrap_val)); + IntT overflow = static_cast(v / (wrap_val)); + value_ = static_cast(value_ + remainder); + return calculate_wrap(overflow); + } + //! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps) + /*! The sign of the returned value will indicate which direction the + * wraps went (positive indicates wrap under, negative indicates wrap over). + * Ex: subtract a negative number and wrapping over could + * occur, this would be indicated by a negative return value. If + * wrapping under took place, a positive value would be returned. */ + template< typename IntT > + IntT subtract(IntT v) + { + int_type remainder = static_cast(v % (wrap_val)); + IntT underflow = static_cast(-(v / (wrap_val))); + value_ = static_cast(value_ - remainder); + return calculate_wrap(underflow) * -1; + } +private: + int_type value_; + + template< typename IntT > + IntT calculate_wrap(IntT wrap) + { + if ((value_) >= wrap_val) + { + ++wrap; + value_ -= (wrap_val); + } + else if(value_ < 0) + { + --wrap; + value_ += (wrap_val); + } + return wrap; + } + +}; + + +//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type) +/*! Bad name, quick impl to fix a bug -- fix later!! + * This allows the wrap to restart at a value other than 0. + */ +template +class wrapping_int2 { +public: + typedef int_type_ int_type; + static int_type wrap_value() {return wrap_max;} + static int_type min_value() {return wrap_min;} + /*! If initializing value is out of range of [wrap_min, wrap_max], + * value will be initialized to closest of min or max */ + wrapping_int2(int_type v) : value_(v) { + if(value_ < wrap_min) + { + value_ = wrap_min; + } + if(value_ > wrap_max) + { + value_ = wrap_max; + } + } + //! Explicit converion method + int_type as_int() const {return value_;} + operator int_type() const {return value_;} + //!Add, return number of wraps performed + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: add a negative number and wrapping under could occur, + * this would be indicated by a negative return value. If wrapping over + * took place, a positive value would be returned */ + template< typename IntT > + IntT add(IntT v) + { + int_type remainder = static_cast(v % (wrap_max - wrap_min + 1)); + IntT overflow = static_cast(v / (wrap_max - wrap_min + 1)); + value_ = static_cast(value_ + remainder); + return calculate_wrap(overflow); + } + //! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps) + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: subtract a negative number and wrapping over could + * occur, this would be indicated by a positive return value. If + * wrapping under took place, a negative value would be returned */ + template< typename IntT > + IntT subtract(IntT v) + { + int_type remainder = static_cast(v % (wrap_max - wrap_min + 1)); + IntT underflow = static_cast(-(v / (wrap_max - wrap_min + 1))); + value_ = static_cast(value_ - remainder); + return calculate_wrap(underflow); + } + +private: + int_type value_; + + template< typename IntT > + IntT calculate_wrap(IntT wrap) + { + if ((value_) > wrap_max) + { + ++wrap; + value_ -= (wrap_max - wrap_min + 1); + } + else if((value_) < wrap_min) + { + --wrap; + value_ += (wrap_max - wrap_min + 1); + } + return wrap; + } +}; + + + +} } //namespace date_time + + + +#endif + diff --git a/boost/date_time/year_month_day.hpp b/boost/date_time/year_month_day.hpp new file mode 100644 index 00000000..6355ab27 --- /dev/null +++ b/boost/date_time/year_month_day.hpp @@ -0,0 +1,47 @@ +#ifndef YearMonthDayBase_HPP__ +#define YearMonthDayBase_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include + +namespace boost { +namespace date_time { + + //! Allow rapid creation of ymd triples of different types + template + struct BOOST_SYMBOL_VISIBLE year_month_day_base { + year_month_day_base(YearType year, + MonthType month, + DayType day); + YearType year; + MonthType month; + DayType day; + typedef YearType year_type; + typedef MonthType month_type; + typedef DayType day_type; + }; + + + //! A basic constructor + template + inline + year_month_day_base::year_month_day_base(YearType y, + MonthType m, + DayType d) : + year(y), + month(m), + day(d) + {} + +} }//namespace date_time + + +#endif + diff --git a/boost/detail/basic_pointerbuf.hpp b/boost/detail/basic_pointerbuf.hpp new file mode 100644 index 00000000..1d8cf373 --- /dev/null +++ b/boost/detail/basic_pointerbuf.hpp @@ -0,0 +1,139 @@ +//----------------------------------------------------------------------------- +// boost detail/templated_streams.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2013 John Maddock, Antony Polukhin +// +// +// 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_DETAIL_BASIC_POINTERBUF_HPP +#define BOOST_DETAIL_BASIC_POINTERBUF_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include "boost/config.hpp" +#include + +namespace boost { namespace detail { + +// +// class basic_pointerbuf: +// acts as a stream buffer which wraps around a pair of pointers: +// +template +class basic_pointerbuf : public BufferT { +protected: + typedef BufferT base_type; + typedef basic_pointerbuf this_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::char_type char_type; + typedef typename base_type::pos_type pos_type; + typedef ::std::streamsize streamsize; + typedef typename base_type::off_type off_type; + +public: + basic_pointerbuf() : base_type() { setbuf(0, 0); } + const charT* getnext() { return this->gptr(); } + +#ifndef BOOST_NO_USING_TEMPLATE + using base_type::pptr; + using base_type::pbase; +#else + charT* pptr() const { return base_type::pptr(); } + charT* pbase() const { return base_type::pbase(); } +#endif + +protected: + // VC mistakenly assumes that `setbuf` and other functions are not referenced. + // Marking those functions with `inline` suppresses the warnings. + // There must be no harm from marking virtual functions as inline: inline virtual + // call can be inlined ONLY when the compiler knows the "exact class". + inline base_type* setbuf(char_type* s, streamsize n); + inline typename this_type::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which); + inline typename this_type::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which); + +private: + basic_pointerbuf& operator=(const basic_pointerbuf&); + basic_pointerbuf(const basic_pointerbuf&); +}; + +template +BufferT* +basic_pointerbuf::setbuf(char_type* s, streamsize n) +{ + this->setg(s, s, s + n); + return this; +} + +template +typename basic_pointerbuf::pos_type +basic_pointerbuf::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) +{ + typedef typename boost::int_t::least cast_type; + + if(which & ::std::ios_base::out) + return pos_type(off_type(-1)); + std::ptrdiff_t size = this->egptr() - this->eback(); + std::ptrdiff_t pos = this->gptr() - this->eback(); + charT* g = this->eback(); + switch(static_cast(way)) + { + case ::std::ios_base::beg: + if((off < 0) || (off > size)) + return pos_type(off_type(-1)); + else + this->setg(g, g + off, g + size); + break; + case ::std::ios_base::end: + if((off < 0) || (off > size)) + return pos_type(off_type(-1)); + else + this->setg(g, g + size - off, g + size); + break; + case ::std::ios_base::cur: + { + std::ptrdiff_t newpos = static_cast(pos + off); + if((newpos < 0) || (newpos > size)) + return pos_type(off_type(-1)); + else + this->setg(g, g + newpos, g + size); + break; + } + default: ; + } +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + return static_cast(this->gptr() - this->eback()); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +} + +template +typename basic_pointerbuf::pos_type +basic_pointerbuf::seekpos(pos_type sp, ::std::ios_base::openmode which) +{ + if(which & ::std::ios_base::out) + return pos_type(off_type(-1)); + off_type size = static_cast(this->egptr() - this->eback()); + charT* g = this->eback(); + if(off_type(sp) <= size) + { + this->setg(g, g + off_type(sp), g + size); + } + return pos_type(off_type(-1)); +} + +}} // namespace boost::detail + +#endif // BOOST_DETAIL_BASIC_POINTERBUF_HPP + diff --git a/boost/detail/bitmask.hpp b/boost/detail/bitmask.hpp new file mode 100644 index 00000000..63d4fac0 --- /dev/null +++ b/boost/detail/bitmask.hpp @@ -0,0 +1,58 @@ +// boost/detail/bitmask.hpp ------------------------------------------------// + +// Copyright Beman Dawes 2006 + +// Distributed under the Boost Software License, Version 1.0 +// http://www.boost.org/LICENSE_1_0.txt + +// Usage: enum foo { a=1, b=2, c=4 }; +// BOOST_BITMASK( foo ) +// +// void f( foo arg ); +// ... +// f( a | c ); +// +// See [bitmask.types] in the C++ standard for the formal specification + +#ifndef BOOST_BITMASK_HPP +#define BOOST_BITMASK_HPP + +#include +#include + +#define BOOST_BITMASK(Bitmask) \ + \ + inline BOOST_CONSTEXPR Bitmask operator| (Bitmask x , Bitmask y ) \ + { return static_cast( static_cast(x) \ + | static_cast(y)); } \ + \ + inline BOOST_CONSTEXPR Bitmask operator& (Bitmask x , Bitmask y ) \ + { return static_cast( static_cast(x) \ + & static_cast(y)); } \ + \ + inline BOOST_CONSTEXPR Bitmask operator^ (Bitmask x , Bitmask y ) \ + { return static_cast( static_cast(x) \ + ^ static_cast(y)); } \ + \ + inline BOOST_CONSTEXPR Bitmask operator~ (Bitmask x ) \ + { return static_cast(~static_cast(x)); } \ + \ + inline Bitmask & operator&=(Bitmask& x , Bitmask y) \ + { x = x & y ; return x ; } \ + \ + inline Bitmask & operator|=(Bitmask& x , Bitmask y) \ + { x = x | y ; return x ; } \ + \ + inline Bitmask & operator^=(Bitmask& x , Bitmask y) \ + { x = x ^ y ; return x ; } \ + \ + /* Boost extensions to [bitmask.types] */ \ + \ + inline BOOST_CONSTEXPR bool operator!(Bitmask x) \ + { return !static_cast(x); } \ + \ + inline BOOST_CONSTEXPR bool bitmask_set(Bitmask x) \ + { return !!x; } + +#endif // BOOST_BITMASK_HPP + diff --git a/boost/detail/call_traits.hpp b/boost/detail/call_traits.hpp new file mode 100644 index 00000000..36dea000 --- /dev/null +++ b/boost/detail/call_traits.hpp @@ -0,0 +1,172 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & 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/utility for most recent version including documentation. + +// call_traits: defines typedefs for function usage +// (see libs/utility/call_traits.htm) + +/* Release notes: + 23rd July 2000: + Fixed array specialization. (JM) + Added Borland specific fixes for reference types + (issue raised by Steve Cleary). +*/ + +#ifndef BOOST_DETAIL_CALL_TRAITS_HPP +#define BOOST_DETAIL_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif +#include + +#include +#include +#include +#include + +namespace boost{ + +namespace detail{ + +template +struct ct_imp2 +{ + typedef const T& param_type; +}; + +template +struct ct_imp2 +{ + typedef const T param_type; +}; + +template +struct ct_imp +{ + typedef const T& param_type; +}; + +template +struct ct_imp +{ + typedef typename ct_imp2::param_type param_type; +}; + +template +struct ct_imp +{ + typedef typename ct_imp2::param_type param_type; +}; + +template +struct ct_imp +{ + typedef const T param_type; +}; + +} + +template +struct call_traits +{ +public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + // + // C++ Builder workaround: we should be able to define a compile time + // constant and pass that as a single template parameter to ct_imp, + // however compiler bugs prevent this - instead pass three bool's to + // ct_imp and add an extra partial specialisation + // of ct_imp to handle the logic. (JM) + typedef typename boost::detail::ct_imp< + T, + ::boost::is_pointer::value, + ::boost::is_arithmetic::value, + ::boost::is_enum::value + >::param_type param_type; +}; + +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +#if BOOST_WORKAROUND( __BORLANDC__, < 0x5A0 ) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +template +struct call_traits< T * > +{ + typedef T * value_type; + typedef T * & reference; + typedef T * const & const_reference; + typedef T * const param_type; // hh removed const +}; +#endif +#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +template +struct call_traits +{ +private: + typedef T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; + +template +struct call_traits +{ +private: + typedef const T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; +#endif + +} + +#endif // BOOST_DETAIL_CALL_TRAITS_HPP diff --git a/boost/detail/container_fwd.hpp b/boost/detail/container_fwd.hpp new file mode 100644 index 00000000..04ce9727 --- /dev/null +++ b/boost/detail/container_fwd.hpp @@ -0,0 +1,157 @@ + +// Copyright 2005-2011 Daniel James. +// 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: if you change this include guard, you also need to change +// container_fwd_compile_fail.cpp +#if !defined(BOOST_DETAIL_CONTAINER_FWD_HPP) +#define BOOST_DETAIL_CONTAINER_FWD_HPP + +#if defined(_MSC_VER) && \ + !defined(BOOST_DETAIL_TEST_CONFIG_ONLY) +# pragma once +#endif + +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +// // +// Define BOOST_DETAIL_NO_CONTAINER_FWD if you don't want this header to // +// forward declare standard containers. // +// // +// BOOST_DETAIL_CONTAINER_FWD to make it foward declare containers even if it // +// normally doesn't. // +// // +// BOOST_DETAIL_NO_CONTAINER_FWD overrides BOOST_DETAIL_CONTAINER_FWD. // +// // +//////////////////////////////////////////////////////////////////////////////// + +#if !defined(BOOST_DETAIL_NO_CONTAINER_FWD) +# if defined(BOOST_DETAIL_CONTAINER_FWD) + // Force forward declarations. +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + // STLport +# define BOOST_DETAIL_NO_CONTAINER_FWD +# elif defined(__LIBCOMO__) + // Comeau STL: +# define BOOST_DETAIL_NO_CONTAINER_FWD +# elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) + // Rogue Wave library: +# define BOOST_DETAIL_NO_CONTAINER_FWD +# elif defined(_LIBCPP_VERSION) + // libc++ +# define BOOST_DETAIL_NO_CONTAINER_FWD +# elif defined(__GLIBCPP__) || defined(__GLIBCXX__) + // GNU libstdc++ 3 + // + // Disable forwarding for all recent versions, as the library has a + // versioned namespace mode, and I don't know how to detect it. +# if __GLIBCXX__ >= 20070513 \ + || defined(_GLIBCXX_DEBUG) \ + || defined(_GLIBCXX_PARALLEL) \ + || defined(_GLIBCXX_PROFILE) +# define BOOST_DETAIL_NO_CONTAINER_FWD +# else +# if defined(__GLIBCXX__) && __GLIBCXX__ >= 20040530 +# define BOOST_CONTAINER_FWD_COMPLEX_STRUCT +# endif +# endif +# elif defined(__STL_CONFIG_H) + // generic SGI STL + // + // Forward declaration seems to be okay, but it has a couple of odd + // implementations. +# define BOOST_CONTAINER_FWD_BAD_BITSET +# if !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) +# define BOOST_CONTAINER_FWD_BAD_DEQUE +# endif +# elif defined(__MSL_CPP__) + // MSL standard lib: +# define BOOST_DETAIL_NO_CONTAINER_FWD +# elif defined(__IBMCPP__) + // The default VACPP std lib, forward declaration seems to be fine. +# elif defined(MSIPL_COMPILE_H) + // Modena C++ standard library +# define BOOST_DETAIL_NO_CONTAINER_FWD +# elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) + // Dinkumware Library (this has to appear after any possible replacement + // libraries) +# else +# define BOOST_DETAIL_NO_CONTAINER_FWD +# endif +#endif + +#if !defined(BOOST_DETAIL_TEST_CONFIG_ONLY) + +#if defined(BOOST_DETAIL_NO_CONTAINER_FWD) && \ + !defined(BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD) + +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +#include + +#if defined(BOOST_CONTAINER_FWD_BAD_DEQUE) +#include +#endif + +#if defined(BOOST_CONTAINER_FWD_BAD_BITSET) +#include +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4099) // struct/class mismatch in fwd declarations +#endif + +namespace std +{ + template class allocator; + template class basic_string; + + template struct char_traits; + +#if defined(BOOST_CONTAINER_FWD_COMPLEX_STRUCT) + template struct complex; +#else + template class complex; +#endif + +#if !defined(BOOST_CONTAINER_FWD_BAD_DEQUE) + template class deque; +#endif + + template class list; + template class vector; + template class map; + template + class multimap; + template class set; + template class multiset; + +#if !defined(BOOST_CONTAINER_FWD_BAD_BITSET) + template class bitset; +#endif + template struct pair; +} + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif // BOOST_DETAIL_NO_CONTAINER_FWD && + // !defined(BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD) + +#endif // BOOST_DETAIL_TEST_CONFIG_ONLY + +#endif diff --git a/boost/detail/endian.hpp b/boost/detail/endian.hpp new file mode 100644 index 00000000..f576c26b --- /dev/null +++ b/boost/detail/endian.hpp @@ -0,0 +1,11 @@ +// Copyright 2013 Rene Rivera +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_ENDIAN_HPP +#define BOOST_DETAIL_ENDIAN_HPP + +// Use the Predef library for the detection of endianess. +#include + +#endif diff --git a/boost/detail/fenv.hpp b/boost/detail/fenv.hpp new file mode 100644 index 00000000..b268f5c1 --- /dev/null +++ b/boost/detail/fenv.hpp @@ -0,0 +1,101 @@ +/*============================================================================= + Copyright (c) 2010 Bryce Lelbach + + 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 + +#if defined(BOOST_NO_FENV_H) + #error This platform does not have a floating point environment +#endif + +#if !defined(BOOST_DETAIL_FENV_HPP) +#define BOOST_DETAIL_FENV_HPP + +/* If we're using clang + glibc, we have to get hacky. + * See http://llvm.org/bugs/show_bug.cgi?id=6907 */ +#if defined(__clang__) && (__clang_major__ < 3) && \ + defined(__GNU_LIBRARY__) && /* up to version 5 */ \ + defined(__GLIBC__) && /* version 6 + */ \ + !defined(_FENV_H) + #define _FENV_H + + #include + #include + + extern "C" { + extern int fegetexceptflag (fexcept_t*, int) __THROW; + extern int fesetexceptflag (__const fexcept_t*, int) __THROW; + extern int feclearexcept (int) __THROW; + extern int feraiseexcept (int) __THROW; + extern int fetestexcept (int) __THROW; + extern int fegetround (void) __THROW; + extern int fesetround (int) __THROW; + extern int fegetenv (fenv_t*) __THROW; + extern int fesetenv (__const fenv_t*) __THROW; + extern int feupdateenv (__const fenv_t*) __THROW; + extern int feholdexcept (fenv_t*) __THROW; + + #ifdef __USE_GNU + extern int feenableexcept (int) __THROW; + extern int fedisableexcept (int) __THROW; + extern int fegetexcept (void) __THROW; + #endif + } + + namespace std { namespace tr1 { + using ::fenv_t; + using ::fexcept_t; + using ::fegetexceptflag; + using ::fesetexceptflag; + using ::feclearexcept; + using ::feraiseexcept; + using ::fetestexcept; + using ::fegetround; + using ::fesetround; + using ::fegetenv; + using ::fesetenv; + using ::feupdateenv; + using ::feholdexcept; + } } + +#elif defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 + + // MinGW (32-bit) has a bug in mingw32/bits/c++config.h, it does not define _GLIBCXX_HAVE_FENV_H, + // which prevents the C fenv.h header contents to be included in the C++ wrapper header fenv.h. This is at least + // the case with gcc 4.8.1 packages tested so far, up to 4.8.1-4. Note that there is no issue with + // MinGW-w64. + // To work around the bug we avoid including the C++ wrapper header and include the C header directly + // and import all relevant symbols into std:: ourselves. + + #include <../include/fenv.h> + + namespace std { + using ::fenv_t; + using ::fexcept_t; + using ::fegetexceptflag; + using ::fesetexceptflag; + using ::feclearexcept; + using ::feraiseexcept; + using ::fetestexcept; + using ::fegetround; + using ::fesetround; + using ::fegetenv; + using ::fesetenv; + using ::feupdateenv; + using ::feholdexcept; + } + +#else /* if we're not using GNU's C stdlib, fenv.h should work with clang */ + + #if defined(__SUNPRO_CC) /* lol suncc */ + #include + #endif + + #include + +#endif + +#endif /* BOOST_DETAIL_FENV_HPP */ diff --git a/boost/detail/indirect_traits.hpp b/boost/detail/indirect_traits.hpp new file mode 100644 index 00000000..6294e40f --- /dev/null +++ b/boost/detail/indirect_traits.hpp @@ -0,0 +1,204 @@ +// 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 INDIRECT_TRAITS_DWA2002131_HPP +# define INDIRECT_TRAITS_DWA2002131_HPP +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include + +# include +# include +# include +# include +# include +# include + + +namespace boost { namespace detail { + +namespace indirect_traits { + +template +struct is_reference_to_const : mpl::false_ +{ +}; + +template +struct is_reference_to_const : mpl::true_ +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_const : mpl::true_ +{ +}; +# endif + +template +struct is_reference_to_function : mpl::false_ +{ +}; + +template +struct is_reference_to_function : is_function +{ +}; + +template +struct is_pointer_to_function : mpl::false_ +{ +}; + +// There's no such thing as a pointer-to-cv-function, so we don't need +// specializations for those +template +struct is_pointer_to_function : is_function +{ +}; + +template +struct is_reference_to_member_function_pointer_impl : mpl::false_ +{ +}; + +template +struct is_reference_to_member_function_pointer_impl + : is_member_function_pointer::type> +{ +}; + + +template +struct is_reference_to_member_function_pointer + : is_reference_to_member_function_pointer_impl +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) +}; + +template +struct is_reference_to_function_pointer_aux + : mpl::and_< + is_reference + , is_pointer_to_function< + typename remove_cv< + typename remove_reference::type + >::type + > + > +{ + // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those +}; + +template +struct is_reference_to_function_pointer + : mpl::if_< + is_reference_to_function + , mpl::false_ + , is_reference_to_function_pointer_aux + >::type +{ +}; + +template +struct is_reference_to_non_const + : mpl::and_< + is_reference + , mpl::not_< + is_reference_to_const + > + > +{ +}; + +template +struct is_reference_to_volatile : mpl::false_ +{ +}; + +template +struct is_reference_to_volatile : mpl::true_ +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_volatile : mpl::true_ +{ +}; +# endif + + +template +struct is_reference_to_pointer : mpl::false_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_class + : mpl::and_< + is_reference + , is_class< + typename remove_cv< + typename remove_reference::type + >::type + > + > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) +}; + +template +struct is_pointer_to_class + : mpl::and_< + is_pointer + , is_class< + typename remove_cv< + typename remove_pointer::type + >::type + > + > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T)) +}; + + +} + +using namespace indirect_traits; + +}} // namespace boost::python::detail + +#endif // INDIRECT_TRAITS_DWA2002131_HPP diff --git a/boost/detail/interlocked.hpp b/boost/detail/interlocked.hpp new file mode 100644 index 00000000..e20e3e46 --- /dev/null +++ b/boost/detail/interlocked.hpp @@ -0,0 +1,201 @@ +#ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED +#define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED + +// +// boost/detail/interlocked.hpp +// +// Copyright 2005 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 + +// MS compatible compilers support #pragma once +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#if defined( BOOST_USE_WINDOWS_H ) + +# include + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer + +#elif defined( BOOST_USE_INTRIN_H ) + +#include + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +# if defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__x86_64) + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer + +# else + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +# endif + +#elif defined(_WIN32_WCE) + +// under Windows CE we still have old-style Interlocked* functions + +extern "C" long __cdecl InterlockedIncrement( long volatile* ); +extern "C" long __cdecl InterlockedDecrement( long volatile* ); +extern "C" long __cdecl InterlockedCompareExchange( long volatile*, long, long ); +extern "C" long __cdecl InterlockedExchange( long volatile*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long volatile*, long ); + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long*)(dest),(long)(exchange))) + +#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) + +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1400 + +#include + +#else + +# if defined( __CLRCALL_PURE_OR_CDECL ) +# define BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL __CLRCALL_PURE_OR_CDECL +# else +# define BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL __cdecl +# endif + +extern "C" long BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); +extern "C" long BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); +extern "C" long BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); +extern "C" long BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); + +# undef BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL + +# if defined( BOOST_MSVC ) && BOOST_MSVC >= 1310 +# pragma intrinsic( _InterlockedIncrement ) +# pragma intrinsic( _InterlockedDecrement ) +# pragma intrinsic( _InterlockedCompareExchange ) +# pragma intrinsic( _InterlockedExchange ) +# pragma intrinsic( _InterlockedExchangeAdd ) +# endif + +#endif + +# if defined(_M_IA64) || defined(_M_AMD64) + +extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer + +# else + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +# endif + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. +#elif defined(__MINGW64_VERSION_MAJOR) + +// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. +#include + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd +# if defined(__x86_64__) || defined(__x86_64) +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer +# else +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) +# endif + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport) + +namespace boost +{ + +namespace detail +{ + +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedIncrement( long volatile * ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedDecrement( long volatile * ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd( long volatile *, long ); + +# if defined(_M_IA64) || defined(_M_AMD64) +extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); +# endif + +} // namespace detail + +} // namespace boost + +# define BOOST_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd + +# if defined(_M_IA64) || defined(_M_AMD64) +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::boost::detail::InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER ::boost::detail::InterlockedExchangePointer +# else +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) +# endif + +#else + +# error "Interlocked intrinsics not available" + +#endif + +#endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED diff --git a/boost/detail/is_incrementable.hpp b/boost/detail/is_incrementable.hpp new file mode 100644 index 00000000..5ebf4b7a --- /dev/null +++ b/boost/detail/is_incrementable.hpp @@ -0,0 +1,125 @@ +// Copyright David Abrahams 2004. 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 IS_INCREMENTABLE_DWA200415_HPP +# define IS_INCREMENTABLE_DWA200415_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace detail { + +// is_incrementable metafunction +// +// Requires: Given x of type T&, if the expression ++x is well-formed +// it must have complete type; otherwise, it must neither be ambiguous +// nor violate access. + +// This namespace ensures that ADL doesn't mess things up. +namespace is_incrementable_ +{ + // a type returned from operator++ when no increment is found in the + // type's own namespace + struct tag {}; + + // any soaks up implicit conversions and makes the following + // operator++ less-preferred than any other such operator that + // might be found via ADL. + struct any { template any(T const&); }; + + // This is a last-resort operator++ for when none other is found +# if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 + +} + +namespace is_incrementable_2 +{ + is_incrementable_::tag operator++(is_incrementable_::any const&); + is_incrementable_::tag operator++(is_incrementable_::any const&,int); +} +using namespace is_incrementable_2; + +namespace is_incrementable_ +{ + +# else + + tag operator++(any const&); + tag operator++(any const&,int); + +# endif + +# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) +# define BOOST_comma(a,b) (a) +# else + // In case an operator++ is found that returns void, we'll use ++x,0 + tag operator,(tag,int); +# define BOOST_comma(a,b) (a,b) +# endif + +# if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4913) // Warning about operator, +# endif + + // two check overloads help us identify which operator++ was picked + char (& check_(tag) )[2]; + + template + char check_(T const&); + + + template + struct impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check_(BOOST_comma(++x,0))) == 1 + ); + }; + + template + struct postfix_impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check_(BOOST_comma(x++,0))) == 1 + ); + }; + +# if defined(BOOST_MSVC) +# pragma warning(pop) +# endif + +} + +# undef BOOST_comma + +template +struct is_incrementable : + public boost::integral_constant::value> +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_incrementable,(T)) +}; + +template +struct is_postfix_incrementable : + public boost::integral_constant::value> +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_postfix_incrementable,(T)) +}; + +} // namespace detail + +} // namespace boost + +# include + +#endif // IS_INCREMENTABLE_DWA200415_HPP diff --git a/boost/detail/iterator.hpp b/boost/detail/iterator.hpp new file mode 100644 index 00000000..2498ef44 --- /dev/null +++ b/boost/detail/iterator.hpp @@ -0,0 +1,39 @@ +// (C) 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 ITERATOR_DWA122600_HPP_ +#define ITERATOR_DWA122600_HPP_ + +// This header is obsolete and will be deprecated. + +#include +#if defined(__SUNPRO_CC) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) +#include +#endif + +namespace boost +{ + +namespace detail +{ + +using std::iterator_traits; +using std::distance; + +#if defined(__SUNPRO_CC) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) +// std::distance from stlport with Oracle compiler 12.4 and 12.5 fails to deduce template parameters +// when one of the arguments is an array and the other one is a pointer. +template< typename T, std::size_t N > +inline typename std::iterator_traits< T* >::difference_type distance(T (&left)[N], T* right) +{ + return std::distance(static_cast< T* >(left), right); +} +#endif + +} // namespace detail + +} // namespace boost + +#endif // ITERATOR_DWA122600_HPP_ diff --git a/boost/detail/lcast_precision.hpp b/boost/detail/lcast_precision.hpp new file mode 100644 index 00000000..2be88fd8 --- /dev/null +++ b/boost/detail/lcast_precision.hpp @@ -0,0 +1,185 @@ +// Copyright Alexander Nasonov & Paul A. Bristow 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) + +#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED +#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + +#include +#include +#include + +#include +#include + +#ifndef BOOST_NO_IS_ABSTRACT +// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL +#include +#include +#endif + +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \ + (defined(BOOST_MSVC) && (BOOST_MSVC<1310)) + +#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#endif + +#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#include +#else +#include +#endif + +namespace boost { namespace detail { + +class lcast_abstract_stub {}; + +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +// Calculate an argument to pass to std::ios_base::precision from +// lexical_cast. See alternative implementation for broken standard +// libraries in lcast_get_precision below. Keep them in sync, please. +template +struct lcast_precision +{ +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_abstract + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + BOOST_STATIC_CONSTANT(bool, use_default_precision = + !limits::is_specialized || limits::is_exact + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_bin = + !use_default_precision && + limits::radix == 2 && limits::digits > 0 + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_dec = + !use_default_precision && + limits::radix == 10 && limits::digits10 > 0 + ); + + BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max = + boost::integer_traits::const_max + ); + + BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U); + + BOOST_STATIC_ASSERT(!is_specialized_dec || + precision_dec <= streamsize_max + 0UL + ); + + BOOST_STATIC_CONSTANT(unsigned long, precision_bin = + 2UL + limits::digits * 30103UL / 100000UL + ); + + BOOST_STATIC_ASSERT(!is_specialized_bin || + (limits::digits + 0UL < ULONG_MAX / 30103UL && + precision_bin > limits::digits10 + 0UL && + precision_bin <= streamsize_max + 0UL) + ); + + BOOST_STATIC_CONSTANT(std::streamsize, value = + is_specialized_bin ? precision_bin + : is_specialized_dec ? precision_dec : 6 + ); +}; +#endif + +template +inline std::streamsize lcast_get_precision(T* = 0) +{ +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION + return lcast_precision::value; +#else // Follow lcast_precision algorithm at run-time: + +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_abstract + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + bool const use_default_precision = + !limits::is_specialized || limits::is_exact; + + if(!use_default_precision) + { // Includes all built-in floating-point types, float, double ... + // and UDT types for which digits (significand bits) is defined (not zero) + + bool const is_specialized_bin = + limits::radix == 2 && limits::digits > 0; + bool const is_specialized_dec = + limits::radix == 10 && limits::digits10 > 0; + std::streamsize const streamsize_max = + (boost::integer_traits::max)(); + (void)streamsize_max; + + if(is_specialized_bin) + { // Floating-point types with + // limits::digits defined by the specialization. + + unsigned long const digits = limits::digits; + unsigned long const precision = 2UL + digits * 30103UL / 100000UL; + // unsigned long is selected because it is at least 32-bits + // and thus ULONG_MAX / 30103UL is big enough for all types. + BOOST_ASSERT( + digits < ULONG_MAX / 30103UL && + precision > limits::digits10 + 0UL && + precision <= streamsize_max + 0UL + ); + return precision; + } + else if(is_specialized_dec) + { // Decimal Floating-point type, most likely a User Defined Type + // rather than a real floating-point hardware type. + unsigned int const precision = limits::digits10 + 1U; + BOOST_ASSERT(precision <= streamsize_max + 0UL); + return precision; + } + } + + // Integral type (for which precision has no effect) + // or type T for which limits is NOT specialized, + // so assume stream precision remains the default 6 decimal digits. + // Warning: if your User-defined Floating-point type T is NOT specialized, + // then you may lose accuracy by only using 6 decimal digits. + // To avoid this, you need to specialize T with either + // radix == 2 and digits == the number of significand bits, + // OR + // radix = 10 and digits10 == the number of decimal digits. + + return 6; +#endif +} + +template +inline void lcast_set_precision(std::ios_base& stream, T*) +{ + stream.precision(lcast_get_precision()); +} + +template +inline void lcast_set_precision(std::ios_base& stream, Source*, Target*) +{ + std::streamsize const s = lcast_get_precision(static_cast(0)); + std::streamsize const t = lcast_get_precision(static_cast(0)); + stream.precision(s > t ? s : t); +} + +}} + +#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + diff --git a/boost/detail/lightweight_main.hpp b/boost/detail/lightweight_main.hpp new file mode 100644 index 00000000..17053097 --- /dev/null +++ b/boost/detail/lightweight_main.hpp @@ -0,0 +1,36 @@ +// boost/detail/lightweight_main.hpp -------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +//--------------------------------------------------------------------------------------// +// // +// exception reporting main() that calls cpp_main() // +// // +//--------------------------------------------------------------------------------------// + +int cpp_main(int argc, char* argv[]); + +int main(int argc, char* argv[]) +{ + try + { + return cpp_main(argc, argv); + } + + catch (const std::exception& ex) + { + std::cout + << "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n" + << "\n****************************** std::exception *****************************\n" + << ex.what() + << "\n***************************************************************************\n" + << std::endl; + } + return 1; +} diff --git a/boost/detail/lightweight_test.hpp b/boost/detail/lightweight_test.hpp new file mode 100644 index 00000000..9fece8ab --- /dev/null +++ b/boost/detail/lightweight_test.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014 Glen Fernandes + * + * 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_DETAIL_LIGHTWEIGHT_TEST_HPP +#define BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP + +// The header file at this path is deprecated; +// use boost/core/lightweight_test.hpp instead. + +#include + +#endif diff --git a/boost/detail/lightweight_test_report.hpp b/boost/detail/lightweight_test_report.hpp new file mode 100644 index 00000000..1511ba9d --- /dev/null +++ b/boost/detail/lightweight_test_report.hpp @@ -0,0 +1,56 @@ +// boost/detail/lightweight_test_reporter.hpp ----------------------------------------// + +// Copyright Beman Dawes 2014 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//--------------------------------------------------------------------------------------// +// // +// Configuration reporting cpp_main() // +// // +// Displays configuration information, then returns test_main(argc, argv), which // +// must be supplied by the user. // +// // +// Note: cpp_main(argc, argv) is called from a try block in main(), which is // +// supplied by as is a catch block that reports // +// std::exception what(). // +// // +//--------------------------------------------------------------------------------------// + +#include +#include +#include +#include +#include + +int test_main(int argc, char* argv[]); + +int cpp_main(int argc, char* argv[]) +{ + std::cout << BOOST_COMPILER +#ifdef __GNUC__ + << ", __GXX_EXPERIMENTAL_CXX0X__ " +# ifdef __GXX_EXPERIMENTAL_CXX0X__ + "defined" +# else + "not defined" +# endif +#endif + << "\n" + << BOOST_STDLIB << "\n" + << BOOST_PLATFORM << "\n" + << "Boost version " << BOOST_VERSION / 100000 << '.' + << BOOST_VERSION / 100 % 1000 << '.' << BOOST_VERSION % 100 << "\n"; + + std::cout << "Command line: "; + for (int a = 0; a < argc; ++a) + { + std::cout << argv[a]; + if (a != argc - 1) + std::cout << ' '; + } + std::cout << std::endl; + + return test_main(argc, argv); +} \ No newline at end of file diff --git a/boost/detail/no_exceptions_support.hpp b/boost/detail/no_exceptions_support.hpp new file mode 100644 index 00000000..7d17454a --- /dev/null +++ b/boost/detail/no_exceptions_support.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014 Glen Fernandes + * + * 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_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP +#define BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP + +// The header file at this path is deprecated; +// use boost/core/no_exceptions_support.hpp instead. + +#include + +#endif diff --git a/boost/detail/reference_content.hpp b/boost/detail/reference_content.hpp new file mode 100644 index 00000000..36b80d24 --- /dev/null +++ b/boost/detail/reference_content.hpp @@ -0,0 +1,120 @@ +//----------------------------------------------------------------------------- +// boost detail/reference_content.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// 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_DETAIL_REFERENCE_CONTENT_HPP +#define BOOST_DETAIL_REFERENCE_CONTENT_HPP + +#include "boost/config.hpp" + +# include "boost/mpl/bool.hpp" +# include "boost/type_traits/has_nothrow_copy.hpp" + +#include "boost/mpl/void.hpp" + +namespace boost { + +namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class template reference_content +// +// Non-Assignable wrapper for references. +// +template +class reference_content +{ +private: // representation + + RefT content_; + +public: // structors + + ~reference_content() + { + } + + reference_content(RefT r) + : content_( r ) + { + } + + reference_content(const reference_content& operand) + : content_( operand.content_ ) + { + } + +private: // non-Assignable + + reference_content& operator=(const reference_content&); + +public: // queries + + RefT get() const + { + return content_; + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction make_reference_content +// +// Wraps with reference_content if specified type is reference. +// + +template struct make_reference_content; + + +template +struct make_reference_content +{ + typedef T type; +}; + +template +struct make_reference_content< T& > +{ + typedef reference_content type; +}; + + +template <> +struct make_reference_content< mpl::void_ > +{ + template + struct apply + : make_reference_content + { + }; + + typedef mpl::void_ type; +}; + +} // namespace detail + +/////////////////////////////////////////////////////////////////////////////// +// reference_content type traits specializations +// + + +template +struct has_nothrow_copy< + ::boost::detail::reference_content< T& > + > + : mpl::true_ +{ +}; + + +} // namespace boost + +#endif // BOOST_DETAIL_REFERENCE_CONTENT_HPP diff --git a/boost/detail/scoped_enum_emulation.hpp b/boost/detail/scoped_enum_emulation.hpp new file mode 100644 index 00000000..1c7bc23c --- /dev/null +++ b/boost/detail/scoped_enum_emulation.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014 Andrey Semashev + * + * 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_DETAIL_SCOPED_ENUM_EMULATION_HPP +#define BOOST_DETAIL_SCOPED_ENUM_EMULATION_HPP + +// The header file at this path is deprecated; +// use boost/core/scoped_enum.hpp instead. + +#include + +#endif diff --git a/boost/detail/sp_typeinfo.hpp b/boost/detail/sp_typeinfo.hpp new file mode 100644 index 00000000..4e4de55b --- /dev/null +++ b/boost/detail/sp_typeinfo.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED +#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_typeinfo.hpp +// +// Deprecated, please use boost/core/typeinfo.hpp +// +// Copyright 2007 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 detail +{ + +typedef boost::core::typeinfo sp_typeinfo; + +} // namespace detail + +} // namespace boost + +#define BOOST_SP_TYPEID(T) BOOST_CORE_TYPEID(T) + +#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED diff --git a/boost/detail/utf8_codecvt_facet.hpp b/boost/detail/utf8_codecvt_facet.hpp new file mode 100644 index 00000000..12ae19ba --- /dev/null +++ b/boost/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,219 @@ +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_UTF8_CODECVT_FACET_HPP +#define BOOST_UTF8_CODECVT_FACET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// utf8_codecvt_facet.hpp + +// This header defines class utf8_codecvt_facet, derived from +// std::codecvt, which can be used to convert utf8 data in +// files into wchar_t strings in the application. +// +// The header is NOT STANDALONE, and is not to be included by the USER. +// There are at least two libraries which want to use this functionality, and +// we want to avoid code duplication. It would be possible to create utf8 +// library, but: +// - this requires review process first +// - in the case, when linking the a library which uses utf8 +// (say 'program_options'), user should also link to the utf8 library. +// This seems inconvenient, and asking a user to link to an unrevieved +// library is strange. +// Until the above points are fixed, a library which wants to use utf8 must: +// - include this header in one of it's headers or sources +// - include the corresponding boost/detail/utf8_codecvt_facet.ipp file in one +// of its sources +// - before including either file, the library must define +// - BOOST_UTF8_BEGIN_NAMESPACE to the namespace declaration that must be used +// - BOOST_UTF8_END_NAMESPACE to the code to close the previous namespace +// declaration. +// - BOOST_UTF8_DECL -- to the code which must be used for all 'exportable' +// symbols. +// +// For example, program_options library might contain: +// #define BOOST_UTF8_BEGIN_NAMESPACE +// namespace boost { namespace program_options { +// #define BOOST_UTF8_END_NAMESPACE }} +// #define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL +// #include +// +// Essentially, each library will have its own copy of utf8 code, in +// different namespaces. + +// Note:(Robert Ramey). I have made the following alterations in the original +// code. +// a) Rendered utf8_codecvt with using templates +// b) Move longer functions outside class definition to prevent inlining +// and make code smaller +// c) added on a derived class to permit translation to/from current +// locale to utf8 + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters +// +// utf8_codecvt_facet +// This is an implementation of a std::codecvt facet for translating +// from UTF-8 externally to UCS-4. Note that this is not tied to +// any specific types in order to allow customization on platforms +// where wchar_t is not big enough. +// +// NOTES: The current implementation jumps through some unpleasant hoops in +// order to deal with signed character types. As a std::codecvt_base::result, +// it is necessary for the ExternType to be convertible to unsigned char. +// I chose not to tie the extern_type explicitly to char. But if any combination +// of types other than is used, then std::codecvt must be +// specialized on those types for this to work. + +#include +#include // for mbstate_t +#include // for std::size_t + +#include +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std { + using ::mbstate_t; + using ::size_t; +} +#endif + +// maximum lenght of a multibyte string +#define MB_LENGTH_MAX 8 + +BOOST_UTF8_BEGIN_NAMESPACE + +//----------------------------------------------------------------------------// +// // +// utf8_codecvt_facet // +// // +// See utf8_codecvt_facet.ipp for the implementation. // +//----------------------------------------------------------------------------// + +#ifndef BOOST_UTF8_DECL +#define BOOST_UTF8_DECL +#endif + +struct BOOST_UTF8_DECL utf8_codecvt_facet : + public std::codecvt +{ +public: + explicit utf8_codecvt_facet(std::size_t no_locale_manage=0); + virtual ~utf8_codecvt_facet(){} +protected: + virtual std::codecvt_base::result do_in( + std::mbstate_t& state, + const char * from, + const char * from_end, + const char * & from_next, + wchar_t * to, + wchar_t * to_end, + wchar_t*& to_next + ) const; + + virtual std::codecvt_base::result do_out( + std::mbstate_t & state, + const wchar_t * from, + const wchar_t * from_end, + const wchar_t* & from_next, + char * to, + char * to_end, + char * & to_next + ) const; + + bool invalid_continuing_octet(unsigned char octet_1) const { + return (octet_1 < 0x80|| 0xbf< octet_1); + } + + bool invalid_leading_octet(unsigned char octet_1) const { + return (0x7f < octet_1 && octet_1 < 0xc0) || + (octet_1 > 0xfd); + } + + // continuing octets = octets except for the leading octet + static unsigned int get_cont_octet_count(unsigned char lead_octet) { + return get_octet_count(lead_octet) - 1; + } + + static unsigned int get_octet_count(unsigned char lead_octet); + + // How many "continuing octets" will be needed for this word + // == total octets - 1. + int get_cont_octet_out_count(wchar_t word) const ; + + virtual bool do_always_noconv() const BOOST_NOEXCEPT_OR_NOTHROW { + return false; + } + + // UTF-8 isn't really stateful since we rewind on partial conversions + virtual std::codecvt_base::result do_unshift( + std::mbstate_t&, + char * from, + char * /*to*/, + char * & next + ) const { + next = from; + return ok; + } + + virtual int do_encoding() const BOOST_NOEXCEPT_OR_NOTHROW { + const int variable_byte_external_encoding=0; + return variable_byte_external_encoding; + } + + // How many char objects can I process to get <= max_limit + // wchar_t objects? + virtual int do_length( + std::mbstate_t &, + const char * from, + const char * from_end, + std::size_t max_limit + ) const +#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + throw() +#endif + ; + + // Nonstandard override + virtual int do_length( + const std::mbstate_t & s, + const char * from, + const char * from_end, + std::size_t max_limit + ) const +#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + throw() +#endif + { + return do_length( + const_cast(s), + from, + from_end, + max_limit + ); + } + + // Largest possible value do_length(state,from,from_end,1) could return. + virtual int do_max_length() const BOOST_NOEXCEPT_OR_NOTHROW { + return 6; // largest UTF-8 encoding of a UCS-4 character + } +}; + +BOOST_UTF8_END_NAMESPACE + +#endif // BOOST_UTF8_CODECVT_FACET_HPP diff --git a/boost/detail/utf8_codecvt_facet.ipp b/boost/detail/utf8_codecvt_facet.ipp new file mode 100644 index 00000000..d60f9063 --- /dev/null +++ b/boost/detail/utf8_codecvt_facet.ipp @@ -0,0 +1,289 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// utf8_codecvt_facet.ipp + +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// 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) + +// Please see the comments in to +// learn how this file should be used. + +#include + +#include // for multi-byte converson routines +#include + +#include +#include + +// If we don't have wstring, then Unicode support +// is not available anyway, so we don't need to even +// compiler this file. This also fixes the problem +// with mingw, which can compile this file, but will +// generate link error when building DLL. +#ifndef BOOST_NO_STD_WSTRING + +BOOST_UTF8_BEGIN_NAMESPACE + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation for wchar_t + +utf8_codecvt_facet::utf8_codecvt_facet( + std::size_t no_locale_manage +) : + std::codecvt(no_locale_manage) +{} + +// Translate incoming UTF-8 into UCS-4 +std::codecvt_base::result utf8_codecvt_facet::do_in( + std::mbstate_t& /*state*/, + const char * from, + const char * from_end, + const char * & from_next, + wchar_t * to, + wchar_t * to_end, + wchar_t * & to_next +) const { + // Basic algorithm: The first octet determines how many + // octets total make up the UCS-4 character. The remaining + // "continuing octets" all begin with "10". To convert, subtract + // the amount that specifies the number of octets from the first + // octet. Subtract 0x80 (1000 0000) from each continuing octet, + // then mash the whole lot together. Note that each continuing + // octet only uses 6 bits as unique values, so only shift by + // multiples of 6 to combine. + while (from != from_end && to != to_end) { + + // Error checking on the first octet + if (invalid_leading_octet(*from)){ + from_next = from; + to_next = to; + return std::codecvt_base::error; + } + + // The first octet is adjusted by a value dependent upon + // the number of "continuing octets" encoding the character + const int cont_octet_count = get_cont_octet_count(*from); + const wchar_t octet1_modifier_table[] = { + 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc + }; + + // The unsigned char conversion is necessary in case char is + // signed (I learned this the hard way) + wchar_t ucs_result = + (unsigned char)(*from++) - octet1_modifier_table[cont_octet_count]; + + // Invariants : + // 1) At the start of the loop, 'i' continuing characters have been + // processed + // 2) *from points to the next continuing character to be processed. + int i = 0; + while(i != cont_octet_count && from != from_end) { + + // Error checking on continuing characters + if (invalid_continuing_octet(*from)) { + from_next = from; + to_next = to; + return std::codecvt_base::error; + } + + ucs_result *= (1 << 6); + + // each continuing character has an extra (10xxxxxx)b attached to + // it that must be removed. + ucs_result += (unsigned char)(*from++) - 0x80; + ++i; + } + + // If the buffer ends with an incomplete unicode character... + if (from == from_end && i != cont_octet_count) { + // rewind "from" to before the current character translation + from_next = from - (i+1); + to_next = to; + return std::codecvt_base::partial; + } + *to++ = ucs_result; + } + from_next = from; + to_next = to; + + // Were we done converting or did we run out of destination space? + if(from == from_end) return std::codecvt_base::ok; + else return std::codecvt_base::partial; +} + +std::codecvt_base::result utf8_codecvt_facet::do_out( + std::mbstate_t& /*state*/, + const wchar_t * from, + const wchar_t * from_end, + const wchar_t * & from_next, + char * to, + char * to_end, + char * & to_next +) const +{ + // RG - consider merging this table with the other one + const wchar_t octet1_modifier_table[] = { + 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc + }; + + wchar_t max_wchar = (std::numeric_limits::max)(); + while (from != from_end && to != to_end) { + + // Check for invalid UCS-4 character + if (*from > max_wchar) { + from_next = from; + to_next = to; + return std::codecvt_base::error; + } + + int cont_octet_count = get_cont_octet_out_count(*from); + + // RG - comment this formula better + int shift_exponent = (cont_octet_count) * 6; + + // Process the first character + *to++ = static_cast(octet1_modifier_table[cont_octet_count] + + (unsigned char)(*from / (1 << shift_exponent))); + + // Process the continuation characters + // Invariants: At the start of the loop: + // 1) 'i' continuing octets have been generated + // 2) '*to' points to the next location to place an octet + // 3) shift_exponent is 6 more than needed for the next octet + int i = 0; + while (i != cont_octet_count && to != to_end) { + shift_exponent -= 6; + *to++ = static_cast(0x80 + ((*from / (1 << shift_exponent)) % (1 << 6))); + ++i; + } + // If we filled up the out buffer before encoding the character + if(to == to_end && i != cont_octet_count) { + from_next = from; + to_next = to - (i+1); + return std::codecvt_base::partial; + } + ++from; + } + from_next = from; + to_next = to; + // Were we done or did we run out of destination space + if(from == from_end) return std::codecvt_base::ok; + else return std::codecvt_base::partial; +} + +// How many char objects can I process to get <= max_limit +// wchar_t objects? +int utf8_codecvt_facet::do_length( + std::mbstate_t &, + const char * from, + const char * from_end, + std::size_t max_limit +) const +#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + throw() +#endif +{ + // RG - this code is confusing! I need a better way to express it. + // and test cases. + + // Invariants: + // 1) last_octet_count has the size of the last measured character + // 2) char_count holds the number of characters shown to fit + // within the bounds so far (no greater than max_limit) + // 3) from_next points to the octet 'last_octet_count' before the + // last measured character. + int last_octet_count=0; + std::size_t char_count = 0; + const char* from_next = from; + // Use "<" because the buffer may represent incomplete characters + while (from_next+last_octet_count <= from_end && char_count <= max_limit) { + from_next += last_octet_count; + last_octet_count = (get_octet_count(*from_next)); + ++char_count; + } + return static_cast(from_next-from); +} + +unsigned int utf8_codecvt_facet::get_octet_count( + unsigned char lead_octet +){ + // if the 0-bit (MSB) is 0, then 1 character + if (lead_octet <= 0x7f) return 1; + + // Otherwise the count number of consecutive 1 bits starting at MSB +// assert(0xc0 <= lead_octet && lead_octet <= 0xfd); + + if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2; + else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3; + else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4; + else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5; + else return 6; +} + +namespace detail { + +template +int get_cont_octet_out_count_impl(wchar_t word){ + if (word < 0x80) { + return 0; + } + if (word < 0x800) { + return 1; + } + return 2; +} + +template<> +int get_cont_octet_out_count_impl<4>(wchar_t word){ + if (word < 0x80) { + return 0; + } + if (word < 0x800) { + return 1; + } + + // Note that the following code will generate warnings on some platforms + // where wchar_t is defined as UCS2. The warnings are superfluous as the + // specialization is never instantitiated with such compilers, but this + // can cause problems if warnings are being treated as errors, so we guard + // against that. Including as we do + // should be enough to get WCHAR_MAX defined. +#if !defined(WCHAR_MAX) +# error WCHAR_MAX not defined! +#endif + // cope with VC++ 7.1 or earlier having invalid WCHAR_MAX +#if defined(_MSC_VER) && _MSC_VER <= 1310 // 7.1 or earlier + return 2; +#elif WCHAR_MAX > 0x10000 + + if (word < 0x10000) { + return 2; + } + if (word < 0x200000) { + return 3; + } + if (word < 0x4000000) { + return 4; + } + return 5; + +#else + return 2; +#endif +} + +} // namespace detail + +// How many "continuing octets" will be needed for this word +// == total octets - 1. +int utf8_codecvt_facet::get_cont_octet_out_count( + wchar_t word +) const { + return detail::get_cont_octet_out_count_impl(word); +} +BOOST_UTF8_END_NAMESPACE + +#endif diff --git a/boost/detail/winapi/detail/deprecated_namespace.hpp b/boost/detail/winapi/detail/deprecated_namespace.hpp new file mode 100644 index 00000000..40c91527 --- /dev/null +++ b/boost/detail/winapi/detail/deprecated_namespace.hpp @@ -0,0 +1,28 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, it provides the deprecated namespace for backward compatibility. + */ + +#ifndef BOOST_DETAIL_WINAPI_DETAIL_DEPRECATED_NAMESPACE_HPP_INCLUDED_ +#define BOOST_DETAIL_WINAPI_DETAIL_DEPRECATED_NAMESPACE_HPP_INCLUDED_ + +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace winapi {} +namespace detail { +namespace winapi { +using namespace boost::winapi; +} // namespace winapi +} // namespace detail +} // namespace boost + +#endif // BOOST_DETAIL_WINAPI_DETAIL_DEPRECATED_NAMESPACE_HPP_INCLUDED_ diff --git a/boost/detail/winapi/get_current_process.hpp b/boost/detail/winapi/get_current_process.hpp new file mode 100644 index 00000000..b6a79150 --- /dev/null +++ b/boost/detail/winapi/get_current_process.hpp @@ -0,0 +1,20 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, use boost/winapi/get_current_process.hpp instead. + */ + +#ifndef BOOST_DETAIL_WINAPI_GET_CURRENT_PROCESS_HPP +#define BOOST_DETAIL_WINAPI_GET_CURRENT_PROCESS_HPP + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_DETAIL_WINAPI_GET_CURRENT_PROCESS_HPP diff --git a/boost/detail/winapi/get_current_thread.hpp b/boost/detail/winapi/get_current_thread.hpp new file mode 100644 index 00000000..f9a27c3e --- /dev/null +++ b/boost/detail/winapi/get_current_thread.hpp @@ -0,0 +1,20 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, use boost/winapi/get_current_thread.hpp instead. + */ + +#ifndef BOOST_DETAIL_WINAPI_GET_CURRENT_THREAD_HPP +#define BOOST_DETAIL_WINAPI_GET_CURRENT_THREAD_HPP + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_DETAIL_WINAPI_GET_CURRENT_THREAD_HPP diff --git a/boost/detail/winapi/get_last_error.hpp b/boost/detail/winapi/get_last_error.hpp new file mode 100644 index 00000000..f76a008e --- /dev/null +++ b/boost/detail/winapi/get_last_error.hpp @@ -0,0 +1,20 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, use boost/winapi/get_last_error.hpp instead. + */ + +#ifndef BOOST_DETAIL_WINAPI_GET_LAST_ERROR_HPP +#define BOOST_DETAIL_WINAPI_GET_LAST_ERROR_HPP + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_DETAIL_WINAPI_GET_LAST_ERROR_HPP diff --git a/boost/detail/winapi/get_process_times.hpp b/boost/detail/winapi/get_process_times.hpp new file mode 100644 index 00000000..6babb391 --- /dev/null +++ b/boost/detail/winapi/get_process_times.hpp @@ -0,0 +1,20 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, use boost/winapi/get_process_times.hpp instead. + */ + +#ifndef BOOST_DETAIL_WINAPI_GET_PROCESS_TIMES_HPP +#define BOOST_DETAIL_WINAPI_GET_PROCESS_TIMES_HPP + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_DETAIL_WINAPI_GET_PROCESS_TIMES_HPP diff --git a/boost/detail/winapi/get_thread_times.hpp b/boost/detail/winapi/get_thread_times.hpp new file mode 100644 index 00000000..96f1fac8 --- /dev/null +++ b/boost/detail/winapi/get_thread_times.hpp @@ -0,0 +1,20 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, use boost/winapi/get_thread_times.hpp instead. + */ + +#ifndef BOOST_DETAIL_WINAPI_GET_THREAD_TIMES_HPP +#define BOOST_DETAIL_WINAPI_GET_THREAD_TIMES_HPP + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_DETAIL_WINAPI_GET_THREAD_TIMES_HPP diff --git a/boost/detail/winapi/time.hpp b/boost/detail/winapi/time.hpp new file mode 100644 index 00000000..a6d728a5 --- /dev/null +++ b/boost/detail/winapi/time.hpp @@ -0,0 +1,20 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, use boost/winapi/time.hpp instead. + */ + +#ifndef BOOST_DETAIL_WINAPI_TIME_HPP_ +#define BOOST_DETAIL_WINAPI_TIME_HPP_ + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_DETAIL_WINAPI_TIME_HPP_ diff --git a/boost/detail/winapi/timers.hpp b/boost/detail/winapi/timers.hpp new file mode 100644 index 00000000..4b874e24 --- /dev/null +++ b/boost/detail/winapi/timers.hpp @@ -0,0 +1,20 @@ +/* + * Copyright 2017 Andrey Semashev + * + * Distributed under the Boost Software License, Version 1.0. + * See http://www.boost.org/LICENSE_1_0.txt + * + * This header is deprecated, use boost/winapi/timers.hpp instead. + */ + +#ifndef BOOST_DETAIL_WINAPI_TIMERS_HPP +#define BOOST_DETAIL_WINAPI_TIMERS_HPP + +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_DETAIL_WINAPI_TIMERS_HPP diff --git a/boost/detail/workaround.hpp b/boost/detail/workaround.hpp new file mode 100644 index 00000000..fb961158 --- /dev/null +++ b/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 WORKAROUND_DWA2002126_HPP +#define WORKAROUND_DWA2002126_HPP + +#include + +#endif // WORKAROUND_DWA2002126_HPP diff --git a/boost/enable_shared_from_this.hpp b/boost/enable_shared_from_this.hpp new file mode 100644 index 00000000..18b938d5 --- /dev/null +++ b/boost/enable_shared_from_this.hpp @@ -0,0 +1,18 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED + +// +// enable_shared_from_this.hpp +// +// Copyright (c) 2002 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 +// +// See http://www.boost.org/libs/smart_ptr/ for documentation. +// + +#include + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED diff --git a/boost/exception/current_exception_cast.hpp b/boost/exception/current_exception_cast.hpp new file mode 100644 index 00000000..5d81f00b --- /dev/null +++ b/boost/exception/current_exception_cast.hpp @@ -0,0 +1,43 @@ +//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 UUID_7E83C166200811DE885E826156D89593 +#define UUID_7E83C166200811DE885E826156D89593 +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + template + inline + E * + current_exception_cast() + { + try + { + throw; + } + catch( + E & e ) + { + return &e; + } + catch( + ...) + { + return 0; + } + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/clone_current_exception.hpp b/boost/exception/detail/clone_current_exception.hpp new file mode 100644 index 00000000..6fc13747 --- /dev/null +++ b/boost/exception/detail/clone_current_exception.hpp @@ -0,0 +1,56 @@ +//Copyright (c) 2006-2013 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 UUID_81522C0EB56511DFAB613DB0DFD72085 +#define UUID_81522C0EB56511DFAB613DB0DFD72085 +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#ifdef BOOST_NO_EXCEPTIONS +# error This header requires exception handling to be enabled. +#endif + +namespace +boost + { + namespace + exception_detail + { + class clone_base; + +#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR + int clone_current_exception_non_intrusive( clone_base const * & cloned ); +#endif + + namespace + clone_current_exception_result + { + int const success=0; + int const bad_alloc=1; + int const bad_exception=2; + int const not_supported=3; + } + + inline + int + clone_current_exception( clone_base const * & cloned ) + { +#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR + return clone_current_exception_non_intrusive(cloned); +#else + return clone_current_exception_result::not_supported; +#endif + } + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/error_info_impl.hpp b/boost/exception/detail/error_info_impl.hpp new file mode 100644 index 00000000..6c48d61a --- /dev/null +++ b/boost/exception/detail/error_info_impl.hpp @@ -0,0 +1,102 @@ +//Copyright (c) 2006-2010 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 UUID_CE6983AC753411DDA764247956D89593 +#define UUID_CE6983AC753411DDA764247956D89593 + +#include +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#include +#endif +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + namespace + exception_detail + { + class + error_info_base + { + public: + + virtual std::string name_value_string() const = 0; + virtual error_info_base * clone() const = 0; + + virtual + ~error_info_base() throw() + { + } + }; + } + + template + class + error_info: + public exception_detail::error_info_base + { + error_info_base * + clone() const + { + return new error_info(*this); + } + public: + typedef T value_type; + error_info( value_type const & v ): + v_(v) + { + } +#if (__GNUC__*100+__GNUC_MINOR__!=406) //workaround for g++ bug +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + error_info( error_info const & x ): + v_(x.v_) + { + } + error_info( T && v ) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible::value): + v_(std::move(v)) + { + } + error_info( error_info && x ) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible::value): + v_(std::move(x.v_)) + { + } +#endif +#endif + ~error_info() throw() + { + } + value_type const & + value() const + { + return v_; + } + value_type & + value() + { + return v_; + } + private: + error_info & operator=( error_info const & ); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + error_info & operator=( error_info && x ); +#endif + std::string name_value_string() const; + value_type v_; + }; + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/exception_ptr.hpp b/boost/exception/detail/exception_ptr.hpp new file mode 100644 index 00000000..8e19f0d9 --- /dev/null +++ b/boost/exception/detail/exception_ptr.hpp @@ -0,0 +1,514 @@ +//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 UUID_618474C2DE1511DEB74A388C56D89593 +#define UUID_618474C2DE1511DEB74A388C56D89593 + +#include +#ifdef BOOST_NO_EXCEPTIONS +#error This header requires exception handling to be enabled. +#endif +#include +#include +#include +#include +#include +#ifndef BOOST_NO_RTTI +#include +#endif +#include +#include +#include +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + class exception_ptr; + BOOST_NORETURN void rethrow_exception( exception_ptr const & ); + exception_ptr current_exception(); + + class + exception_ptr + { + typedef boost::shared_ptr impl; + impl ptr_; + friend void rethrow_exception( exception_ptr const & ); + typedef exception_detail::clone_base const * (impl::*unspecified_bool_type)() const; + public: + exception_ptr() + { + } + explicit + exception_ptr( impl const & ptr ): + ptr_(ptr) + { + } + bool + operator==( exception_ptr const & other ) const + { + return ptr_==other.ptr_; + } + bool + operator!=( exception_ptr const & other ) const + { + return ptr_!=other.ptr_; + } + operator unspecified_bool_type() const + { + return ptr_?&impl::get:0; + } + }; + + template + inline + exception_ptr + copy_exception( T const & e ) + { + try + { + throw enable_current_exception(e); + } + catch( + ... ) + { + return current_exception(); + } + } + +#ifndef BOOST_NO_RTTI + typedef error_info original_exception_type; + + inline + std::string + to_string( original_exception_type const & x ) + { + return core::demangle(x.value()->name()); + } +#endif + + namespace + exception_detail + { + struct + bad_alloc_: + boost::exception, + std::bad_alloc + { + ~bad_alloc_() throw() { } + }; + + struct + bad_exception_: + boost::exception, + std::bad_exception + { + ~bad_exception_() throw() { } + }; + + template + exception_ptr + get_static_exception_object() + { + Exception ba; + exception_detail::clone_impl c(ba); +#ifndef BOOST_EXCEPTION_DISABLE + c << + throw_function(BOOST_CURRENT_FUNCTION) << + throw_file(__FILE__) << + throw_line(__LINE__); +#endif + static exception_ptr ep(shared_ptr(new exception_detail::clone_impl(c))); + return ep; + } + + template + struct + exception_ptr_static_exception_object + { + static exception_ptr const e; + }; + + template + exception_ptr const + exception_ptr_static_exception_object:: + e = get_static_exception_object(); + } + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class + unknown_exception: + public boost::exception, + public std::exception + { + public: + + unknown_exception() + { + } + + explicit + unknown_exception( std::exception const & e ) + { + add_original_type(e); + } + + explicit + unknown_exception( boost::exception const & e ): + boost::exception(e) + { + add_original_type(e); + } + + ~unknown_exception() throw() + { + } + + private: + + template + void + add_original_type( E const & e ) + { +#ifndef BOOST_NO_RTTI + (*this) << original_exception_type(&typeid(e)); +#endif + } + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + namespace + exception_detail + { + template + class + current_exception_std_exception_wrapper: + public T, + public boost::exception + { + public: + + explicit + current_exception_std_exception_wrapper( T const & e1 ): + T(e1) + { + add_original_type(e1); + } + + current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ): + T(e1), + boost::exception(e2) + { + add_original_type(e1); + } + + ~current_exception_std_exception_wrapper() throw() + { + } + + private: + + template + void + add_original_type( E const & e ) + { +#ifndef BOOST_NO_RTTI + (*this) << original_exception_type(&typeid(e)); +#endif + } + }; + +#ifdef BOOST_NO_RTTI + template + boost::exception const * + get_boost_exception( T const * ) + { + try + { + throw; + } + catch( + boost::exception & x ) + { + return &x; + } + catch(...) + { + return 0; + } + } +#else + template + boost::exception const * + get_boost_exception( T const * x ) + { + return dynamic_cast(x); + } +#endif + + template + inline + exception_ptr + current_exception_std_exception( T const & e1 ) + { + if( boost::exception const * e2 = get_boost_exception(&e1) ) + return boost::copy_exception(current_exception_std_exception_wrapper(e1,*e2)); + else + return boost::copy_exception(current_exception_std_exception_wrapper(e1)); + } + + inline + exception_ptr + current_exception_unknown_exception() + { + return boost::copy_exception(unknown_exception()); + } + + inline + exception_ptr + current_exception_unknown_boost_exception( boost::exception const & e ) + { + return boost::copy_exception(unknown_exception(e)); + } + + inline + exception_ptr + current_exception_unknown_std_exception( std::exception const & e ) + { + if( boost::exception const * be = get_boost_exception(&e) ) + return current_exception_unknown_boost_exception(*be); + else + return boost::copy_exception(unknown_exception(e)); + } + + inline + exception_ptr + current_exception_impl() + { + exception_detail::clone_base const * e=0; + switch( + exception_detail::clone_current_exception(e) ) + { + case exception_detail::clone_current_exception_result:: + success: + { + BOOST_ASSERT(e!=0); + return exception_ptr(shared_ptr(e)); + } + case exception_detail::clone_current_exception_result:: + bad_alloc: + { + BOOST_ASSERT(!e); + return exception_detail::exception_ptr_static_exception_object::e; + } + case exception_detail::clone_current_exception_result:: + bad_exception: + { + BOOST_ASSERT(!e); + return exception_detail::exception_ptr_static_exception_object::e; + } + default: + BOOST_ASSERT(0); + case exception_detail::clone_current_exception_result:: + not_supported: + { + BOOST_ASSERT(!e); + try + { + throw; + } + catch( + exception_detail::clone_base & e ) + { + return exception_ptr(shared_ptr(e.clone())); + } + catch( + std::domain_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::invalid_argument & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::length_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::out_of_range & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::logic_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::range_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::overflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::underflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::ios_base::failure & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::runtime_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_alloc & e ) + { + return exception_detail::current_exception_std_exception(e); + } + #ifndef BOOST_NO_TYPEID + catch( + std::bad_cast & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_typeid & e ) + { + return exception_detail::current_exception_std_exception(e); + } + #endif + catch( + std::bad_exception & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::exception & e ) + { + return exception_detail::current_exception_unknown_std_exception(e); + } + catch( + boost::exception & e ) + { + return exception_detail::current_exception_unknown_boost_exception(e); + } + catch( + ... ) + { + return exception_detail::current_exception_unknown_exception(); + } + } + } + } + } + + inline + exception_ptr + current_exception() + { + exception_ptr ret; + try + { + ret=exception_detail::current_exception_impl(); + } + catch( + std::bad_alloc & ) + { + ret=exception_detail::exception_ptr_static_exception_object::e; + } + catch( + ... ) + { + ret=exception_detail::exception_ptr_static_exception_object::e; + } + BOOST_ASSERT(ret); + return ret; + } + + BOOST_NORETURN + inline + void + rethrow_exception( exception_ptr const & p ) + { + BOOST_ASSERT(p); + p.ptr_->rethrow(); + BOOST_ASSERT(0); + #if defined(UNDER_CE) + // some CE platforms don't define ::abort() + exit(-1); + #else + abort(); + #endif + } + + inline + std::string + diagnostic_information( exception_ptr const & p, bool verbose=true ) + { + if( p ) + try + { + rethrow_exception(p); + } + catch( + ... ) + { + return current_exception_diagnostic_information(verbose); + } + return ""; + } + + inline + std::string + to_string( exception_ptr const & p ) + { + std::string s='\n'+diagnostic_information(p); + std::string padding(" "); + std::string r; + bool f=false; + for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i ) + { + if( f ) + r+=padding; + char c=*i; + r+=c; + f=(c=='\n'); + } + return r; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/is_output_streamable.hpp b/boost/exception/detail/is_output_streamable.hpp new file mode 100644 index 00000000..10e5c516 --- /dev/null +++ b/boost/exception/detail/is_output_streamable.hpp @@ -0,0 +1,61 @@ +//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 UUID_898984B4076411DD973EDFA055D89593 +#define UUID_898984B4076411DD973EDFA055D89593 + +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + namespace + to_string_detail + { + struct + partial_ordering_helper1 + { + template + partial_ordering_helper1( std::basic_ostream & ); + }; + + struct + partial_ordering_helper2 + { + template + partial_ordering_helper2( T const & ); + }; + + char operator<<( partial_ordering_helper1, partial_ordering_helper2 ); + + template + struct + is_output_streamable_impl + { + static std::basic_ostream & f(); + static T const & g(); + enum e { value=1!=(sizeof(f()< > + struct + is_output_streamable + { + enum e { value=to_string_detail::is_output_streamable_impl::value }; + }; + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/object_hex_dump.hpp b/boost/exception/detail/object_hex_dump.hpp new file mode 100644 index 00000000..267bf0bf --- /dev/null +++ b/boost/exception/detail/object_hex_dump.hpp @@ -0,0 +1,51 @@ +//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 UUID_6F463AC838DF11DDA3E6909F56D89593 +#define UUID_6F463AC838DF11DDA3E6909F56D89593 + +#include +#include +#include +#include +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + namespace + exception_detail + { + template + inline + std::string + object_hex_dump( T const & x, std::size_t max_size=16 ) + { + std::ostringstream s; + s << "type: " << type_name() << ", size: " << sizeof(T) << ", dump: "; + std::size_t n=sizeof(T)>max_size?max_size:sizeof(T); + s.fill('0'); + s.width(2); + unsigned char const * b=reinterpret_cast(&x); + s << std::setw(2) << std::hex << (unsigned int)*b; + for( unsigned char const * e=b+n; ++b!=e; ) + s << " " << std::setw(2) << std::hex << (unsigned int)*b; + return s.str(); + } + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/detail/shared_ptr.hpp b/boost/exception/detail/shared_ptr.hpp new file mode 100644 index 00000000..51febe8c --- /dev/null +++ b/boost/exception/detail/shared_ptr.hpp @@ -0,0 +1,17 @@ +//Copyright (c) 2006-2008 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 UUID_837060E885AF11E68DA91D15E31AC075 +#define UUID_837060E885AF11E68DA91D15E31AC075 + +#ifdef BOOST_EXCEPTION_MINI_BOOST +#include +namespace boost { namespace exception_detail { using std::shared_ptr; } } +#else +#include +namespace boost { namespace exception_detail { using boost::shared_ptr; } } +#endif + +#endif diff --git a/boost/exception/detail/type_info.hpp b/boost/exception/detail/type_info.hpp new file mode 100644 index 00000000..739ac574 --- /dev/null +++ b/boost/exception/detail/type_info.hpp @@ -0,0 +1,82 @@ +//Copyright (c) 2006-2010 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 UUID_C3E1741C754311DDB2834CCA55D89593 +#define UUID_C3E1741C754311DDB2834CCA55D89593 + +#include +#include +#include +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + template + inline + std::string + tag_type_name() + { +#ifdef BOOST_NO_TYPEID + return BOOST_CURRENT_FUNCTION; +#else + return core::demangle(typeid(T*).name()); +#endif + } + + template + inline + std::string + type_name() + { +#ifdef BOOST_NO_TYPEID + return BOOST_CURRENT_FUNCTION; +#else + return core::demangle(typeid(T).name()); +#endif + } + + namespace + exception_detail + { + struct + type_info_ + { + core::typeinfo const * type_; + + explicit + type_info_( core::typeinfo const & type ): + type_(&type) + { + } + + friend + bool + operator<( type_info_ const & a, type_info_ const & b ) + { + return 0!=(a.type_->before(*b.type_)); + } + }; + } + } + +#define BOOST_EXCEPTION_STATIC_TYPEID(T) ::boost::exception_detail::type_info_(BOOST_CORE_TYPEID(T)) + +#ifndef BOOST_NO_RTTI +#define BOOST_EXCEPTION_DYNAMIC_TYPEID(x) ::boost::exception_detail::type_info_(typeid(x)) +#endif + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/diagnostic_information.hpp b/boost/exception/diagnostic_information.hpp new file mode 100644 index 00000000..48f06a0f --- /dev/null +++ b/boost/exception/diagnostic_information.hpp @@ -0,0 +1,204 @@ +//Copyright (c) 2006-2010 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 UUID_0552D49838DD11DD90146B8956D89593 +#define UUID_0552D49838DD11DD90146B8956D89593 + +#include +#include +#include +#include +#ifndef BOOST_NO_RTTI +#include +#endif +#include +#include +#include +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#ifndef BOOST_NO_EXCEPTIONS +namespace +boost + { + namespace + exception_detail + { + std::string diagnostic_information_impl( boost::exception const *, std::exception const *, bool, bool ); + } + + inline + std::string + current_exception_diagnostic_information( bool verbose=true) + { + boost::exception const * be=current_exception_cast(); + std::exception const * se=current_exception_cast(); + if( be || se ) + return exception_detail::diagnostic_information_impl(be,se,true,verbose); + else + return "No diagnostic information available."; + } + } +#endif + +namespace +boost + { + namespace + exception_detail + { + inline + exception const * + get_boost_exception( exception const * e ) + { + return e; + } + + inline + exception const * + get_boost_exception( ... ) + { + return 0; + } + + inline + std::exception const * + get_std_exception( std::exception const * e ) + { + return e; + } + + inline + std::exception const * + get_std_exception( ... ) + { + return 0; + } + + inline + char const * + get_diagnostic_information( exception const & x, char const * header ) + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + error_info_container * c=x.data_.get(); + if( !c ) + x.data_.adopt(c=new exception_detail::error_info_container_impl); + char const * di=c->diagnostic_information(header); + BOOST_ASSERT(di!=0); + return di; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(...) + { + return 0; + } +#endif + } + + inline + std::string + diagnostic_information_impl( boost::exception const * be, std::exception const * se, bool with_what, bool verbose ) + { + if( !be && !se ) + return "Unknown exception."; +#ifndef BOOST_NO_RTTI + if( !be ) + be=dynamic_cast(se); + if( !se ) + se=dynamic_cast(be); +#endif + char const * wh=0; + if( with_what && se ) + { + wh=se->what(); + if( be && exception_detail::get_diagnostic_information(*be,0)==wh ) + return wh; + } + std::ostringstream tmp; + if( be && verbose ) + { + char const * const * f=get_error_info(*be); + int const * l=get_error_info(*be); + char const * const * fn=get_error_info(*be); + if( !f && !l && !fn ) + tmp << "Throw location unknown (consider using BOOST_THROW_EXCEPTION)\n"; + else + { + if( f ) + { + tmp << *f; + if( int const * l=get_error_info(*be) ) + tmp << '(' << *l << "): "; + } + tmp << "Throw in function "; + if( char const * const * fn=get_error_info(*be) ) + tmp << *fn; + else + tmp << "(unknown)"; + tmp << '\n'; + } + } +#ifndef BOOST_NO_RTTI + if ( verbose ) + tmp << std::string("Dynamic exception type: ") << + core::demangle((be?(BOOST_EXCEPTION_DYNAMIC_TYPEID(*be)):(BOOST_EXCEPTION_DYNAMIC_TYPEID(*se))).type_->name()) << '\n'; +#endif + if( with_what && se && verbose ) + tmp << "std::exception::what: " << wh << '\n'; + if( be ) + if( char const * s=exception_detail::get_diagnostic_information(*be,tmp.str().c_str()) ) + if( *s ) + return std::string(s); + return tmp.str(); + } + } + + template + std::string + diagnostic_information( T const & e, bool verbose=true ) + { + return exception_detail::diagnostic_information_impl(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),true,verbose); + } + + inline + char const * + diagnostic_information_what( exception const & e, bool verbose=true ) throw() + { + char const * w=0; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + (void) exception_detail::diagnostic_information_impl(&e,0,false,verbose); + if( char const * di=exception_detail::get_diagnostic_information(e,0) ) + return di; + else + return "Failed to produce boost::diagnostic_information_what()"; +#ifndef BOOST_NO_EXCEPTIONS + } + catch( + ... ) + { + } +#endif + return w; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/exception.hpp b/boost/exception/exception.hpp new file mode 100644 index 00000000..c0fdaf9e --- /dev/null +++ b/boost/exception/exception.hpp @@ -0,0 +1,521 @@ +//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 UUID_274DA366004E11DCB1DDFE2E56D89593 +#define UUID_274DA366004E11DCB1DDFE2E56D89593 +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#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 + +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; + + 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) + { + } + }; + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class exception; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + 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() throw() + { + } + }; + + 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; + + 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 & ); + } + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class + 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) + { + } + +#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 ) throw(): + data_(x.data_), + throw_function_(x.throw_function_), + throw_file_(x.throw_file_), + throw_line_(x.throw_line_) + { + } +#endif + + virtual ~exception() throw() +#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 &, error_info const & ); + + friend char const * exception_detail::get_diagnostic_information( exception const &, char 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; + 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 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_; + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + inline + exception:: + ~exception() throw() + { + } + + 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; + } + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + template + struct + error_info_injector: + public T, + public exception + { + explicit + error_info_injector( T const & x ): + T(x) + { + } + + ~error_info_injector() throw() + { + } + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + 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); + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + class + clone_base + { + public: + + virtual clone_base const * clone() const = 0; + virtual void rethrow() const = 0; + + virtual + ~clone_base() throw() + { + } + }; +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#endif + + 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->data_ = data; + } + + inline + void + copy_boost_exception( void *, void const * ) + { + } + +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility push (default) +# endif +#endif + template + class + 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() throw() + { + } + + private: + + clone_base const * + clone() const + { + return new clone_impl(*this,clone_tag()); + } + + void + rethrow() const + { + throw*this; + } + }; + } +#if defined(__GNUC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +# pragma GCC visibility pop +# endif +#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 diff --git a/boost/exception/get_error_info.hpp b/boost/exception/get_error_info.hpp new file mode 100644 index 00000000..831717df --- /dev/null +++ b/boost/exception/get_error_info.hpp @@ -0,0 +1,133 @@ +//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 UUID_1A590226753311DD9E4CCF6156D89593 +#define UUID_1A590226753311DD9E4CCF6156D89593 + +#include +#include +#include +#include +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + namespace + exception_detail + { + template + struct + get_info + { + static + typename ErrorInfo::value_type * + get( exception const & x ) + { + if( exception_detail::error_info_container * c=x.data_.get() ) + if( shared_ptr eib = c->get(BOOST_EXCEPTION_STATIC_TYPEID(ErrorInfo)) ) + { +#ifndef BOOST_NO_RTTI + BOOST_ASSERT( 0!=dynamic_cast(eib.get()) ); +#endif + ErrorInfo * w = static_cast(eib.get()); + return &w->value(); + } + return 0; + } + }; + + template <> + struct + get_info + { + static + char const * * + get( exception const & x ) + { + return x.throw_function_ ? &x.throw_function_ : 0; + } + }; + + template <> + struct + get_info + { + static + char const * * + get( exception const & x ) + { + return x.throw_file_ ? &x.throw_file_ : 0; + } + }; + + template <> + struct + get_info + { + static + int * + get( exception const & x ) + { + return x.throw_line_!=-1 ? &x.throw_line_ : 0; + } + }; + + template + struct + get_error_info_return_type + { + typedef R * type; + }; + + template + struct + get_error_info_return_type + { + typedef R const * type; + }; + } + +#ifdef BOOST_NO_RTTI + template + inline + typename ErrorInfo::value_type const * + get_error_info( boost::exception const & x ) + { + return exception_detail::get_info::get(x); + } + template + inline + typename ErrorInfo::value_type * + get_error_info( boost::exception & x ) + { + return exception_detail::get_info::get(x); + } +#else + template + inline + typename exception_detail::get_error_info_return_type::type + get_error_info( E & some_exception ) + { + if( exception const * x = dynamic_cast(&some_exception) ) + return exception_detail::get_info::get(*x); + else + return 0; + } +#endif + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/info.hpp b/boost/exception/info.hpp new file mode 100644 index 00000000..f7ac50ec --- /dev/null +++ b/boost/exception/info.hpp @@ -0,0 +1,277 @@ +//Copyright (c) 2006-2010 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 UUID_8D22C4CA9CC811DCAA9133D256D89593 +#define UUID_8D22C4CA9CC811DCAA9133D256D89593 + +#include +#include +#include +#include +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + template + inline + std::string + error_info_name( error_info const & x ) + { + return tag_type_name(); + } + + template + inline + std::string + to_string( error_info const & x ) + { + return '[' + error_info_name(x) + "] = " + to_string_stub(x.value()) + '\n'; + } + + template + inline + std::string + error_info:: + name_value_string() const + { + return to_string_stub(*this); + } + + namespace + exception_detail + { + class + error_info_container_impl: + public error_info_container + { + public: + + error_info_container_impl(): + count_(0) + { + } + + ~error_info_container_impl() throw() + { + } + + void + set( shared_ptr const & x, type_info_ const & typeid_ ) + { + BOOST_ASSERT(x); + info_[typeid_] = x; + diagnostic_info_str_.clear(); + } + + shared_ptr + get( type_info_ const & ti ) const + { + error_info_map::const_iterator i=info_.find(ti); + if( info_.end()!=i ) + { + shared_ptr const & p = i->second; +#ifndef BOOST_NO_RTTI + BOOST_ASSERT( *BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==*ti.type_ ); +#endif + return p; + } + return shared_ptr(); + } + + char const * + diagnostic_information( char const * header ) const + { + if( header ) + { + std::ostringstream tmp; + tmp << header; + for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i ) + { + error_info_base const & x = *i->second; + tmp << x.name_value_string(); + } + tmp.str().swap(diagnostic_info_str_); + } + return diagnostic_info_str_.c_str(); + } + + private: + + friend class boost::exception; + + typedef std::map< type_info_, shared_ptr > error_info_map; + error_info_map info_; + mutable std::string diagnostic_info_str_; + mutable int count_; + + error_info_container_impl( error_info_container_impl const & ); + error_info_container_impl & operator=( error_info_container const & ); + + void + add_ref() const + { + ++count_; + } + + bool + release() const + { + if( --count_ ) + return false; + else + { + delete this; + return true; + } + } + + refcount_ptr + clone() const + { + refcount_ptr p; + error_info_container_impl * c=new error_info_container_impl; + p.adopt(c); + for( error_info_map::const_iterator i=info_.begin(),e=info_.end(); i!=e; ++i ) + { + shared_ptr cp(i->second->clone()); + c->info_.insert(std::make_pair(i->first,cp)); + } + return p; + } + }; + + template + inline + E const & + set_info( E const & x, error_info const & v ) + { + typedef error_info error_info_tag_t; + shared_ptr p( new error_info_tag_t(v) ); + exception_detail::error_info_container * c=x.data_.get(); + if( !c ) + x.data_.adopt(c=new exception_detail::error_info_container_impl); + c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t)); + return x; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + E const & set_info( E const &, error_info && ); + template + struct set_info_rv; + template + struct + set_info_rv > + { + template + friend E const & set_info( E const &, error_info && ); + template + static + E const & + set( E const & x, error_info && v ) + { + typedef error_info error_info_tag_t; + shared_ptr p( new error_info_tag_t(std::move(v)) ); + exception_detail::error_info_container * c=x.data_.get(); + if( !c ) + x.data_.adopt(c=new exception_detail::error_info_container_impl); + c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t)); + return x; + } + }; + template <> + struct + set_info_rv + { + template + friend E const & set_info( E const &, error_info && ); + template + static + E const & + set( E const & x, throw_function && y ) + { + x.throw_function_=y.v_; + return x; + } + }; + template <> + struct + set_info_rv + { + template + friend E const & set_info( E const &, error_info && ); + template + static + E const & + set( E const & x, throw_file && y ) + { + x.throw_file_=y.v_; + return x; + } + }; + template <> + struct + set_info_rv + { + template + friend E const & set_info( E const &, error_info && ); + template + static + E const & + set( E const & x, throw_line && y ) + { + x.throw_line_=y.v_; + return x; + } + }; + template + inline + E const & + set_info( E const & x, error_info && v ) + { + return set_info_rv >::template set(x,std::move(v)); + } +#endif + + template + struct + derives_boost_exception + { + enum e { value = (sizeof(dispatch_boost_exception((T*)0))==sizeof(large_size)) }; + }; + } + + template + inline + typename enable_if,E const &>::type + operator<<( E const & x, error_info const & v ) + { + return exception_detail::set_info(x,v); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + inline + typename enable_if,E const &>::type + operator<<( E const & x, error_info && v ) + { + return exception_detail::set_info(x,std::move(v)); + } +#endif + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/to_string.hpp b/boost/exception/to_string.hpp new file mode 100644 index 00000000..51425b10 --- /dev/null +++ b/boost/exception/to_string.hpp @@ -0,0 +1,89 @@ +//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 UUID_7E48761AD92811DC9011477D56D89593 +#define UUID_7E48761AD92811DC9011477D56D89593 + +#include +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + template + std::string to_string( std::pair const & ); + std::string to_string( std::exception const & ); + + namespace + to_string_detail + { + template + typename disable_if,char>::type to_string( T const & ); + using boost::to_string; + + template + struct has_to_string_impl; + + template + struct + has_to_string_impl + { + enum e { value=1 }; + }; + + template + struct + has_to_string_impl + { + static T const & f(); + enum e { value=1!=sizeof(to_string(f())) }; + }; + } + + template + inline + typename enable_if,std::string>::type + to_string( T const & x ) + { + std::ostringstream out; + out << x; + return out.str(); + } + + template + struct + has_to_string + { + enum e { value=to_string_detail::has_to_string_impl::value>::value }; + }; + + template + inline + std::string + to_string( std::pair const & x ) + { + return std::string("(") + to_string(x.first) + ',' + to_string(x.second) + ')'; + } + + inline + std::string + to_string( std::exception const & x ) + { + return x.what(); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception/to_string_stub.hpp b/boost/exception/to_string_stub.hpp new file mode 100644 index 00000000..8ff5e47f --- /dev/null +++ b/boost/exception/to_string_stub.hpp @@ -0,0 +1,118 @@ +//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 UUID_E788439ED9F011DCB181F25B55D89593 +#define UUID_E788439ED9F011DCB181F25B55D89593 + +#include +#include +#include + +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + namespace + exception_detail + { + template + struct + to_string_dispatcher + { + template + static + std::string + convert( T const & x, Stub ) + { + return to_string(x); + } + }; + + template <> + struct + to_string_dispatcher + { + template + static + std::string + convert( T const & x, Stub s ) + { + return s(x); + } + + template + static + std::string + convert( T const & x, std::string s ) + { + return s; + } + + template + static + std::string + convert( T const & x, char const * s ) + { + BOOST_ASSERT(s!=0); + return s; + } + }; + + namespace + to_string_dispatch + { + template + inline + std::string + dispatch( T const & x, Stub s ) + { + return to_string_dispatcher::value>::convert(x,s); + } + } + + template + inline + std::string + string_stub_dump( T const & x ) + { + return "[ " + exception_detail::object_hex_dump(x) + " ]"; + } + } + + template + inline + std::string + to_string_stub( T const & x ) + { + return exception_detail::to_string_dispatch::dispatch(x,&exception_detail::string_stub_dump); + } + + template + inline + std::string + to_string_stub( T const & x, Stub s ) + { + return exception_detail::to_string_dispatch::dispatch(x,s); + } + + template + inline + std::string + to_string_stub( std::pair const & x, Stub s ) + { + return std::string("(") + to_string_stub(x.first,s) + ',' + to_string_stub(x.second,s) + ')'; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/boost/exception_ptr.hpp b/boost/exception_ptr.hpp new file mode 100644 index 00000000..d48cce9d --- /dev/null +++ b/boost/exception_ptr.hpp @@ -0,0 +1,11 @@ +//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 UUID_FA5836A2CADA11DC8CD47C8555D89593 +#define UUID_FA5836A2CADA11DC8CD47C8555D89593 + +#include + +#endif diff --git a/boost/filesystem.hpp b/boost/filesystem.hpp new file mode 100644 index 00000000..0122634d --- /dev/null +++ b/boost/filesystem.hpp @@ -0,0 +1,21 @@ +// boost/filesystem.hpp --------------------------------------------------------------// + +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_FILESYSTEM_HPP +#define BOOST_FILESYSTEM_FILESYSTEM_HPP + +# include +# include +# include +# include +# include + +#endif // BOOST_FILESYSTEM_FILESYSTEM_HPP diff --git a/boost/filesystem/config.hpp b/boost/filesystem/config.hpp new file mode 100644 index 00000000..81597695 --- /dev/null +++ b/boost/filesystem/config.hpp @@ -0,0 +1,110 @@ +// boost/filesystem/v3/config.hpp ----------------------------------------------------// + +// Copyright Beman Dawes 2003 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_CONFIG_HPP +#define BOOST_FILESYSTEM3_CONFIG_HPP + +# if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION != 3 +# error Compiling Filesystem version 3 file with BOOST_FILESYSTEM_VERSION defined != 3 +# endif + +# if !defined(BOOST_FILESYSTEM_VERSION) +# define BOOST_FILESYSTEM_VERSION 3 +# endif + +#define BOOST_FILESYSTEM_I18N // aid users wishing to compile several versions + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include +#include // for BOOST_POSIX_API or BOOST_WINDOWS_API +#include + +// BOOST_FILESYSTEM_DEPRECATED needed for source compiles -----------------------------// + +# ifdef BOOST_FILESYSTEM_SOURCE +# define BOOST_FILESYSTEM_DEPRECATED +# undef BOOST_FILESYSTEM_NO_DEPRECATED // fixes #9454, src bld fails if NO_DEP defined +# endif + +// throw an exception ----------------------------------------------------------------// +// +// Exceptions were originally thrown via boost::throw_exception(). +// As throw_exception() became more complex, it caused user error reporting +// to be harder to interpret, since the exception reported became much more complex. +// The immediate fix was to throw directly, wrapped in a macro to make any later change +// easier. + +#define BOOST_FILESYSTEM_THROW(EX) throw EX + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// normalize macros ------------------------------------------------------------------// + +#if !defined(BOOST_FILESYSTEM_DYN_LINK) && !defined(BOOST_FILESYSTEM_STATIC_LINK) \ + && !defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_ALL_STATIC_LINK) +# define BOOST_FILESYSTEM_STATIC_LINK +#endif + +#if defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_FILESYSTEM_DYN_LINK) +# define BOOST_FILESYSTEM_DYN_LINK +#elif defined(BOOST_ALL_STATIC_LINK) && !defined(BOOST_FILESYSTEM_STATIC_LINK) +# define BOOST_FILESYSTEM_STATIC_LINK +#endif + +#if defined(BOOST_FILESYSTEM_DYN_LINK) && defined(BOOST_FILESYSTEM_STATIC_LINK) +# error Must not define both BOOST_FILESYSTEM_DYN_LINK and BOOST_FILESYSTEM_STATIC_LINK +#endif + +#if defined(BOOST_ALL_NO_LIB) && !defined(BOOST_FILESYSTEM_NO_LIB) +# define BOOST_FILESYSTEM_NO_LIB +#endif + +// enable dynamic linking ------------------------------------------------------------// + +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# if defined(BOOST_FILESYSTEM_SOURCE) +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_FILESYSTEM_DECL BOOST_SYMBOL_IMPORT +# endif +#else +# define BOOST_FILESYSTEM_DECL +#endif + +// enable automatic library variant selection ----------------------------------------// + +#if !defined(BOOST_FILESYSTEM_SOURCE) && !defined(BOOST_ALL_NO_LIB) \ + && !defined(BOOST_FILESYSTEM_NO_LIB) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_filesystem +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#endif // BOOST_FILESYSTEM3_CONFIG_HPP diff --git a/boost/filesystem/convenience.hpp b/boost/filesystem/convenience.hpp new file mode 100644 index 00000000..f0bd9869 --- /dev/null +++ b/boost/filesystem/convenience.hpp @@ -0,0 +1,58 @@ +// boost/filesystem/convenience.hpp ----------------------------------------// + +// Copyright Beman Dawes, 2002-2005 +// Copyright Vladimir Prus, 2002 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/filesystem + +//----------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_CONVENIENCE_HPP +#define BOOST_FILESYSTEM3_CONVENIENCE_HPP + +#include + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include +#include + +#include // must be the last #include + +namespace boost +{ + namespace filesystem + { + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + + inline std::string extension(const path & p) + { + return p.extension().string(); + } + + inline std::string basename(const path & p) + { + return p.stem().string(); + } + + inline path change_extension( const path & p, const path & new_extension ) + { + path new_p( p ); + new_p.replace_extension( new_extension ); + return new_p; + } + +# endif + + + } // namespace filesystem +} // namespace boost + +#include // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_CONVENIENCE_HPP diff --git a/boost/filesystem/detail/macro_value.hpp b/boost/filesystem/detail/macro_value.hpp new file mode 100644 index 00000000..2c4a16a6 --- /dev/null +++ b/boost/filesystem/detail/macro_value.hpp @@ -0,0 +1,44 @@ +// boost/filesystem/detail/macro_value.hpp -------------------------------------------// + +// (C) Copyright John Maddock 2001 - 2003 +// (C) Copyright Jens Maurer 2001 +// (C) Copyright Peter Dimov 2001 +// (C) Copyright Darin Adler 2001 +// (C) Copyright Beman Dawes 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM_MACRO_VALUE_HPP +#define BOOST_FILESYSTEM_MACRO_VALUE_HPP + +#include +#include +#include + +namespace boost +{ + namespace detail + { + inline const char* macro_value(const char* name, const char* value) + { + static const char* no_value = "[no value]"; + static const char* not_defined = "[not defined]"; + + BOOST_ASSERT_MSG(name, "name argument must not be a null pointer"); + BOOST_ASSERT_MSG(value, "value argument must not be a null pointer"); + + return strcmp(name, value + 1) + ? ((*value && *(value+1)) ? (value+1) : no_value) + : not_defined; // name == value+1 so the macro is not defined + } + } // detail +} // boost + +#define BOOST_MACRO_VALUE(X) boost::detail::macro_value(#X, BOOST_STRINGIZE(=X)) + +#endif // BOOST_FILESYSTEM_MACRO_VALUE_HPP diff --git a/boost/filesystem/detail/utf8_codecvt_facet.hpp b/boost/filesystem/detail/utf8_codecvt_facet.hpp new file mode 100644 index 00000000..3b78fb1b --- /dev/null +++ b/boost/filesystem/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,24 @@ +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). + +// Distributed under the Boost Software License, Version 1.0. +// (See http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP +#define BOOST_FILESYSTEM_UTF8_CODECVT_FACET_HPP + +#include + +#define BOOST_UTF8_BEGIN_NAMESPACE \ + namespace boost { namespace filesystem { namespace detail { + +#define BOOST_UTF8_END_NAMESPACE }}} +#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL + +#include + +#undef BOOST_UTF8_BEGIN_NAMESPACE +#undef BOOST_UTF8_END_NAMESPACE +#undef BOOST_UTF8_DECL + +#endif diff --git a/boost/filesystem/exception.hpp b/boost/filesystem/exception.hpp new file mode 100644 index 00000000..985cd8f7 --- /dev/null +++ b/boost/filesystem/exception.hpp @@ -0,0 +1,9 @@ +// boost/filesystem/exception.hpp -----------------------------------------------------// + +// Copyright Beman Dawes 2003 +// 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 header is no longer used. The contents have been moved to path.hpp. +// It is provided so that user code #includes do not have to be changed. diff --git a/boost/filesystem/fstream.hpp b/boost/filesystem/fstream.hpp new file mode 100644 index 00000000..07272388 --- /dev/null +++ b/boost/filesystem/fstream.hpp @@ -0,0 +1,182 @@ +// boost/filesystem/fstream.hpp ------------------------------------------------------// + +// Copyright Beman Dawes 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_FSTREAM_HPP +#define BOOST_FILESYSTEM3_FSTREAM_HPP + +#include + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include +#include +#include + +#include // must be the last #include + +// on Windows, except for standard libaries known to have wchar_t overloads for +// file stream I/O, use path::string() to get a narrow character c_str() +#if defined(BOOST_WINDOWS_API) \ + && (!defined(_CPPLIB_VER) || _CPPLIB_VER < 405 || defined(_STLPORT_VERSION)) + // !Dinkumware || early Dinkumware || STLPort masquerading as Dinkumware +# define BOOST_FILESYSTEM_C_STR string().c_str() // use narrow, since wide not available +#else // use the native c_str, which will be narrow on POSIX, wide on Windows +# define BOOST_FILESYSTEM_C_STR c_str() +#endif + +namespace boost +{ +namespace filesystem +{ + +//--------------------------------------------------------------------------------------// +// basic_filebuf // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits > + class basic_filebuf : public std::basic_filebuf + { + private: // disallow copying + basic_filebuf(const basic_filebuf&); + const basic_filebuf& operator=(const basic_filebuf&); + + public: + basic_filebuf() {} + virtual ~basic_filebuf() {} + + basic_filebuf* + open(const path& p, std::ios_base::openmode mode) + { + return std::basic_filebuf::open(p.BOOST_FILESYSTEM_C_STR, mode) + ? this : 0; + } + }; + +//--------------------------------------------------------------------------------------// +// basic_ifstream // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits > + class basic_ifstream : public std::basic_ifstream + { + private: // disallow copying + basic_ifstream(const basic_ifstream&); + const basic_ifstream& operator=(const basic_ifstream&); + + public: + basic_ifstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + + explicit basic_ifstream(const path& p) + : std::basic_ifstream(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in) {} + + basic_ifstream(const path& p, std::ios_base::openmode mode) + : std::basic_ifstream(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_ifstream::open(p.BOOST_FILESYSTEM_C_STR, std::ios_base::in); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_ifstream::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_ifstream() {} + }; + +//--------------------------------------------------------------------------------------// +// basic_ofstream // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits > + class basic_ofstream : public std::basic_ofstream + { + private: // disallow copying + basic_ofstream(const basic_ofstream&); + const basic_ofstream& operator=(const basic_ofstream&); + + public: + basic_ofstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + + explicit basic_ofstream(const path& p) + : std::basic_ofstream(p.BOOST_FILESYSTEM_C_STR, std::ios_base::out) {} + + basic_ofstream(const path& p, std::ios_base::openmode mode) + : std::basic_ofstream(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_ofstream::open(p.BOOST_FILESYSTEM_C_STR, std::ios_base::out); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_ofstream::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_ofstream() {} + }; + +//--------------------------------------------------------------------------------------// +// basic_fstream // +//--------------------------------------------------------------------------------------// + + template < class charT, class traits = std::char_traits > + class basic_fstream : public std::basic_fstream + { + private: // disallow copying + basic_fstream(const basic_fstream&); + const basic_fstream & operator=(const basic_fstream&); + + public: + basic_fstream() {} + + // use two signatures, rather than one signature with default second + // argument, to workaround VC++ 7.1 bug (ID VSWhidbey 38416) + + explicit basic_fstream(const path& p) + : std::basic_fstream(p.BOOST_FILESYSTEM_C_STR, + std::ios_base::in | std::ios_base::out) {} + + basic_fstream(const path& p, std::ios_base::openmode mode) + : std::basic_fstream(p.BOOST_FILESYSTEM_C_STR, mode) {} + + void open(const path& p) + { std::basic_fstream::open(p.BOOST_FILESYSTEM_C_STR, + std::ios_base::in | std::ios_base::out); } + + void open(const path& p, std::ios_base::openmode mode) + { std::basic_fstream::open(p.BOOST_FILESYSTEM_C_STR, mode); } + + virtual ~basic_fstream() {} + + }; + +//--------------------------------------------------------------------------------------// +// typedefs // +//--------------------------------------------------------------------------------------// + + typedef basic_filebuf filebuf; + typedef basic_ifstream ifstream; + typedef basic_ofstream ofstream; + typedef basic_fstream fstream; + + typedef basic_filebuf wfilebuf; + typedef basic_ifstream wifstream; + typedef basic_ofstream wofstream; + typedef basic_fstream wfstream; + +} // namespace filesystem +} // namespace boost + +#include // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_FSTREAM_HPP diff --git a/boost/filesystem/operations.hpp b/boost/filesystem/operations.hpp new file mode 100644 index 00000000..b0ea42a3 --- /dev/null +++ b/boost/filesystem/operations.hpp @@ -0,0 +1,1357 @@ +// boost/filesystem/operations.hpp ---------------------------------------------------// + +// Copyright Beman Dawes 2002-2009 +// Copyright Jan Langer 2002 +// Copyright Dietmar Kuehl 2001 +// Copyright Vladimir Prus 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_FILESYSTEM3_OPERATIONS_HPP +#define BOOST_FILESYSTEM3_OPERATIONS_HPP + +#include + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for pair +#include +#include +#include + +#ifdef BOOST_WINDOWS_API +# include +#endif + +#include // must be the last #include + +//--------------------------------------------------------------------------------------// + +namespace boost +{ + namespace filesystem + { + + //--------------------------------------------------------------------------------------// + // // + // class filesystem_error // + // // + //--------------------------------------------------------------------------------------// + + class BOOST_SYMBOL_VISIBLE filesystem_error : public system::system_error + { + // see http://www.boost.org/more/error_handling.html for design rationale + + // all functions are inline to avoid issues with crossing dll boundaries + + // functions previously throw() are now BOOST_NOEXCEPT_OR_NOTHROW + // functions previously without throw() are now BOOST_NOEXCEPT + + public: + // compiler generates copy constructor and copy assignment + + filesystem_error( + const std::string & what_arg, system::error_code ec) BOOST_NOEXCEPT + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + } + catch (...) { m_imp_ptr.reset(); } + } + + filesystem_error( + const std::string & what_arg, const path& path1_arg, + system::error_code ec) BOOST_NOEXCEPT + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + m_imp_ptr->m_path1 = path1_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + filesystem_error( + const std::string & what_arg, const path& path1_arg, + const path& path2_arg, system::error_code ec) BOOST_NOEXCEPT + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + m_imp_ptr->m_path1 = path1_arg; + m_imp_ptr->m_path2 = path2_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + ~filesystem_error() BOOST_NOEXCEPT_OR_NOTHROW{} + + const path& path1() const BOOST_NOEXCEPT + { + static const path empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path; + } + const path& path2() const BOOST_NOEXCEPT + { + static const path empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path; + } + + const char* what() const BOOST_NOEXCEPT_OR_NOTHROW + { + if (!m_imp_ptr.get()) + return system::system_error::what(); + + try + { + if (m_imp_ptr->m_what.empty()) + { + m_imp_ptr->m_what = system::system_error::what(); + if (!m_imp_ptr->m_path1.empty()) + { + m_imp_ptr->m_what += ": \""; + m_imp_ptr->m_what += m_imp_ptr->m_path1.string(); + m_imp_ptr->m_what += "\""; + } + if (!m_imp_ptr->m_path2.empty()) + { + m_imp_ptr->m_what += ", \""; + m_imp_ptr->m_what += m_imp_ptr->m_path2.string(); + m_imp_ptr->m_what += "\""; + } + } + return m_imp_ptr->m_what.c_str(); + } + catch (...) + { + return system::system_error::what(); + } + } + + private: + struct m_imp + { + path m_path1; // may be empty() + path m_path2; // may be empty() + std::string m_what; // not built until needed + }; + boost::shared_ptr m_imp_ptr; + }; + +//--------------------------------------------------------------------------------------// +// file_type // +//--------------------------------------------------------------------------------------// + + enum file_type + { + status_error, +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + status_unknown = status_error, +# endif + file_not_found, + regular_file, + directory_file, + // the following may not apply to some operating systems or file systems + symlink_file, + block_file, + character_file, + fifo_file, + socket_file, + reparse_file, // Windows: FILE_ATTRIBUTE_REPARSE_POINT that is not a symlink + type_unknown, // file does exist, but isn't one of the above types or + // we don't have strong enough permission to find its type + + _detail_directory_symlink // internal use only; never exposed to users + }; + +//--------------------------------------------------------------------------------------// +// perms // +//--------------------------------------------------------------------------------------// + + enum perms + { + no_perms = 0, // file_not_found is no_perms rather than perms_not_known + + // POSIX equivalent macros given in comments. + // Values are from POSIX and are given in octal per the POSIX standard. + + // permission bits + + owner_read = 0400, // S_IRUSR, Read permission, owner + owner_write = 0200, // S_IWUSR, Write permission, owner + owner_exe = 0100, // S_IXUSR, Execute/search permission, owner + owner_all = 0700, // S_IRWXU, Read, write, execute/search by owner + + group_read = 040, // S_IRGRP, Read permission, group + group_write = 020, // S_IWGRP, Write permission, group + group_exe = 010, // S_IXGRP, Execute/search permission, group + group_all = 070, // S_IRWXG, Read, write, execute/search by group + + others_read = 04, // S_IROTH, Read permission, others + others_write = 02, // S_IWOTH, Write permission, others + others_exe = 01, // S_IXOTH, Execute/search permission, others + others_all = 07, // S_IRWXO, Read, write, execute/search by others + + all_all = 0777, // owner_all|group_all|others_all + + // other POSIX bits + + set_uid_on_exe = 04000, // S_ISUID, Set-user-ID on execution + set_gid_on_exe = 02000, // S_ISGID, Set-group-ID on execution + sticky_bit = 01000, // S_ISVTX, + // (POSIX XSI) On directories, restricted deletion flag + // (V7) 'sticky bit': save swapped text even after use + // (SunOS) On non-directories: don't cache this file + // (SVID-v4.2) On directories: restricted deletion flag + // Also see http://en.wikipedia.org/wiki/Sticky_bit + + perms_mask = 07777, // all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit + + perms_not_known = 0xFFFF, // present when directory_entry cache not loaded + + // options for permissions() function + + add_perms = 0x1000, // adds the given permission bits to the current bits + remove_perms = 0x2000, // removes the given permission bits from the current bits; + // choose add_perms or remove_perms, not both; if neither add_perms + // nor remove_perms is given, replace the current bits with + // the given bits. + + symlink_perms = 0x4000 // on POSIX, don't resolve symlinks; implied on Windows + }; + + BOOST_BITMASK(perms) + +//--------------------------------------------------------------------------------------// +// file_status // +//--------------------------------------------------------------------------------------// + + class BOOST_FILESYSTEM_DECL file_status + { + public: + file_status() BOOST_NOEXCEPT + : m_value(status_error), m_perms(perms_not_known) {} + explicit file_status(file_type v) BOOST_NOEXCEPT + : m_value(v), m_perms(perms_not_known) {} + file_status(file_type v, perms prms) BOOST_NOEXCEPT + : m_value(v), m_perms(prms) {} + + // As of October 2015 the interaction between noexcept and =default is so troublesome + // for VC++, GCC, and probably other compilers, that =default is not used with noexcept + // functions. GCC is not even consistent for the same release on different platforms. + + file_status(const file_status& rhs) BOOST_NOEXCEPT + : m_value(rhs.m_value), m_perms(rhs.m_perms) {} + file_status& operator=(const file_status& rhs) BOOST_NOEXCEPT + { + m_value = rhs.m_value; + m_perms = rhs.m_perms; + return *this; + } + +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + file_status(file_status&& rhs) BOOST_NOEXCEPT + { + m_value = std::move(rhs.m_value); + m_perms = std::move(rhs.m_perms); + } + file_status& operator=(file_status&& rhs) BOOST_NOEXCEPT + { + m_value = std::move(rhs.m_value); + m_perms = std::move(rhs.m_perms); + return *this; + } +# endif + + + // observers + file_type type() const BOOST_NOEXCEPT { return m_value; } + perms permissions() const BOOST_NOEXCEPT { return m_perms; } + + // modifiers + void type(file_type v) BOOST_NOEXCEPT { m_value = v; } + void permissions(perms prms) BOOST_NOEXCEPT { m_perms = prms; } + + bool operator==(const file_status& rhs) const BOOST_NOEXCEPT + { return type() == rhs.type() && + permissions() == rhs.permissions(); } + bool operator!=(const file_status& rhs) const BOOST_NOEXCEPT + { return !(*this == rhs); } + + private: + file_type m_value; + enum perms m_perms; + }; + + inline bool type_present(file_status f) BOOST_NOEXCEPT + { return f.type() != status_error; } + inline bool permissions_present(file_status f) BOOST_NOEXCEPT + {return f.permissions() != perms_not_known;} + inline bool status_known(file_status f) BOOST_NOEXCEPT + { return type_present(f) && permissions_present(f); } + inline bool exists(file_status f) BOOST_NOEXCEPT + { return f.type() != status_error + && f.type() != file_not_found; } + inline bool is_regular_file(file_status f) BOOST_NOEXCEPT + { return f.type() == regular_file; } + inline bool is_directory(file_status f) BOOST_NOEXCEPT + { return f.type() == directory_file; } + inline bool is_symlink(file_status f) BOOST_NOEXCEPT + { return f.type() == symlink_file; } + inline bool is_other(file_status f) BOOST_NOEXCEPT + { return exists(f) && !is_regular_file(f) + && !is_directory(f) && !is_symlink(f); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool is_regular(file_status f) BOOST_NOEXCEPT { return f.type() == regular_file; } +# endif + + struct space_info + { + // all values are byte counts + boost::uintmax_t capacity; + boost::uintmax_t free; // <= capacity + boost::uintmax_t available; // <= free + }; + + BOOST_SCOPED_ENUM_START(copy_option) + {none=0, fail_if_exists = none, overwrite_if_exists}; + BOOST_SCOPED_ENUM_END + +//--------------------------------------------------------------------------------------// +// implementation details // +//--------------------------------------------------------------------------------------// + + namespace detail + { + // We cannot pass a BOOST_SCOPED_ENUM to a compled function because it will result + // in an undefined reference if the library is compled with -std=c++0x but the use + // is compiled in C++03 mode, or visa versa. See tickets 6124, 6779, 10038. + enum copy_option {none=0, fail_if_exists = none, overwrite_if_exists}; + + BOOST_FILESYSTEM_DECL + file_status status(const path&p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + file_status symlink_status(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool is_empty(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path initial_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path canonical(const path& p, const path& base, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy(const path& from, const path& to, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_directory(const path& from, const path& to, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_file(const path& from, const path& to, // See ticket #2925 + detail::copy_option option, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool create_directories(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool create_directory(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_directory_symlink(const path& to, const path& from, + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_hard_link(const path& to, const path& from, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void create_symlink(const path& to, const path& from, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path current_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void current_path(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + bool equivalent(const path& p1, const path& p2, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t file_size(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t hard_link_count(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + std::time_t last_write_time(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void last_write_time(const path& p, const std::time_t new_time, + system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void permissions(const path& p, perms prms, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path read_symlink(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path relative(const path& p, const path& base, system::error_code* ec = 0); + BOOST_FILESYSTEM_DECL + bool remove(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + boost::uintmax_t remove_all(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void rename(const path& old_p, const path& new_p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + void resize_file(const path& p, uintmax_t size, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + space_info space(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path system_complete(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path temp_directory_path(system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path unique_path(const path& p, system::error_code* ec=0); + BOOST_FILESYSTEM_DECL + path weakly_canonical(const path& p, system::error_code* ec = 0); + } // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// status query functions // +// // +//--------------------------------------------------------------------------------------// + + inline + file_status status(const path& p) {return detail::status(p);} + inline + file_status status(const path& p, system::error_code& ec) + {return detail::status(p, &ec);} + inline + file_status symlink_status(const path& p) {return detail::symlink_status(p);} + inline + file_status symlink_status(const path& p, system::error_code& ec) + {return detail::symlink_status(p, &ec);} + inline + bool exists(const path& p) {return exists(detail::status(p));} + inline + bool exists(const path& p, system::error_code& ec) + {return exists(detail::status(p, &ec));} + inline + bool is_directory(const path& p) {return is_directory(detail::status(p));} + inline + bool is_directory(const path& p, system::error_code& ec) + {return is_directory(detail::status(p, &ec));} + inline + bool is_regular_file(const path& p) {return is_regular_file(detail::status(p));} + inline + bool is_regular_file(const path& p, system::error_code& ec) + {return is_regular_file(detail::status(p, &ec));} + inline + bool is_other(const path& p) {return is_other(detail::status(p));} + inline + bool is_other(const path& p, system::error_code& ec) + {return is_other(detail::status(p, &ec));} + inline + bool is_symlink(const path& p) {return is_symlink(detail::symlink_status(p));} + inline + bool is_symlink(const path& p, system::error_code& ec) + {return is_symlink(detail::symlink_status(p, &ec));} +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline + bool is_regular(const path& p) {return is_regular(detail::status(p));} + inline + bool is_regular(const path& p, system::error_code& ec) + {return is_regular(detail::status(p, &ec));} +# endif + + inline + bool is_empty(const path& p) {return detail::is_empty(p);} + inline + bool is_empty(const path& p, system::error_code& ec) + {return detail::is_empty(p, &ec);} + +//--------------------------------------------------------------------------------------// +// // +// operational functions // +// in alphabetical order, unless otherwise noted // +// // +//--------------------------------------------------------------------------------------// + + // forward declarations + path current_path(); // fwd declaration + path initial_path(); + + BOOST_FILESYSTEM_DECL + path absolute(const path& p, const path& base=current_path()); + // If base.is_absolute(), throws nothing. Thus no need for ec argument + + inline + path canonical(const path& p, const path& base=current_path()) + {return detail::canonical(p, base);} + inline + path canonical(const path& p, system::error_code& ec) + {return detail::canonical(p, current_path(), &ec);} + inline + path canonical(const path& p, const path& base, system::error_code& ec) + {return detail::canonical(p, base, &ec);} + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline + path complete(const path& p) + { + return absolute(p, initial_path()); + } + + inline + path complete(const path& p, const path& base) + { + return absolute(p, base); + } +# endif + + inline + void copy(const path& from, const path& to) {detail::copy(from, to);} + + inline + void copy(const path& from, const path& to, system::error_code& ec) BOOST_NOEXCEPT + {detail::copy(from, to, &ec);} + inline + void copy_directory(const path& from, const path& to) + {detail::copy_directory(from, to);} + inline + void copy_directory(const path& from, const path& to, system::error_code& ec) BOOST_NOEXCEPT + {detail::copy_directory(from, to, &ec);} + inline + void copy_file(const path& from, const path& to, // See ticket #2925 + BOOST_SCOPED_ENUM(copy_option) option) + { + detail::copy_file(from, to, static_cast(option)); + } + inline + void copy_file(const path& from, const path& to) + { + detail::copy_file(from, to, detail::fail_if_exists); + } + inline + void copy_file(const path& from, const path& to, // See ticket #2925 + BOOST_SCOPED_ENUM(copy_option) option, system::error_code& ec) BOOST_NOEXCEPT + { + detail::copy_file(from, to, static_cast(option), &ec); + } + inline + void copy_file(const path& from, const path& to, system::error_code& ec) BOOST_NOEXCEPT + { + detail::copy_file(from, to, detail::fail_if_exists, &ec); + } + inline + void copy_symlink(const path& existing_symlink, + const path& new_symlink) {detail::copy_symlink(existing_symlink, new_symlink);} + + inline + void copy_symlink(const path& existing_symlink, const path& new_symlink, + system::error_code& ec) BOOST_NOEXCEPT + {detail::copy_symlink(existing_symlink, new_symlink, &ec);} + inline + bool create_directories(const path& p) {return detail::create_directories(p);} + + inline + bool create_directories(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::create_directories(p, &ec);} + inline + bool create_directory(const path& p) {return detail::create_directory(p);} + + inline + bool create_directory(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::create_directory(p, &ec);} + inline + void create_directory_symlink(const path& to, const path& from) + {detail::create_directory_symlink(to, from);} + inline + void create_directory_symlink(const path& to, const path& from, system::error_code& ec) BOOST_NOEXCEPT + {detail::create_directory_symlink(to, from, &ec);} + inline + void create_hard_link(const path& to, const path& new_hard_link) {detail::create_hard_link(to, new_hard_link);} + + inline + void create_hard_link(const path& to, const path& new_hard_link, system::error_code& ec) BOOST_NOEXCEPT + {detail::create_hard_link(to, new_hard_link, &ec);} + inline + void create_symlink(const path& to, const path& new_symlink) {detail::create_symlink(to, new_symlink);} + + inline + void create_symlink(const path& to, const path& new_symlink, system::error_code& ec) BOOST_NOEXCEPT + {detail::create_symlink(to, new_symlink, &ec);} + inline + path current_path() {return detail::current_path();} + + inline + path current_path(system::error_code& ec) BOOST_NOEXCEPT {return detail::current_path(&ec);} + + inline + void current_path(const path& p) {detail::current_path(p);} + + inline + void current_path(const path& p, system::error_code& ec) BOOST_NOEXCEPT {detail::current_path(p, &ec);} + + inline + bool equivalent(const path& p1, const path& p2) {return detail::equivalent(p1, p2);} + + inline + bool equivalent(const path& p1, const path& p2, system::error_code& ec) BOOST_NOEXCEPT + {return detail::equivalent(p1, p2, &ec);} + inline + boost::uintmax_t file_size(const path& p) {return detail::file_size(p);} + + inline + boost::uintmax_t file_size(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::file_size(p, &ec);} + inline + boost::uintmax_t hard_link_count(const path& p) {return detail::hard_link_count(p);} + + inline + boost::uintmax_t hard_link_count(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::hard_link_count(p, &ec);} + inline + path initial_path() {return detail::initial_path();} + + inline + path initial_path(system::error_code& ec) {return detail::initial_path(&ec);} + + template + path initial_path() {return initial_path();} + template + path initial_path(system::error_code& ec) {return detail::initial_path(&ec);} + + inline + std::time_t last_write_time(const path& p) {return detail::last_write_time(p);} + + inline + std::time_t last_write_time(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::last_write_time(p, &ec);} + inline + void last_write_time(const path& p, const std::time_t new_time) + {detail::last_write_time(p, new_time);} + inline + void last_write_time(const path& p, const std::time_t new_time, + system::error_code& ec) BOOST_NOEXCEPT + {detail::last_write_time(p, new_time, &ec);} + inline + void permissions(const path& p, perms prms) + {detail::permissions(p, prms);} + inline + void permissions(const path& p, perms prms, system::error_code& ec) BOOST_NOEXCEPT + {detail::permissions(p, prms, &ec);} + + inline + path read_symlink(const path& p) {return detail::read_symlink(p);} + + inline + path read_symlink(const path& p, system::error_code& ec) + {return detail::read_symlink(p, &ec);} + inline + // For standardization, if the committee doesn't like "remove", consider "eliminate" + bool remove(const path& p) {return detail::remove(p);} + + inline + bool remove(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::remove(p, &ec);} + + inline + boost::uintmax_t remove_all(const path& p) {return detail::remove_all(p);} + + inline + boost::uintmax_t remove_all(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::remove_all(p, &ec);} + inline + void rename(const path& old_p, const path& new_p) {detail::rename(old_p, new_p);} + + inline + void rename(const path& old_p, const path& new_p, system::error_code& ec) BOOST_NOEXCEPT + {detail::rename(old_p, new_p, &ec);} + inline // name suggested by Scott McMurray + void resize_file(const path& p, uintmax_t size) {detail::resize_file(p, size);} + + inline + void resize_file(const path& p, uintmax_t size, system::error_code& ec) BOOST_NOEXCEPT + {detail::resize_file(p, size, &ec);} + inline + path relative(const path& p, const path& base=current_path()) + {return detail::relative(p, base);} + inline + path relative(const path& p, system::error_code& ec) + {return detail::relative(p, current_path(), &ec);} + inline + path relative(const path& p, const path& base, system::error_code& ec) + {return detail::relative(p, base, &ec);} + inline + space_info space(const path& p) {return detail::space(p);} + + inline + space_info space(const path& p, system::error_code& ec) BOOST_NOEXCEPT + {return detail::space(p, &ec);} + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + inline bool symbolic_link_exists(const path& p) + { return is_symlink(symlink_status(p)); } +# endif + + inline + path system_complete(const path& p) {return detail::system_complete(p);} + + inline + path system_complete(const path& p, system::error_code& ec) + {return detail::system_complete(p, &ec);} + inline + path temp_directory_path() {return detail::temp_directory_path();} + + inline + path temp_directory_path(system::error_code& ec) + {return detail::temp_directory_path(&ec);} + inline + path unique_path(const path& p="%%%%-%%%%-%%%%-%%%%") + {return detail::unique_path(p);} + inline + path unique_path(const path& p, system::error_code& ec) + {return detail::unique_path(p, &ec);} + inline + path weakly_canonical(const path& p) {return detail::weakly_canonical(p);} + + inline + path weakly_canonical(const path& p, system::error_code& ec) + {return detail::weakly_canonical(p, &ec);} + +//--------------------------------------------------------------------------------------// +// // +// directory_entry // +// // +//--------------------------------------------------------------------------------------// + +// GCC has a problem with a member function named path within a namespace or +// sub-namespace that also has a class named path. The workaround is to always +// fully qualify the name path when it refers to the class name. + +class BOOST_FILESYSTEM_DECL directory_entry +{ +public: + typedef boost::filesystem::path::value_type value_type; // enables class path ctor taking directory_entry + + directory_entry() BOOST_NOEXCEPT {} + explicit directory_entry(const boost::filesystem::path& p) + : m_path(p), m_status(file_status()), m_symlink_status(file_status()) + {} + directory_entry(const boost::filesystem::path& p, + file_status st, file_status symlink_st = file_status()) + : m_path(p), m_status(st), m_symlink_status(symlink_st) {} + + directory_entry(const directory_entry& rhs) + : m_path(rhs.m_path), m_status(rhs.m_status), m_symlink_status(rhs.m_symlink_status){} + + directory_entry& operator=(const directory_entry& rhs) + { + m_path = rhs.m_path; + m_status = rhs.m_status; + m_symlink_status = rhs.m_symlink_status; + return *this; + } + + // As of October 2015 the interaction between noexcept and =default is so troublesome + // for VC++, GCC, and probably other compilers, that =default is not used with noexcept + // functions. GCC is not even consistent for the same release on different platforms. + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + directory_entry(directory_entry&& rhs) BOOST_NOEXCEPT + { + m_path = std::move(rhs.m_path); + m_status = std::move(rhs.m_status); + m_symlink_status = std::move(rhs.m_symlink_status); + } + directory_entry& operator=(directory_entry&& rhs) BOOST_NOEXCEPT + { + m_path = std::move(rhs.m_path); + m_status = std::move(rhs.m_status); + m_symlink_status = std::move(rhs.m_symlink_status); + return *this; + } +#endif + + void assign(const boost::filesystem::path& p, + file_status st = file_status(), file_status symlink_st = file_status()) + { m_path = p; m_status = st; m_symlink_status = symlink_st; } + + void replace_filename(const boost::filesystem::path& p, + file_status st = file_status(), file_status symlink_st = file_status()) + { + m_path.remove_filename(); + m_path /= p; + m_status = st; + m_symlink_status = symlink_st; + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + void replace_leaf(const boost::filesystem::path& p, + file_status st, file_status symlink_st) + { replace_filename(p, st, symlink_st); } +# endif + + const boost::filesystem::path& path() const BOOST_NOEXCEPT {return m_path;} + operator const boost::filesystem::path&() const BOOST_NOEXCEPT + {return m_path;} + file_status status() const {return m_get_status();} + file_status status(system::error_code& ec) const BOOST_NOEXCEPT + {return m_get_status(&ec); } + file_status symlink_status() const {return m_get_symlink_status();} + file_status symlink_status(system::error_code& ec) const BOOST_NOEXCEPT + {return m_get_symlink_status(&ec); } + + bool operator==(const directory_entry& rhs) const BOOST_NOEXCEPT {return m_path == rhs.m_path; } + bool operator!=(const directory_entry& rhs) const BOOST_NOEXCEPT {return m_path != rhs.m_path;} + bool operator< (const directory_entry& rhs) const BOOST_NOEXCEPT {return m_path < rhs.m_path;} + bool operator<=(const directory_entry& rhs) const BOOST_NOEXCEPT {return m_path <= rhs.m_path;} + bool operator> (const directory_entry& rhs) const BOOST_NOEXCEPT {return m_path > rhs.m_path;} + bool operator>=(const directory_entry& rhs) const BOOST_NOEXCEPT {return m_path >= rhs.m_path;} + +private: + boost::filesystem::path m_path; + mutable file_status m_status; // stat()-like + mutable file_status m_symlink_status; // lstat()-like + + file_status m_get_status(system::error_code* ec=0) const; + file_status m_get_symlink_status(system::error_code* ec=0) const; +}; // directory_entry + +//--------------------------------------------------------------------------------------// +// // +// directory_iterator helpers // +// // +//--------------------------------------------------------------------------------------// + +class directory_iterator; + +namespace detail +{ + BOOST_FILESYSTEM_DECL + system::error_code dir_itr_close(// never throws() + void *& handle +# if defined(BOOST_POSIX_API) + , void *& buffer +# endif + ); + + struct dir_itr_imp + { + directory_entry dir_entry; + void* handle; + +# ifdef BOOST_POSIX_API + void* buffer; // see dir_itr_increment implementation +# endif + + dir_itr_imp() : handle(0) +# ifdef BOOST_POSIX_API + , buffer(0) +# endif + {} + + ~dir_itr_imp() // never throws + { + dir_itr_close(handle +# if defined(BOOST_POSIX_API) + , buffer +# endif + ); + } + }; + + // see path::iterator: comment below + BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it, + const path& p, system::error_code* ec); + BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it, + system::error_code* ec); + +} // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// directory_iterator // +// // +//--------------------------------------------------------------------------------------// + + class directory_iterator + : public boost::iterator_facade< directory_iterator, + directory_entry, + boost::single_pass_traversal_tag > + { + public: + + directory_iterator() BOOST_NOEXCEPT {} // creates the "end" iterator + + // iterator_facade derived classes don't seem to like implementations in + // separate translation unit dll's, so forward to detail functions + explicit directory_iterator(const path& p) + : m_imp(new detail::dir_itr_imp) + { detail::directory_iterator_construct(*this, p, 0); } + + directory_iterator(const path& p, system::error_code& ec) BOOST_NOEXCEPT + : m_imp(new detail::dir_itr_imp) + { detail::directory_iterator_construct(*this, p, &ec); } + + ~directory_iterator() {} + + directory_iterator& increment(system::error_code& ec) BOOST_NOEXCEPT + { + detail::directory_iterator_increment(*this, &ec); + return *this; + } + + private: + friend struct detail::dir_itr_imp; + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_construct(directory_iterator& it, + const path& p, system::error_code* ec); + friend BOOST_FILESYSTEM_DECL void detail::directory_iterator_increment(directory_iterator& it, + system::error_code* ec); + + // shared_ptr provides the shallow-copy semantics required for single pass iterators + // (i.e. InputIterators). The end iterator is indicated by !m_imp || !m_imp->handle + boost::shared_ptr< detail::dir_itr_imp > m_imp; + + friend class boost::iterator_core_access; + + boost::iterator_facade< + directory_iterator, + directory_entry, + boost::single_pass_traversal_tag >::reference dereference() const + { + BOOST_ASSERT_MSG(m_imp.get(), "attempt to dereference end iterator"); + return m_imp->dir_entry; + } + + void increment() { detail::directory_iterator_increment(*this, 0); } + + bool equal(const directory_iterator& rhs) const + { + return m_imp == rhs.m_imp + || (!m_imp && rhs.m_imp && !rhs.m_imp->handle) + || (!rhs.m_imp && m_imp && !m_imp->handle); + } + + }; // directory_iterator + + // enable directory_iterator C++11 range-base for statement use --------------------// + + // begin() and end() are only used by a range-based for statement in the context of + // auto - thus the top-level const is stripped - so returning const is harmless and + // emphasizes begin() is just a pass through. + inline + const directory_iterator& begin(const directory_iterator& iter) BOOST_NOEXCEPT + {return iter;} + inline + directory_iterator end(const directory_iterator&) BOOST_NOEXCEPT + {return directory_iterator();} + + // enable directory_iterator BOOST_FOREACH -----------------------------------------// + + inline + directory_iterator& range_begin(directory_iterator& iter) BOOST_NOEXCEPT + {return iter;} + inline + directory_iterator range_begin(const directory_iterator& iter) BOOST_NOEXCEPT + {return iter;} + inline + directory_iterator range_end(const directory_iterator&) BOOST_NOEXCEPT + {return directory_iterator();} + } // namespace filesystem + + // namespace boost template specializations + template<> + struct range_mutable_iterator + { typedef boost::filesystem::directory_iterator type; }; + template<> + struct range_const_iterator + { typedef boost::filesystem::directory_iterator type; }; + +namespace filesystem +{ + +//--------------------------------------------------------------------------------------// +// // +// recursive_directory_iterator helpers // +// // +//--------------------------------------------------------------------------------------// + + BOOST_SCOPED_ENUM_START(symlink_option) + { + none, + no_recurse = none, // don't follow directory symlinks (default behavior) + recurse, // follow directory symlinks + _detail_no_push = recurse << 1 // internal use only + }; + BOOST_SCOPED_ENUM_END + + BOOST_BITMASK(BOOST_SCOPED_ENUM(symlink_option)) + + namespace detail + { + struct recur_dir_itr_imp + { + typedef directory_iterator element_type; + std::stack< element_type, std::vector< element_type > > m_stack; + int m_level; + BOOST_SCOPED_ENUM(symlink_option) m_options; + + recur_dir_itr_imp() : m_level(0), m_options(symlink_option::none) {} + + void increment(system::error_code* ec); // ec == 0 means throw on error + + bool push_directory(system::error_code& ec) BOOST_NOEXCEPT; + + void pop(); + + }; + + // Implementation is inline to avoid dynamic linking difficulties with m_stack: + // Microsoft warning C4251, m_stack needs to have dll-interface to be used by + // clients of struct 'boost::filesystem::detail::recur_dir_itr_imp' + + inline + bool recur_dir_itr_imp::push_directory(system::error_code& ec) BOOST_NOEXCEPT + // Returns: true if push occurs, otherwise false. Always returns false on error. + { + ec.clear(); + + // Discover if the iterator is for a directory that needs to be recursed into, + // taking symlinks and options into account. + + if ((m_options & symlink_option::_detail_no_push) == symlink_option::_detail_no_push) + { + m_options &= ~symlink_option::_detail_no_push; + return false; + } + + file_status symlink_stat; + + // if we are not recursing into symlinks, we are going to have to know if the + // stack top is a symlink, so get symlink_status and verify no error occurred + if ((m_options & symlink_option::recurse) != symlink_option::recurse) + { + symlink_stat = m_stack.top()->symlink_status(ec); + if (ec) + return false; + } + + // Logic for following predicate was contributed by Daniel Aarno to handle cyclic + // symlinks correctly and efficiently, fixing ticket #5652. + // if (((m_options & symlink_option::recurse) == symlink_option::recurse + // || !is_symlink(m_stack.top()->symlink_status())) + // && is_directory(m_stack.top()->status())) ... + // The predicate code has since been rewritten to pass error_code arguments, + // per ticket #5653. + + if ((m_options & symlink_option::recurse) == symlink_option::recurse + || !is_symlink(symlink_stat)) + { + file_status stat = m_stack.top()->status(ec); + if (ec || !is_directory(stat)) + return false; + + directory_iterator next(m_stack.top()->path(), ec); + if (!ec && next != directory_iterator()) + { + m_stack.push(next); + ++m_level; + return true; + } + } + return false; + } + + inline + void recur_dir_itr_imp::increment(system::error_code* ec) + // ec == 0 means throw on error + // + // Invariant: On return, the top of the iterator stack is the next valid (possibly + // end) iterator, regardless of whether or not an error is reported, and regardless of + // whether any error is reported by exception or error code. In other words, progress + // is always made so a loop on the iterator will always eventually terminate + // regardless of errors. + { + system::error_code ec_push_directory; + + // if various conditions are met, push a directory_iterator into the iterator stack + if (push_directory(ec_push_directory)) + { + if (ec) + ec->clear(); + return; + } + + // Do the actual increment operation on the top iterator in the iterator + // stack, popping the stack if necessary, until either the stack is empty or a + // non-end iterator is reached. + while (!m_stack.empty() && ++m_stack.top() == directory_iterator()) + { + m_stack.pop(); + --m_level; + } + + // report errors if any + if (ec_push_directory) + { + if (ec) + *ec = ec_push_directory; + else + { + BOOST_FILESYSTEM_THROW(filesystem_error( + "filesystem::recursive_directory_iterator directory error", + ec_push_directory)); + } + } + else if (ec) + ec->clear(); + } + + inline + void recur_dir_itr_imp::pop() + { + BOOST_ASSERT_MSG(m_level > 0, + "pop() on recursive_directory_iterator with level < 1"); + + do + { + m_stack.pop(); + --m_level; + } + while (!m_stack.empty() && ++m_stack.top() == directory_iterator()); + } + } // namespace detail + +//--------------------------------------------------------------------------------------// +// // +// recursive_directory_iterator // +// // +//--------------------------------------------------------------------------------------// + + class recursive_directory_iterator + : public boost::iterator_facade< + recursive_directory_iterator, + directory_entry, + boost::single_pass_traversal_tag > + { + public: + + recursive_directory_iterator() BOOST_NOEXCEPT {} // creates the "end" iterator + + explicit recursive_directory_iterator(const path& dir_path) // throws if !exists() + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_options = symlink_option::none; + m_imp->m_stack.push(directory_iterator(dir_path)); + if (m_imp->m_stack.top() == directory_iterator()) + { m_imp.reset(); } + } + + recursive_directory_iterator(const path& dir_path, + BOOST_SCOPED_ENUM(symlink_option) opt) // throws if !exists() + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_options = opt; + m_imp->m_stack.push(directory_iterator(dir_path)); + if (m_imp->m_stack.top() == directory_iterator()) + { m_imp.reset (); } + } + + recursive_directory_iterator(const path& dir_path, + BOOST_SCOPED_ENUM(symlink_option) opt, + system::error_code & ec) BOOST_NOEXCEPT + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_options = opt; + m_imp->m_stack.push(directory_iterator(dir_path, ec)); + if (m_imp->m_stack.top() == directory_iterator()) + { m_imp.reset (); } + } + + recursive_directory_iterator(const path& dir_path, + system::error_code & ec) BOOST_NOEXCEPT + : m_imp(new detail::recur_dir_itr_imp) + { + m_imp->m_options = symlink_option::none; + m_imp->m_stack.push(directory_iterator(dir_path, ec)); + if (m_imp->m_stack.top() == directory_iterator()) + { m_imp.reset (); } + } + + recursive_directory_iterator& increment(system::error_code& ec) BOOST_NOEXCEPT + { + BOOST_ASSERT_MSG(m_imp.get(), + "increment() on end recursive_directory_iterator"); + m_imp->increment(&ec); + if (m_imp->m_stack.empty()) + m_imp.reset(); // done, so make end iterator + return *this; + } + + int depth() const BOOST_NOEXCEPT + { + BOOST_ASSERT_MSG(m_imp.get(), + "depth() on end recursive_directory_iterator"); + return m_imp->m_level; + } + + int level() const BOOST_NOEXCEPT { return depth(); } + + bool recursion_pending() const BOOST_NOEXCEPT + { + BOOST_ASSERT_MSG(m_imp.get(), + "is_no_push_requested() on end recursive_directory_iterator"); + return (m_imp->m_options & symlink_option::_detail_no_push) + == symlink_option::_detail_no_push; + } + + bool no_push_pending() const BOOST_NOEXCEPT { return recursion_pending(); } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + bool no_push_request() const BOOST_NOEXCEPT { return no_push_pending(); } +# endif + + void pop() + { + BOOST_ASSERT_MSG(m_imp.get(), + "pop() on end recursive_directory_iterator"); + m_imp->pop(); + if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator + } + + void disable_recursion_pending(bool value=true) BOOST_NOEXCEPT + { + BOOST_ASSERT_MSG(m_imp.get(), + "no_push() on end recursive_directory_iterator"); + if (value) + m_imp->m_options |= symlink_option::_detail_no_push; + else + m_imp->m_options &= ~symlink_option::_detail_no_push; + } + + void no_push(bool value=true) BOOST_NOEXCEPT { disable_recursion_pending(value); } + + file_status status() const + { + BOOST_ASSERT_MSG(m_imp.get(), + "status() on end recursive_directory_iterator"); + return m_imp->m_stack.top()->status(); + } + + file_status symlink_status() const + { + BOOST_ASSERT_MSG(m_imp.get(), + "symlink_status() on end recursive_directory_iterator"); + return m_imp->m_stack.top()->symlink_status(); + } + + private: + + // shared_ptr provides the shallow-copy semantics required for single pass iterators + // (i.e. InputIterators). + // The end iterator is indicated by !m_imp || m_imp->m_stack.empty() + boost::shared_ptr< detail::recur_dir_itr_imp > m_imp; + + friend class boost::iterator_core_access; + + boost::iterator_facade< + recursive_directory_iterator, + directory_entry, + boost::single_pass_traversal_tag >::reference + dereference() const + { + BOOST_ASSERT_MSG(m_imp.get(), + "dereference of end recursive_directory_iterator"); + return *m_imp->m_stack.top(); + } + + void increment() + { + BOOST_ASSERT_MSG(m_imp.get(), + "increment of end recursive_directory_iterator"); + m_imp->increment(0); + if (m_imp->m_stack.empty()) + m_imp.reset(); // done, so make end iterator + } + + bool equal(const recursive_directory_iterator& rhs) const + { + return m_imp == rhs.m_imp + || (!m_imp && rhs.m_imp && rhs.m_imp->m_stack.empty()) + || (!rhs.m_imp && m_imp && m_imp->m_stack.empty()) ; + } + + }; // recursive directory iterator + + // enable recursive directory iterator C++11 range-base for statement use ----------// + + // begin() and end() are only used by a range-based for statement in the context of + // auto - thus the top-level const is stripped - so returning const is harmless and + // emphasizes begin() is just a pass through. + inline + const recursive_directory_iterator& + begin(const recursive_directory_iterator& iter) BOOST_NOEXCEPT + {return iter;} + inline + recursive_directory_iterator end(const recursive_directory_iterator&) BOOST_NOEXCEPT + {return recursive_directory_iterator();} + + // enable recursive directory iterator BOOST_FOREACH -------------------------------// + + inline + recursive_directory_iterator& + range_begin(recursive_directory_iterator& iter) BOOST_NOEXCEPT + {return iter;} + inline + recursive_directory_iterator + range_begin(const recursive_directory_iterator& iter) BOOST_NOEXCEPT + {return iter;} + inline + recursive_directory_iterator range_end(const recursive_directory_iterator&) BOOST_NOEXCEPT + {return recursive_directory_iterator();} + } // namespace filesystem + + // namespace boost template specializations + template<> + struct range_mutable_iterator + { typedef boost::filesystem::recursive_directory_iterator type; }; + template<> + struct range_const_iterator + { typedef boost::filesystem::recursive_directory_iterator type; }; + +namespace filesystem +{ + +# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + typedef recursive_directory_iterator wrecursive_directory_iterator; +# endif + +// test helper -----------------------------------------------------------------------// + +// Not part of the documented interface since false positives are possible; +// there is no law that says that an OS that has large stat.st_size +// actually supports large file sizes. + + namespace detail + { + BOOST_FILESYSTEM_DECL bool possible_large_file_size_support(); + } + + } // namespace filesystem +} // namespace boost + +#include // pops abi_prefix.hpp pragmas +#endif // BOOST_FILESYSTEM3_OPERATIONS_HPP diff --git a/boost/filesystem/path.hpp b/boost/filesystem/path.hpp new file mode 100644 index 00000000..65e27b17 --- /dev/null +++ b/boost/filesystem/path.hpp @@ -0,0 +1,1015 @@ +// filesystem path.hpp ---------------------------------------------------------------// + +// Copyright Beman Dawes 2002-2005, 2009 +// Copyright Vladimir Prus 2002 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +// path::stem(), extension(), and replace_extension() are based on +// basename(), extension(), and change_extension() from the original +// filesystem/convenience.hpp header by Vladimir Prus. + +#ifndef BOOST_FILESYSTEM_PATH_HPP +#define BOOST_FILESYSTEM_PATH_HPP + +#include + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include +#include // includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // must be the last #include + +namespace boost +{ +namespace filesystem +{ + + //------------------------------------------------------------------------------------// + // // + // class path // + // // + //------------------------------------------------------------------------------------// + + class BOOST_FILESYSTEM_DECL path + { + public: + + // value_type is the character type used by the operating system API to + // represent paths. + +# ifdef BOOST_WINDOWS_API + typedef wchar_t value_type; + BOOST_STATIC_CONSTEXPR value_type separator = L'/'; + BOOST_STATIC_CONSTEXPR value_type preferred_separator = L'\\'; + BOOST_STATIC_CONSTEXPR value_type dot = L'.'; +# else + typedef char value_type; + BOOST_STATIC_CONSTEXPR value_type separator = '/'; + BOOST_STATIC_CONSTEXPR value_type preferred_separator = '/'; + BOOST_STATIC_CONSTEXPR value_type dot = '.'; +# endif + typedef std::basic_string string_type; + typedef std::codecvt codecvt_type; + + + // ----- character encoding conversions ----- + + // Following the principle of least astonishment, path input arguments + // passed to or obtained from the operating system via objects of + // class path behave as if they were directly passed to or + // obtained from the O/S API, unless conversion is explicitly requested. + // + // POSIX specfies that path strings are passed unchanged to and from the + // API. Note that this is different from the POSIX command line utilities, + // which convert according to a locale. + // + // Thus for POSIX, char strings do not undergo conversion. wchar_t strings + // are converted to/from char using the path locale or, if a conversion + // argument is given, using a conversion object modeled on + // std::wstring_convert. + // + // The path locale, which is global to the thread, can be changed by the + // imbue() function. It is initialized to an implementation defined locale. + // + // For Windows, wchar_t strings do not undergo conversion. char strings + // are converted using the "ANSI" or "OEM" code pages, as determined by + // the AreFileApisANSI() function, or, if a conversion argument is given, + // using a conversion object modeled on std::wstring_convert. + // + // See m_pathname comments for further important rationale. + + // TODO: rules needed for operating systems that use / or . + // differently, or format directory paths differently from file paths. + // + // ********************************************************************************** + // + // More work needed: How to handle an operating system that may have + // slash characters or dot characters in valid filenames, either because + // it doesn't follow the POSIX standard, or because it allows MBCS + // filename encodings that may contain slash or dot characters. For + // example, ISO/IEC 2022 (JIS) encoding which allows switching to + // JIS x0208-1983 encoding. A valid filename in this set of encodings is + // 0x1B 0x24 0x42 [switch to X0208-1983] 0x24 0x2F [U+304F Kiragana letter KU] + // ^^^^ + // Note that 0x2F is the ASCII slash character + // + // ********************************************************************************** + + // Supported source arguments: half-open iterator range, container, c-array, + // and single pointer to null terminated string. + + // All source arguments except pointers to null terminated byte strings support + // multi-byte character strings which may have embedded nulls. Embedded null + // support is required for some Asian languages on Windows. + + // "const codecvt_type& cvt=codecvt()" default arguments are not used because this + // limits the impact of locale("") initialization failures on POSIX systems to programs + // that actually depend on locale(""). It further ensures that exceptions thrown + // as a result of such failues occur after main() has started, so can be caught. + + // ----- constructors ----- + + path() BOOST_NOEXCEPT {} + path(const path& p) : m_pathname(p.m_pathname) {} + + template + path(Source const& source, + typename boost::enable_if::type> >::type* =0) + { + path_traits::dispatch(source, m_pathname); + } + + path(const value_type* s) : m_pathname(s) {} + path(value_type* s) : m_pathname(s) {} + path(const string_type& s) : m_pathname(s) {} + path(string_type& s) : m_pathname(s) {} + + // As of October 2015 the interaction between noexcept and =default is so troublesome + // for VC++, GCC, and probably other compilers, that =default is not used with noexcept + // functions. GCC is not even consistent for the same release on different platforms. + +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + path(path&& p) BOOST_NOEXCEPT { m_pathname = std::move(p.m_pathname); } + path& operator=(path&& p) BOOST_NOEXCEPT + { m_pathname = std::move(p.m_pathname); return *this; } +# endif + + template + path(Source const& source, const codecvt_type& cvt) + { + path_traits::dispatch(source, m_pathname, cvt); + } + + template + path(InputIterator begin, InputIterator end) + { + if (begin != end) + { + // convert requires contiguous string, so copy + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname); + } + } + + template + path(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + if (begin != end) + { + // convert requires contiguous string, so copy + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt); + } + } + + // ----- assignments ----- + + path& operator=(const path& p) + { + m_pathname = p.m_pathname; + return *this; + } + + template + typename boost::enable_if::type>, path&>::type + operator=(Source const& source) + { + m_pathname.clear(); + path_traits::dispatch(source, m_pathname); + return *this; + } + + // value_type overloads + + path& operator=(const value_type* ptr) // required in case ptr overlaps *this + {m_pathname = ptr; return *this;} + path& operator=(value_type* ptr) // required in case ptr overlaps *this + {m_pathname = ptr; return *this;} + path& operator=(const string_type& s) {m_pathname = s; return *this;} + path& operator=(string_type& s) {m_pathname = s; return *this;} + + path& assign(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this + {m_pathname = ptr; return *this;} + template + path& assign(Source const& source, const codecvt_type& cvt) + { + m_pathname.clear(); + path_traits::dispatch(source, m_pathname, cvt); + return *this; + } + + template + path& assign(InputIterator begin, InputIterator end) + { + m_pathname.clear(); + if (begin != end) + { + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname); + } + return *this; + } + + template + path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + m_pathname.clear(); + if (begin != end) + { + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt); + } + return *this; + } + + // ----- concatenation ----- + + template + typename boost::enable_if::type>, path&>::type + operator+=(Source const& source) + { + return concat(source); + } + + // value_type overloads. Same rationale as for constructors above + path& operator+=(const path& p) { m_pathname += p.m_pathname; return *this; } + path& operator+=(const value_type* ptr) { m_pathname += ptr; return *this; } + path& operator+=(value_type* ptr) { m_pathname += ptr; return *this; } + path& operator+=(const string_type& s) { m_pathname += s; return *this; } + path& operator+=(string_type& s) { m_pathname += s; return *this; } + path& operator+=(value_type c) { m_pathname += c; return *this; } + + template + typename boost::enable_if, path&>::type + operator+=(CharT c) + { + CharT tmp[2]; + tmp[0] = c; + tmp[1] = 0; + return concat(tmp); + } + + template + path& concat(Source const& source) + { + path_traits::dispatch(source, m_pathname); + return *this; + } + + template + path& concat(Source const& source, const codecvt_type& cvt) + { + path_traits::dispatch(source, m_pathname, cvt); + return *this; + } + + template + path& concat(InputIterator begin, InputIterator end) + { + if (begin == end) + return *this; + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname); + return *this; + } + + template + path& concat(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + if (begin == end) + return *this; + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt); + return *this; + } + + // ----- appends ----- + + // if a separator is added, it is the preferred separator for the platform; + // slash for POSIX, backslash for Windows + + path& operator/=(const path& p); + + template + typename boost::enable_if::type>, path&>::type + operator/=(Source const& source) + { + return append(source); + } + + path& operator/=(const value_type* ptr); + path& operator/=(value_type* ptr) + { + return this->operator/=(const_cast(ptr)); + } + path& operator/=(const string_type& s) { return this->operator/=(path(s)); } + path& operator/=(string_type& s) { return this->operator/=(path(s)); } + + path& append(const value_type* ptr) // required in case ptr overlaps *this + { + this->operator/=(ptr); + return *this; + } + + path& append(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this + { + this->operator/=(ptr); + return *this; + } + + template + path& append(Source const& source); + + template + path& append(Source const& source, const codecvt_type& cvt); + + template + path& append(InputIterator begin, InputIterator end); + + template + path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt); + + // ----- modifiers ----- + + void clear() BOOST_NOEXCEPT { m_pathname.clear(); } + path& make_preferred() +# ifdef BOOST_POSIX_API + { return *this; } // POSIX no effect +# else // BOOST_WINDOWS_API + ; // change slashes to backslashes +# endif + path& remove_filename(); + path& remove_trailing_separator(); + path& replace_extension(const path& new_extension = path()); + void swap(path& rhs) BOOST_NOEXCEPT { m_pathname.swap(rhs.m_pathname); } + + // ----- observers ----- + + // For operating systems that format file paths differently than directory + // paths, return values from observers are formatted as file names unless there + // is a trailing separator, in which case returns are formatted as directory + // paths. POSIX and Windows make no such distinction. + + // Implementations are permitted to return const values or const references. + + // The string or path returned by an observer are specified as being formatted + // as "native" or "generic". + // + // For POSIX, these are all the same format; slashes and backslashes are as input and + // are not modified. + // + // For Windows, native: as input; slashes and backslashes are not modified; + // this is the format of the internally stored string. + // generic: backslashes are converted to slashes + + // ----- native format observers ----- + + const string_type& native() const BOOST_NOEXCEPT { return m_pathname; } + const value_type* c_str() const BOOST_NOEXCEPT { return m_pathname.c_str(); } + string_type::size_type size() const BOOST_NOEXCEPT { return m_pathname.size(); } + + template + String string() const; + + template + String string(const codecvt_type& cvt) const; + +# ifdef BOOST_WINDOWS_API + const std::string string() const + { + std::string tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp); + return tmp; + } + const std::string string(const codecvt_type& cvt) const + { + std::string tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp, cvt); + return tmp; + } + + // string_type is std::wstring, so there is no conversion + const std::wstring& wstring() const { return m_pathname; } + const std::wstring& wstring(const codecvt_type&) const { return m_pathname; } + +# else // BOOST_POSIX_API + // string_type is std::string, so there is no conversion + const std::string& string() const { return m_pathname; } + const std::string& string(const codecvt_type&) const { return m_pathname; } + + const std::wstring wstring() const + { + std::wstring tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp); + return tmp; + } + const std::wstring wstring(const codecvt_type& cvt) const + { + std::wstring tmp; + if (!m_pathname.empty()) + path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), + tmp, cvt); + return tmp; + } + +# endif + + // ----- generic format observers ----- + + // Experimental generic function returning generic formatted path (i.e. separators + // are forward slashes). Motivation: simpler than a family of generic_*string + // functions. + path generic_path() const + { +# ifdef BOOST_WINDOWS_API + path tmp; + std::replace_copy(m_pathname.begin(), m_pathname.end(), + std::back_inserter(tmp.m_pathname), L'\\', L'/'); + return tmp; +# else + return path(*this); +# endif + } + + template + String generic_string() const; + + template + String generic_string(const codecvt_type& cvt) const; + +# ifdef BOOST_WINDOWS_API + const std::string generic_string() const; + const std::string generic_string(const codecvt_type& cvt) const; + const std::wstring generic_wstring() const; + const std::wstring generic_wstring(const codecvt_type&) const { return generic_wstring(); }; + +# else // BOOST_POSIX_API + // On POSIX-like systems, the generic format is the same as the native format + const std::string& generic_string() const { return m_pathname; } + const std::string& generic_string(const codecvt_type&) const { return m_pathname; } + const std::wstring generic_wstring() const { return wstring(); } + const std::wstring generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); } + +# endif + + // ----- compare ----- + + int compare(const path& p) const BOOST_NOEXCEPT; // generic, lexicographical + int compare(const std::string& s) const { return compare(path(s)); } + int compare(const value_type* s) const { return compare(path(s)); } + + // ----- decomposition ----- + + path root_path() const; + path root_name() const; // returns 0 or 1 element path + // even on POSIX, root_name() is non-empty() for network paths + path root_directory() const; // returns 0 or 1 element path + path relative_path() const; + path parent_path() const; + path filename() const; // returns 0 or 1 element path + path stem() const; // returns 0 or 1 element path + path extension() const; // returns 0 or 1 element path + + // ----- query ----- + + bool empty() const BOOST_NOEXCEPT{ return m_pathname.empty(); } + bool filename_is_dot() const; + bool filename_is_dot_dot() const; + bool has_root_path() const { return has_root_directory() || has_root_name(); } + bool has_root_name() const { return !root_name().empty(); } + bool has_root_directory() const { return !root_directory().empty(); } + bool has_relative_path() const { return !relative_path().empty(); } + bool has_parent_path() const { return !parent_path().empty(); } + bool has_filename() const { return !m_pathname.empty(); } + bool has_stem() const { return !stem().empty(); } + bool has_extension() const { return !extension().empty(); } + bool is_relative() const { return !is_absolute(); } + bool is_absolute() const + { +# ifdef BOOST_WINDOWS_API + return has_root_name() && has_root_directory(); +# else + return has_root_directory(); +# endif + } + + // ----- lexical operations ----- + + path lexically_normal() const; + path lexically_relative(const path& base) const; + path lexically_proximate(const path& base) const + { + path tmp(lexically_relative(base)); + return tmp.empty() ? *this : tmp; + } + + // ----- iterators ----- + + class iterator; + typedef iterator const_iterator; + class reverse_iterator; + typedef reverse_iterator const_reverse_iterator; + + iterator begin() const; + iterator end() const; + reverse_iterator rbegin() const; + reverse_iterator rend() const; + + // ----- static member functions ----- + + static std::locale imbue(const std::locale& loc); + static const codecvt_type& codecvt(); + + // ----- deprecated functions ----- + +# if defined(BOOST_FILESYSTEM_DEPRECATED) && defined(BOOST_FILESYSTEM_NO_DEPRECATED) +# error both BOOST_FILESYSTEM_DEPRECATED and BOOST_FILESYSTEM_NO_DEPRECATED are defined +# endif + +# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + // recently deprecated functions supplied by default + path& normalize() { + path tmp(lexically_normal()); + m_pathname.swap(tmp.m_pathname); + return *this; + } + path& remove_leaf() { return remove_filename(); } + path leaf() const { return filename(); } + path branch_path() const { return parent_path(); } + path generic() const { return generic_path(); } + bool has_leaf() const { return !m_pathname.empty(); } + bool has_branch_path() const { return !parent_path().empty(); } + bool is_complete() const { return is_absolute(); } +# endif + +# if defined(BOOST_FILESYSTEM_DEPRECATED) + // deprecated functions with enough signature or semantic changes that they are + // not supplied by default + const std::string file_string() const { return string(); } + const std::string directory_string() const { return string(); } + const std::string native_file_string() const { return string(); } + const std::string native_directory_string() const { return string(); } + const string_type external_file_string() const { return native(); } + const string_type external_directory_string() const { return native(); } + + // older functions no longer supported + //typedef bool (*name_check)(const std::string & name); + //basic_path(const string_type& str, name_check) { operator/=(str); } + //basic_path(const typename string_type::value_type* s, name_check) + // { operator/=(s);} + //static bool default_name_check_writable() { return false; } + //static void default_name_check(name_check) {} + //static name_check default_name_check() { return 0; } + //basic_path& canonize(); +# endif + +//--------------------------------------------------------------------------------------// +// class path private members // +//--------------------------------------------------------------------------------------// + + private: + +# if defined(_MSC_VER) +# pragma warning(push) // Save warning settings +# pragma warning(disable : 4251) // disable warning: class 'std::basic_string<_Elem,_Traits,_Ax>' +# endif // needs to have dll-interface... +/* + m_pathname has the type, encoding, and format required by the native + operating system. Thus for POSIX and Windows there is no conversion for + passing m_pathname.c_str() to the O/S API or when obtaining a path from the + O/S API. POSIX encoding is unspecified other than for dot and slash + characters; POSIX just treats paths as a sequence of bytes. Windows + encoding is UCS-2 or UTF-16 depending on the version. +*/ + string_type m_pathname; // Windows: as input; backslashes NOT converted to slashes, + // slashes NOT converted to backslashes +# if defined(_MSC_VER) +# pragma warning(pop) // restore warning settings. +# endif + + string_type::size_type m_append_separator_if_needed(); + // Returns: If separator is to be appended, m_pathname.size() before append. Otherwise 0. + // Note: An append is never performed if size()==0, so a returned 0 is unambiguous. + + void m_erase_redundant_separator(string_type::size_type sep_pos); + string_type::size_type m_parent_path_end() const; + + path& m_normalize(); + + // Was qualified; como433beta8 reports: + // warning #427-D: qualified name is not allowed in member declaration + friend class iterator; + friend bool operator<(const path& lhs, const path& rhs); + + // see path::iterator::increment/decrement comment below + static void m_path_iterator_increment(path::iterator & it); + static void m_path_iterator_decrement(path::iterator & it); + + }; // class path + + namespace detail + { + BOOST_FILESYSTEM_DECL + int lex_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2); + BOOST_FILESYSTEM_DECL + const path& dot_path(); + BOOST_FILESYSTEM_DECL + const path& dot_dot_path(); + } + +# ifndef BOOST_FILESYSTEM_NO_DEPRECATED + typedef path wpath; +# endif + + //------------------------------------------------------------------------------------// + // class path::iterator // + //------------------------------------------------------------------------------------// + + class path::iterator + : public boost::iterator_facade< + path::iterator, + path const, + boost::bidirectional_traversal_tag > + { + private: + friend class boost::iterator_core_access; + friend class boost::filesystem::path; + friend class boost::filesystem::path::reverse_iterator; + friend void m_path_iterator_increment(path::iterator & it); + friend void m_path_iterator_decrement(path::iterator & it); + + const path& dereference() const { return m_element; } + + bool equal(const iterator & rhs) const + { + return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; + } + + // iterator_facade derived classes don't seem to like implementations in + // separate translation unit dll's, so forward to class path static members + void increment() { m_path_iterator_increment(*this); } + void decrement() { m_path_iterator_decrement(*this); } + + path m_element; // current element + const path* m_path_ptr; // path being iterated over + string_type::size_type m_pos; // position of m_element in + // m_path_ptr->m_pathname. + // if m_element is implicit dot, m_pos is the + // position of the last separator in the path. + // end() iterator is indicated by + // m_pos == m_path_ptr->m_pathname.size() + }; // path::iterator + + //------------------------------------------------------------------------------------// + // class path::reverse_iterator // + //------------------------------------------------------------------------------------// + + class path::reverse_iterator + : public boost::iterator_facade< + path::reverse_iterator, + path const, + boost::bidirectional_traversal_tag > + { + public: + + explicit reverse_iterator(iterator itr) : m_itr(itr) + { + if (itr != itr.m_path_ptr->begin()) + m_element = *--itr; + } + private: + friend class boost::iterator_core_access; + friend class boost::filesystem::path; + + const path& dereference() const { return m_element; } + bool equal(const reverse_iterator& rhs) const { return m_itr == rhs.m_itr; } + void increment() + { + --m_itr; + if (m_itr != m_itr.m_path_ptr->begin()) + { + iterator tmp = m_itr; + m_element = *--tmp; + } + } + void decrement() + { + m_element = *m_itr; + ++m_itr; + } + + iterator m_itr; + path m_element; + + }; // path::reverse_iterator + + //------------------------------------------------------------------------------------// + // // + // non-member functions // + // // + //------------------------------------------------------------------------------------// + + // std::lexicographical_compare would infinately recurse because path iterators + // yield paths, so provide a path aware version + inline bool lexicographical_compare(path::iterator first1, path::iterator last1, + path::iterator first2, path::iterator last2) + { return detail::lex_compare(first1, last1, first2, last2) < 0; } + + inline bool operator==(const path& lhs, const path& rhs) {return lhs.compare(rhs) == 0;} + inline bool operator==(const path& lhs, const path::string_type& rhs) {return lhs.compare(rhs) == 0;} + inline bool operator==(const path::string_type& lhs, const path& rhs) {return rhs.compare(lhs) == 0;} + inline bool operator==(const path& lhs, const path::value_type* rhs) {return lhs.compare(rhs) == 0;} + inline bool operator==(const path::value_type* lhs, const path& rhs) {return rhs.compare(lhs) == 0;} + + inline bool operator!=(const path& lhs, const path& rhs) {return lhs.compare(rhs) != 0;} + inline bool operator!=(const path& lhs, const path::string_type& rhs) {return lhs.compare(rhs) != 0;} + inline bool operator!=(const path::string_type& lhs, const path& rhs) {return rhs.compare(lhs) != 0;} + inline bool operator!=(const path& lhs, const path::value_type* rhs) {return lhs.compare(rhs) != 0;} + inline bool operator!=(const path::value_type* lhs, const path& rhs) {return rhs.compare(lhs) != 0;} + + // TODO: why do == and != have additional overloads, but the others don't? + + inline bool operator<(const path& lhs, const path& rhs) {return lhs.compare(rhs) < 0;} + inline bool operator<=(const path& lhs, const path& rhs) {return !(rhs < lhs);} + inline bool operator> (const path& lhs, const path& rhs) {return rhs < lhs;} + inline bool operator>=(const path& lhs, const path& rhs) {return !(lhs < rhs);} + + inline std::size_t hash_value(const path& x) + { +# ifdef BOOST_WINDOWS_API + std::size_t seed = 0; + for(const path::value_type* it = x.c_str(); *it; ++it) + hash_combine(seed, *it == '/' ? L'\\' : *it); + return seed; +# else // BOOST_POSIX_API + return hash_range(x.native().begin(), x.native().end()); +# endif + } + + inline void swap(path& lhs, path& rhs) { lhs.swap(rhs); } + + inline path operator/(const path& lhs, const path& rhs) { return path(lhs) /= rhs; } + + // inserters and extractors + // use boost::io::quoted() to handle spaces in paths + // use '&' as escape character to ease use for Windows paths + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const path& p) + { + return os + << boost::io::quoted(p.template string >(), static_cast('&')); + } + + template + inline std::basic_istream& + operator>>(std::basic_istream& is, path& p) + { + std::basic_string str; + is >> boost::io::quoted(str, static_cast('&')); + p = str; + return is; + } + + // name_checks + + // These functions are holdovers from version 1. It isn't clear they have much + // usefulness, or how to generalize them for later versions. + + BOOST_FILESYSTEM_DECL bool portable_posix_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool windows_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool portable_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool portable_directory_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool portable_file_name(const std::string & name); + BOOST_FILESYSTEM_DECL bool native(const std::string & name); + + namespace detail + { + // For POSIX, is_directory_separator() and is_element_separator() are identical since + // a forward slash is the only valid directory separator and also the only valid + // element separator. For Windows, forward slash and back slash are the possible + // directory separators, but colon (example: "c:foo") is also an element separator. + + inline bool is_directory_separator(path::value_type c) BOOST_NOEXCEPT + { + return c == path::separator +# ifdef BOOST_WINDOWS_API + || c == path::preferred_separator +# endif + ; + } + inline bool is_element_separator(path::value_type c) BOOST_NOEXCEPT + { + return c == path::separator +# ifdef BOOST_WINDOWS_API + || c == path::preferred_separator || c == L':' +# endif + ; + } + } // namespace detail + + //------------------------------------------------------------------------------------// + // class path miscellaneous function implementations // + //------------------------------------------------------------------------------------// + + inline path::reverse_iterator path::rbegin() const { return reverse_iterator(end()); } + inline path::reverse_iterator path::rend() const { return reverse_iterator(begin()); } + + inline bool path::filename_is_dot() const + { + // implicit dot is tricky, so actually call filename(); see path::filename() example + // in reference.html + path p(filename()); + return p.size() == 1 && *p.c_str() == dot; + } + + inline bool path::filename_is_dot_dot() const + { + return size() >= 2 && m_pathname[size()-1] == dot && m_pathname[size()-2] == dot + && (m_pathname.size() == 2 || detail::is_element_separator(m_pathname[size()-3])); + // use detail::is_element_separator() rather than detail::is_directory_separator + // to deal with "c:.." edge case on Windows when ':' acts as a separator + } + +//--------------------------------------------------------------------------------------// +// class path member template implementation // +//--------------------------------------------------------------------------------------// + + template + path& path::append(InputIterator begin, InputIterator end) + { + if (begin == end) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + + template + path& path::append(InputIterator begin, InputIterator end, const codecvt_type& cvt) + { + if (begin == end) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + std::basic_string::value_type> + seq(begin, end); + path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + + template + path& path::append(Source const& source) + { + if (path_traits::empty(source)) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + path_traits::dispatch(source, m_pathname); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + + template + path& path::append(Source const& source, const codecvt_type& cvt) + { + if (path_traits::empty(source)) + return *this; + string_type::size_type sep_pos(m_append_separator_if_needed()); + path_traits::dispatch(source, m_pathname, cvt); + if (sep_pos) + m_erase_redundant_separator(sep_pos); + return *this; + } + +//--------------------------------------------------------------------------------------// +// class path member template specializations // +//--------------------------------------------------------------------------------------// + + template <> inline + std::string path::string() const + { return string(); } + + template <> inline + std::wstring path::string() const + { return wstring(); } + + template <> inline + std::string path::string(const codecvt_type& cvt) const + { return string(cvt); } + + template <> inline + std::wstring path::string(const codecvt_type& cvt) const + { return wstring(cvt); } + + template <> inline + std::string path::generic_string() const + { return generic_string(); } + + template <> inline + std::wstring path::generic_string() const + { return generic_wstring(); } + + template <> inline + std::string path::generic_string(const codecvt_type& cvt) const + { return generic_string(cvt); } + + template <> inline + std::wstring path::generic_string(const codecvt_type& cvt) const + { return generic_wstring(cvt); } + + //--------------------------------------------------------------------------------------// + // path_traits convert function implementations // + // requiring path::codecvt() be visable // + //--------------------------------------------------------------------------------------// + +namespace path_traits +{ // without codecvt + + inline + void convert(const char* from, + const char* from_end, // 0 for null terminated MBCS + std::wstring & to) + { + convert(from, from_end, to, path::codecvt()); + } + + inline + void convert(const wchar_t* from, + const wchar_t* from_end, // 0 for null terminated MBCS + std::string & to) + { + convert(from, from_end, to, path::codecvt()); + } + + inline + void convert(const char* from, + std::wstring & to) + { + BOOST_ASSERT(from); + convert(from, 0, to, path::codecvt()); + } + + inline + void convert(const wchar_t* from, + std::string & to) + { + BOOST_ASSERT(from); + convert(from, 0, to, path::codecvt()); + } +} // namespace path_traits +} // namespace filesystem +} // namespace boost + +//----------------------------------------------------------------------------// + +#include // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_HPP diff --git a/boost/filesystem/path_traits.hpp b/boost/filesystem/path_traits.hpp new file mode 100644 index 00000000..129044a4 --- /dev/null +++ b/boost/filesystem/path_traits.hpp @@ -0,0 +1,352 @@ +// filesystem path_traits.hpp --------------------------------------------------------// + +// Copyright Beman Dawes 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +#ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP +#define BOOST_FILESYSTEM_PATH_TRAITS_HPP + +#include + +# if defined( BOOST_NO_STD_WSTRING ) +# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support +# endif + +#include +#include +#include +#include +#include +#include // for mbstate_t +#include +#include +#include +#include +#include +#include +// #include //**** comment me out **** + +#include // must be the last #include + +namespace boost { namespace filesystem { + + BOOST_FILESYSTEM_DECL const system::error_category& codecvt_error_category(); + // uses std::codecvt_base::result used for error codes: + // + // ok: Conversion successful. + // partial: Not all source characters converted; one or more additional source + // characters are needed to produce the final target character, or the + // size of the target intermediate buffer was too small to hold the result. + // error: A character in the source could not be converted to the target encoding. + // noconv: The source and target characters have the same type and encoding, so no + // conversion was necessary. + + class directory_entry; + +namespace path_traits { + + typedef std::codecvt codecvt_type; + + // is_pathable type trait; allows disabling over-agressive class path member templates + + template + struct is_pathable { static const bool value = false; }; + + template<> struct is_pathable { static const bool value = true; }; + template<> struct is_pathable { static const bool value = true; }; + template<> struct is_pathable { static const bool value = true; }; + template<> struct is_pathable { static const bool value = true; }; + template<> struct is_pathable { static const bool value = true; }; + template<> struct is_pathable { static const bool value = true; }; + template<> struct is_pathable > { static const bool value = true; }; + template<> struct is_pathable > { static const bool value = true; }; + template<> struct is_pathable > { static const bool value = true; }; + template<> struct is_pathable > { static const bool value = true; }; + template<> struct is_pathable { static const bool value = true; }; + + // Pathable empty + + template inline + // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for + // conforming compilers. Replace by plain "bool" at some future date (2012?) + typename boost::disable_if, bool>::type + empty(const Container & c) + { return c.begin() == c.end(); } + + template inline + bool empty(T * const & c_str) + { + BOOST_ASSERT(c_str); + return !*c_str; + } + + template inline + bool empty(T (&x)[N]) + { return !x[0]; } + + // value types differ ---------------------------------------------------------------// + // + // A from_end argument of 0 is less efficient than a known end, so use only if needed + + // with codecvt + + BOOST_FILESYSTEM_DECL + void convert(const char* from, + const char* from_end, // 0 for null terminated MBCS + std::wstring & to, + const codecvt_type& cvt); + + BOOST_FILESYSTEM_DECL + void convert(const wchar_t* from, + const wchar_t* from_end, // 0 for null terminated MBCS + std::string & to, + const codecvt_type& cvt); + + inline + void convert(const char* from, + std::wstring & to, + const codecvt_type& cvt) + { + BOOST_ASSERT(from); + convert(from, 0, to, cvt); + } + + inline + void convert(const wchar_t* from, + std::string & to, + const codecvt_type& cvt) + { + BOOST_ASSERT(from); + convert(from, 0, to, cvt); + } + + // without codecvt + + inline + void convert(const char* from, + const char* from_end, // 0 for null terminated MBCS + std::wstring & to); + + inline + void convert(const wchar_t* from, + const wchar_t* from_end, // 0 for null terminated MBCS + std::string & to); + + inline + void convert(const char* from, + std::wstring & to); + + inline + void convert(const wchar_t* from, + std::string & to); + + // value types same -----------------------------------------------------------------// + + // char with codecvt + + inline + void convert(const char* from, const char* from_end, std::string & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const char* from, + std::string & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + to += from; + } + + // wchar_t with codecvt + + inline + void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const wchar_t* from, + std::wstring & to, + const codecvt_type&) + { + BOOST_ASSERT(from); + to += from; + } + + // char without codecvt + + inline + void convert(const char* from, const char* from_end, std::string & to) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const char* from, std::string & to) + { + BOOST_ASSERT(from); + to += from; + } + + // wchar_t without codecvt + + inline + void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to) + { + BOOST_ASSERT(from); + BOOST_ASSERT(from_end); + to.append(from, from_end); + } + + inline + void convert(const wchar_t* from, std::wstring & to) + { + BOOST_ASSERT(from); + to += from; + } + + // Source dispatch -----------------------------------------------------------------// + + // contiguous containers with codecvt + template inline + void dispatch(const std::string& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template inline + void dispatch(const std::wstring& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template inline + void dispatch(const std::vector& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + template inline + void dispatch(const std::vector& c, U& to, const codecvt_type& cvt) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); + } + + // contiguous containers without codecvt + template inline + void dispatch(const std::string& c, U& to) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to); + } + template inline + void dispatch(const std::wstring& c, U& to) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to); + } + template inline + void dispatch(const std::vector& c, U& to) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to); + } + template inline + void dispatch(const std::vector& c, U& to) + { + if (c.size()) + convert(&*c.begin(), &*c.begin() + c.size(), to); + } + + // non-contiguous containers with codecvt + template inline + // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for + // conforming compilers. Replace by plain "void" at some future date (2012?) + typename boost::disable_if, void>::type + dispatch(const Container & c, U& to, const codecvt_type& cvt) + { + if (c.size()) + { + std::basic_string s(c.begin(), c.end()); + convert(s.c_str(), s.c_str()+s.size(), to, cvt); + } + } + + // c_str + template inline + void dispatch(T * const & c_str, U& to, const codecvt_type& cvt) + { + // std::cout << "dispatch() const T *\n"; + BOOST_ASSERT(c_str); + convert(c_str, to, cvt); + } + + // Note: there is no dispatch on C-style arrays because the array may + // contain a string smaller than the array size. + + BOOST_FILESYSTEM_DECL + void dispatch(const directory_entry & de, +# ifdef BOOST_WINDOWS_API + std::wstring & to, +# else + std::string & to, +# endif + const codecvt_type&); + + // non-contiguous containers without codecvt + template inline + // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for + // conforming compilers. Replace by plain "void" at some future date (2012?) + typename boost::disable_if, void>::type + dispatch(const Container & c, U& to) + { + if (c.size()) + { + std::basic_string seq(c.begin(), c.end()); + convert(seq.c_str(), seq.c_str()+seq.size(), to); + } + } + + // c_str + template inline + void dispatch(T * const & c_str, U& to) + { + // std::cout << "dispatch() const T *\n"; + BOOST_ASSERT(c_str); + convert(c_str, to); + } + + // Note: there is no dispatch on C-style arrays because the array may + // contain a string smaller than the array size. + + BOOST_FILESYSTEM_DECL + void dispatch(const directory_entry & de, +# ifdef BOOST_WINDOWS_API + std::wstring & to +# else + std::string & to +# endif + ); + + +}}} // namespace boost::filesystem::path_traits + +#include // pops abi_prefix.hpp pragmas + +#endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP diff --git a/boost/filesystem/string_file.hpp b/boost/filesystem/string_file.hpp new file mode 100644 index 00000000..015f6590 --- /dev/null +++ b/boost/filesystem/string_file.hpp @@ -0,0 +1,43 @@ +// filesystem/string_file.hpp --------------------------------------------------------// + +// Copyright Beman Dawes 2015 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Library home page: http://www.boost.org/libs/filesystem + +#ifndef BOOST_FILESYSTEM_STRING_FILE_HPP +#define BOOST_FILESYSTEM_STRING_FILE_HPP + +#include +#include +#include + +namespace boost +{ +namespace filesystem +{ +inline +void save_string_file(const path& p, const std::string& str) +{ + ofstream file; + file.exceptions(std::ofstream::failbit | std::ofstream::badbit); + file.open(p, std::ios_base::binary); + file.write(str.c_str(), str.size()); +} + +inline +void load_string_file(const path& p, std::string& str) +{ + ifstream file; + file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + file.open(p, std::ios_base::binary); + std::size_t sz = static_cast(file_size(p)); + str.resize(sz, '\0'); + file.read(&str[0], sz); +} +} // namespace filesystem +} // namespace boost + +#endif // include guard diff --git a/boost/function.hpp b/boost/function.hpp new file mode 100644 index 00000000..68a25ab0 --- /dev/null +++ b/boost/function.hpp @@ -0,0 +1,74 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2003. 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) + +// For more information, see http://www.boost.org/libs/function + +// William Kempf, Jesse Jones and Karl Nelson were all very helpful in the +// design of this library. + +#ifndef BOOST_FUNCTION_MAX_ARGS +# define BOOST_FUNCTION_MAX_ARGS 10 +#endif // BOOST_FUNCTION_MAX_ARGS + +#if !defined(BOOST_FUNCTION_MAX_ARGS_DEFINED) || (BOOST_FUNCTION_MAX_ARGS_DEFINED != BOOST_FUNCTION_MAX_ARGS) + +#if !defined(BOOST_FUNCTION_MAX_ARGS_DEFINED) +#define BOOST_FUNCTION_MAX_ARGS_DEFINED 0 +#endif + +#include // unary_function, binary_function + +#include +#include + +// Include the prologue here so that the use of file-level iteration +// in anything that may be included by function_template.hpp doesn't break +#include + +// Older Visual Age C++ version do not handle the file iteration well +#if BOOST_WORKAROUND(__IBMCPP__, >= 500) && BOOST_WORKAROUND(__IBMCPP__, < 800) +# if BOOST_FUNCTION_MAX_ARGS >= 0 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 1 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 2 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 3 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 4 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 5 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 6 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 7 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 8 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 9 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 10 +# include +# endif +#else +// What is the '3' for? +# define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_FUNCTION_MAX_ARGS,)) +# include BOOST_PP_ITERATE() +# undef BOOST_PP_ITERATION_PARAMS_1 +#endif + +#endif // !defined(BOOST_FUNCTION_MAX_ARGS_DEFINED) || (BOOST_FUNCTION_MAX_ARGS_DEFINED != BOOST_FUNCTION_MAX_ARGS) diff --git a/boost/function/detail/function_iterate.hpp b/boost/function/detail/function_iterate.hpp new file mode 100644 index 00000000..5370b36a --- /dev/null +++ b/boost/function/detail/function_iterate.hpp @@ -0,0 +1,16 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2003. 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) + +// For more information, see http://www.boost.org +#if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Function - do not include this file! +#endif + +#define BOOST_FUNCTION_NUM_ARGS BOOST_PP_ITERATION() +#include +#undef BOOST_FUNCTION_NUM_ARGS + diff --git a/boost/function/detail/gen_maybe_include.pl b/boost/function/detail/gen_maybe_include.pl new file mode 100644 index 00000000..bc409840 --- /dev/null +++ b/boost/function/detail/gen_maybe_include.pl @@ -0,0 +1,39 @@ +#!/usr/bin/perl -w +# +# Boost.Function library +# +# Copyright (C) 2001-2003 Douglas Gregor (gregod@cs.rpi.edu) +# +# Permission to copy, use, sell and distribute this software is granted +# provided this copyright notice appears in all copies. +# Permission to modify the code and to distribute modified code is granted +# provided this copyright notice appears in all copies, and a notice +# that the code was modified is included with the copyright notice. +# +# This software is provided "as is" without express or implied warranty, +# and with no claim as to its suitability for any purpose. +# +# For more information, see http://www.boost.org +use English; + +$max_args = $ARGV[0]; + +open (OUT, ">maybe_include.hpp") or die("Cannot write to maybe_include.hpp"); +for($on_arg = 0; $on_arg <= $max_args; ++$on_arg) { + if ($on_arg == 0) { + print OUT "#if"; + } + else { + print OUT "#elif"; + } + print OUT " BOOST_FUNCTION_NUM_ARGS == $on_arg\n"; + print OUT "# undef BOOST_FUNCTION_MAX_ARGS_DEFINED\n"; + print OUT "# define BOOST_FUNCTION_MAX_ARGS_DEFINED $on_arg\n"; + print OUT "# ifndef BOOST_FUNCTION_$on_arg\n"; + print OUT "# define BOOST_FUNCTION_$on_arg\n"; + print OUT "# include \n"; + print OUT "# endif\n"; +} +print OUT "#else\n"; +print OUT "# error Cannot handle Boost.Function objects that accept more than $max_args arguments!\n"; +print OUT "#endif\n"; diff --git a/boost/function/detail/maybe_include.hpp b/boost/function/detail/maybe_include.hpp new file mode 100644 index 00000000..ec88905d --- /dev/null +++ b/boost/function/detail/maybe_include.hpp @@ -0,0 +1,369 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2003. 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) + +// For more information, see http://www.boost.org + +#if BOOST_FUNCTION_NUM_ARGS == 0 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 0 +# ifndef BOOST_FUNCTION_0 +# define BOOST_FUNCTION_0 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 1 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 1 +# ifndef BOOST_FUNCTION_1 +# define BOOST_FUNCTION_1 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 2 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 2 +# ifndef BOOST_FUNCTION_2 +# define BOOST_FUNCTION_2 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 3 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 3 +# ifndef BOOST_FUNCTION_3 +# define BOOST_FUNCTION_3 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 4 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 4 +# ifndef BOOST_FUNCTION_4 +# define BOOST_FUNCTION_4 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 5 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 5 +# ifndef BOOST_FUNCTION_5 +# define BOOST_FUNCTION_5 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 6 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 6 +# ifndef BOOST_FUNCTION_6 +# define BOOST_FUNCTION_6 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 7 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 7 +# ifndef BOOST_FUNCTION_7 +# define BOOST_FUNCTION_7 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 8 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 8 +# ifndef BOOST_FUNCTION_8 +# define BOOST_FUNCTION_8 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 9 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 9 +# ifndef BOOST_FUNCTION_9 +# define BOOST_FUNCTION_9 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 10 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 10 +# ifndef BOOST_FUNCTION_10 +# define BOOST_FUNCTION_10 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 11 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 11 +# ifndef BOOST_FUNCTION_11 +# define BOOST_FUNCTION_11 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 12 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 12 +# ifndef BOOST_FUNCTION_12 +# define BOOST_FUNCTION_12 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 13 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 13 +# ifndef BOOST_FUNCTION_13 +# define BOOST_FUNCTION_13 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 14 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 14 +# ifndef BOOST_FUNCTION_14 +# define BOOST_FUNCTION_14 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 15 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 15 +# ifndef BOOST_FUNCTION_15 +# define BOOST_FUNCTION_15 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 16 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 16 +# ifndef BOOST_FUNCTION_16 +# define BOOST_FUNCTION_16 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 17 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 17 +# ifndef BOOST_FUNCTION_17 +# define BOOST_FUNCTION_17 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 18 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 18 +# ifndef BOOST_FUNCTION_18 +# define BOOST_FUNCTION_18 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 19 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 19 +# ifndef BOOST_FUNCTION_19 +# define BOOST_FUNCTION_19 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 20 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 20 +# ifndef BOOST_FUNCTION_20 +# define BOOST_FUNCTION_20 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 21 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 21 +# ifndef BOOST_FUNCTION_21 +# define BOOST_FUNCTION_21 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 22 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 22 +# ifndef BOOST_FUNCTION_22 +# define BOOST_FUNCTION_22 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 23 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 23 +# ifndef BOOST_FUNCTION_23 +# define BOOST_FUNCTION_23 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 24 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 24 +# ifndef BOOST_FUNCTION_24 +# define BOOST_FUNCTION_24 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 25 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 25 +# ifndef BOOST_FUNCTION_25 +# define BOOST_FUNCTION_25 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 26 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 26 +# ifndef BOOST_FUNCTION_26 +# define BOOST_FUNCTION_26 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 27 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 27 +# ifndef BOOST_FUNCTION_27 +# define BOOST_FUNCTION_27 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 28 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 28 +# ifndef BOOST_FUNCTION_28 +# define BOOST_FUNCTION_28 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 29 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 29 +# ifndef BOOST_FUNCTION_29 +# define BOOST_FUNCTION_29 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 30 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 30 +# ifndef BOOST_FUNCTION_30 +# define BOOST_FUNCTION_30 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 31 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 31 +# ifndef BOOST_FUNCTION_31 +# define BOOST_FUNCTION_31 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 32 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 32 +# ifndef BOOST_FUNCTION_32 +# define BOOST_FUNCTION_32 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 33 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 33 +# ifndef BOOST_FUNCTION_33 +# define BOOST_FUNCTION_33 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 34 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 34 +# ifndef BOOST_FUNCTION_34 +# define BOOST_FUNCTION_34 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 35 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 35 +# ifndef BOOST_FUNCTION_35 +# define BOOST_FUNCTION_35 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 36 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 36 +# ifndef BOOST_FUNCTION_36 +# define BOOST_FUNCTION_36 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 37 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 37 +# ifndef BOOST_FUNCTION_37 +# define BOOST_FUNCTION_37 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 38 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 38 +# ifndef BOOST_FUNCTION_38 +# define BOOST_FUNCTION_38 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 39 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 39 +# ifndef BOOST_FUNCTION_39 +# define BOOST_FUNCTION_39 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 40 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 40 +# ifndef BOOST_FUNCTION_40 +# define BOOST_FUNCTION_40 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 41 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 41 +# ifndef BOOST_FUNCTION_41 +# define BOOST_FUNCTION_41 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 42 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 42 +# ifndef BOOST_FUNCTION_42 +# define BOOST_FUNCTION_42 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 43 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 43 +# ifndef BOOST_FUNCTION_43 +# define BOOST_FUNCTION_43 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 44 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 44 +# ifndef BOOST_FUNCTION_44 +# define BOOST_FUNCTION_44 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 45 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 45 +# ifndef BOOST_FUNCTION_45 +# define BOOST_FUNCTION_45 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 46 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 46 +# ifndef BOOST_FUNCTION_46 +# define BOOST_FUNCTION_46 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 47 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 47 +# ifndef BOOST_FUNCTION_47 +# define BOOST_FUNCTION_47 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 48 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 48 +# ifndef BOOST_FUNCTION_48 +# define BOOST_FUNCTION_48 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 49 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 49 +# ifndef BOOST_FUNCTION_49 +# define BOOST_FUNCTION_49 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 50 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 50 +# ifndef BOOST_FUNCTION_50 +# define BOOST_FUNCTION_50 +# include +# endif +#else +# error Cannot handle Boost.Function objects that accept more than 50 arguments! +#endif diff --git a/boost/function/detail/prologue.hpp b/boost/function/detail/prologue.hpp new file mode 100644 index 00000000..53d0f05c --- /dev/null +++ b/boost/function/detail/prologue.hpp @@ -0,0 +1,26 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#ifndef BOOST_FUNCTION_PROLOGUE_HPP +#define BOOST_FUNCTION_PROLOGUE_HPP +# include +# include +# include // unary_function, binary_function +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif // BOOST_FUNCTION_PROLOGUE_HPP diff --git a/boost/function/function0.hpp b/boost/function/function0.hpp new file mode 100644 index 00000000..65a02e5f --- /dev/null +++ b/boost/function/function0.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 0 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function1.hpp b/boost/function/function1.hpp new file mode 100644 index 00000000..90897151 --- /dev/null +++ b/boost/function/function1.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 1 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function10.hpp b/boost/function/function10.hpp new file mode 100644 index 00000000..65627248 --- /dev/null +++ b/boost/function/function10.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 10 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function2.hpp b/boost/function/function2.hpp new file mode 100644 index 00000000..dc8bf975 --- /dev/null +++ b/boost/function/function2.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 2 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function3.hpp b/boost/function/function3.hpp new file mode 100644 index 00000000..19d1a49d --- /dev/null +++ b/boost/function/function3.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 3 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function4.hpp b/boost/function/function4.hpp new file mode 100644 index 00000000..f3349e2d --- /dev/null +++ b/boost/function/function4.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 4 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function5.hpp b/boost/function/function5.hpp new file mode 100644 index 00000000..a1305eb5 --- /dev/null +++ b/boost/function/function5.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 5 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function6.hpp b/boost/function/function6.hpp new file mode 100644 index 00000000..1f609149 --- /dev/null +++ b/boost/function/function6.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 6 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function7.hpp b/boost/function/function7.hpp new file mode 100644 index 00000000..68542ed4 --- /dev/null +++ b/boost/function/function7.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 7 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function8.hpp b/boost/function/function8.hpp new file mode 100644 index 00000000..cf2c3766 --- /dev/null +++ b/boost/function/function8.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 8 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function9.hpp b/boost/function/function9.hpp new file mode 100644 index 00000000..590e0883 --- /dev/null +++ b/boost/function/function9.hpp @@ -0,0 +1,12 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. 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) + +// For more information, see http://www.boost.org + +#define BOOST_FUNCTION_NUM_ARGS 9 +#include +#undef BOOST_FUNCTION_NUM_ARGS diff --git a/boost/function/function_base.hpp b/boost/function/function_base.hpp new file mode 100644 index 00000000..841affb4 --- /dev/null +++ b/boost/function/function_base.hpp @@ -0,0 +1,886 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2006 +// Copyright Emil Dotchevski 2007 +// 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) + +// For more information, see http://www.boost.org + +#ifndef BOOST_FUNCTION_BASE_HEADER +#define BOOST_FUNCTION_BASE_HEADER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_NO_SFINAE +# include "boost/utility/enable_if.hpp" +#else +# include "boost/mpl/bool.hpp" +#endif +#include +#include + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable : 4793 ) // complaint about native code generation +# pragma warning( disable : 4127 ) // "conditional expression is constant" +#endif + +#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG) +# define BOOST_FUNCTION_TARGET_FIX(x) x +#else +# define BOOST_FUNCTION_TARGET_FIX(x) +#endif // __ICL etc + +# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \ + typename ::boost::enable_if_c< \ + !(::boost::is_integral::value), \ + Type>::type + +namespace boost { + namespace detail { + namespace function { + class X; + + /** + * A buffer used to store small function objects in + * boost::function. It is a union containing function pointers, + * object pointers, and a structure that resembles a bound + * member function pointer. + */ + union function_buffer_members + { + // For pointers to function objects + typedef void* obj_ptr_t; + mutable obj_ptr_t obj_ptr; + + // For pointers to std::type_info objects + struct type_t { + // (get_functor_type_tag, check_functor_type_tag). + const boost::typeindex::type_info* type; + + // Whether the type is const-qualified. + bool const_qualified; + // Whether the type is volatile-qualified. + bool volatile_qualified; + } type; + + // For function pointers of all kinds + typedef void (*func_ptr_t)(); + mutable func_ptr_t func_ptr; + + // For bound member pointers + struct bound_memfunc_ptr_t { + void (X::*memfunc_ptr)(int); + void* obj_ptr; + } bound_memfunc_ptr; + + // For references to function objects. We explicitly keep + // track of the cv-qualifiers on the object referenced. + struct obj_ref_t { + mutable void* obj_ptr; + bool is_const_qualified; + bool is_volatile_qualified; + } obj_ref; + }; + + union function_buffer + { + // Type-specific union members + mutable function_buffer_members members; + + // To relax aliasing constraints + mutable char data[sizeof(function_buffer_members)]; + }; + + /** + * The unusable class is a placeholder for unused function arguments + * It is also completely unusable except that it constructable from + * anything. This helps compilers without partial specialization to + * handle Boost.Function objects returning void. + */ + struct unusable + { + unusable() {} + template unusable(const T&) {} + }; + + /* Determine the return type. This supports compilers that do not support + * void returns or partial specialization by silently changing the return + * type to "unusable". + */ + template struct function_return_type { typedef T type; }; + + template<> + struct function_return_type + { + typedef unusable type; + }; + + // The operation type to perform on the given functor/function pointer + enum functor_manager_operation_type { + clone_functor_tag, + move_functor_tag, + destroy_functor_tag, + check_functor_type_tag, + get_functor_type_tag + }; + + // Tags used to decide between different types of functions + struct function_ptr_tag {}; + struct function_obj_tag {}; + struct member_ptr_tag {}; + struct function_obj_ref_tag {}; + + template + class get_function_tag + { + typedef typename mpl::if_c<(is_pointer::value), + function_ptr_tag, + function_obj_tag>::type ptr_or_obj_tag; + + typedef typename mpl::if_c<(is_member_pointer::value), + member_ptr_tag, + ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag; + + typedef typename mpl::if_c<(is_reference_wrapper::value), + function_obj_ref_tag, + ptr_or_obj_or_mem_tag>::type or_ref_tag; + + public: + typedef or_ref_tag type; + }; + + // The trivial manager does nothing but return the same pointer (if we + // are cloning) or return the null pointer (if we are deleting). + template + struct reference_manager + { + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + switch (op) { + case clone_functor_tag: + out_buffer.members.obj_ref = in_buffer.members.obj_ref; + return; + + case move_functor_tag: + out_buffer.members.obj_ref = in_buffer.members.obj_ref; + in_buffer.members.obj_ref.obj_ptr = 0; + return; + + case destroy_functor_tag: + out_buffer.members.obj_ref.obj_ptr = 0; + return; + + case check_functor_type_tag: + { + // Check whether we have the same type. We can add + // cv-qualifiers, but we can't take them away. + if (*out_buffer.members.type.type == boost::typeindex::type_id() + && (!in_buffer.members.obj_ref.is_const_qualified + || out_buffer.members.type.const_qualified) + && (!in_buffer.members.obj_ref.is_volatile_qualified + || out_buffer.members.type.volatile_qualified)) + out_buffer.members.obj_ptr = in_buffer.members.obj_ref.obj_ptr; + else + out_buffer.members.obj_ptr = 0; + } + return; + + case get_functor_type_tag: + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = in_buffer.members.obj_ref.is_const_qualified; + out_buffer.members.type.volatile_qualified = in_buffer.members.obj_ref.is_volatile_qualified; + return; + } + } + }; + + /** + * Determine if boost::function can use the small-object + * optimization with the function object type F. + */ + template + struct function_allows_small_object_optimization + { + BOOST_STATIC_CONSTANT + (bool, + value = ((sizeof(F) <= sizeof(function_buffer) && + (alignment_of::value + % alignment_of::value == 0)))); + }; + + template + struct functor_wrapper: public F, public A + { + functor_wrapper( F f, A a ): + F(f), + A(a) + { + } + + functor_wrapper(const functor_wrapper& f) : + F(static_cast(f)), + A(static_cast(f)) + { + } + }; + + /** + * The functor_manager class contains a static function "manage" which + * can clone or destroy the given function/function object pointer. + */ + template + struct functor_manager_common + { + typedef Functor functor_type; + + // Function pointers + static inline void + manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + if (op == clone_functor_tag) + out_buffer.members.func_ptr = in_buffer.members.func_ptr; + else if (op == move_functor_tag) { + out_buffer.members.func_ptr = in_buffer.members.func_ptr; + in_buffer.members.func_ptr = 0; + } else if (op == destroy_functor_tag) + out_buffer.members.func_ptr = 0; + else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = &in_buffer.members.func_ptr; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + + // Function objects that fit in the small-object buffer. + static inline void + manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + if (op == clone_functor_tag || op == move_functor_tag) { + const functor_type* in_functor = + reinterpret_cast(in_buffer.data); + new (reinterpret_cast(out_buffer.data)) functor_type(*in_functor); + + if (op == move_functor_tag) { + functor_type* f = reinterpret_cast(in_buffer.data); + (void)f; // suppress warning about the value of f not being used (MSVC) + f->~Functor(); + } + } else if (op == destroy_functor_tag) { + // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. + functor_type* f = reinterpret_cast(out_buffer.data); + (void)f; // suppress warning about the value of f not being used (MSVC) + f->~Functor(); + } else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.data; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + }; + + template + struct functor_manager + { + private: + typedef Functor functor_type; + + // Function pointers + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_ptr_tag) + { + functor_manager_common::manage_ptr(in_buffer,out_buffer,op); + } + + // Function objects that fit in the small-object buffer. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, mpl::true_) + { + functor_manager_common::manage_small(in_buffer,out_buffer,op); + } + + // Function objects that require heap allocation + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, mpl::false_) + { + if (op == clone_functor_tag) { + // Clone the functor + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + // jewillco: Changing this to static_cast because GCC 2.95.3 is + // obsolete. + const functor_type* f = + static_cast(in_buffer.members.obj_ptr); + functor_type* new_f = new functor_type(*f); + out_buffer.members.obj_ptr = new_f; + } else if (op == move_functor_tag) { + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + in_buffer.members.obj_ptr = 0; + } else if (op == destroy_functor_tag) { + /* Cast from the void pointer to the functor pointer type */ + functor_type* f = + static_cast(out_buffer.members.obj_ptr); + delete f; + out_buffer.members.obj_ptr = 0; + } else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + + // For function objects, we determine whether the function + // object can use the small-object optimization buffer or + // whether we need to allocate it on the heap. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_obj_tag) + { + manager(in_buffer, out_buffer, op, + mpl::bool_<(function_allows_small_object_optimization::value)>()); + } + + // For member pointers, we use the small-object optimization buffer. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, member_ptr_tag) + { + manager(in_buffer, out_buffer, op, mpl::true_()); + } + + public: + /* Dispatch to an appropriate manager based on whether we have a + function pointer or a function object pointer. */ + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + typedef typename get_function_tag::type tag_type; + switch (op) { + case get_functor_type_tag: + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + return; + + default: + manager(in_buffer, out_buffer, op, tag_type()); + return; + } + } + }; + + template + struct functor_manager_a + { + private: + typedef Functor functor_type; + + // Function pointers + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_ptr_tag) + { + functor_manager_common::manage_ptr(in_buffer,out_buffer,op); + } + + // Function objects that fit in the small-object buffer. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, mpl::true_) + { + functor_manager_common::manage_small(in_buffer,out_buffer,op); + } + + // Function objects that require heap allocation + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, mpl::false_) + { + typedef functor_wrapper functor_wrapper_type; +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Allocator::template rebind::other + wrapper_allocator_type; + typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type; +#else + using wrapper_allocator_type = typename std::allocator_traits::template rebind_alloc; + using wrapper_allocator_pointer_type = typename std::allocator_traits::pointer; +#endif + + if (op == clone_functor_tag) { + // Clone the functor + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + const functor_wrapper_type* f = + static_cast(in_buffer.members.obj_ptr); + wrapper_allocator_type wrapper_allocator(static_cast(*f)); + wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); +#if defined(BOOST_NO_CXX11_ALLOCATOR) + wrapper_allocator.construct(copy, *f); +#else + std::allocator_traits::construct(wrapper_allocator, copy, *f); +#endif + + // Get back to the original pointer type + functor_wrapper_type* new_f = static_cast(copy); + out_buffer.members.obj_ptr = new_f; + } else if (op == move_functor_tag) { + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + in_buffer.members.obj_ptr = 0; + } else if (op == destroy_functor_tag) { + /* Cast from the void pointer to the functor_wrapper_type */ + functor_wrapper_type* victim = + static_cast(in_buffer.members.obj_ptr); + wrapper_allocator_type wrapper_allocator(static_cast(*victim)); +#if defined(BOOST_NO_CXX11_ALLOCATOR) + wrapper_allocator.destroy(victim); +#else + std::allocator_traits::destroy(wrapper_allocator, victim); +#endif + wrapper_allocator.deallocate(victim,1); + out_buffer.members.obj_ptr = 0; + } else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + + // For function objects, we determine whether the function + // object can use the small-object optimization buffer or + // whether we need to allocate it on the heap. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_obj_tag) + { + manager(in_buffer, out_buffer, op, + mpl::bool_<(function_allows_small_object_optimization::value)>()); + } + + public: + /* Dispatch to an appropriate manager based on whether we have a + function pointer or a function object pointer. */ + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + typedef typename get_function_tag::type tag_type; + switch (op) { + case get_functor_type_tag: + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + return; + + default: + manager(in_buffer, out_buffer, op, tag_type()); + return; + } + } + }; + + // A type that is only used for comparisons against zero + struct useless_clear_type {}; + +#ifdef BOOST_NO_SFINAE + // These routines perform comparisons between a Boost.Function + // object and an arbitrary function object (when the last + // parameter is mpl::bool_) or against zero (when the + // last parameter is mpl::bool_). They are only necessary + // for compilers that don't support SFINAE. + template + bool + compare_equal(const Function& f, const Functor&, int, mpl::bool_) + { return f.empty(); } + + template + bool + compare_not_equal(const Function& f, const Functor&, int, + mpl::bool_) + { return !f.empty(); } + + template + bool + compare_equal(const Function& f, const Functor& g, long, + mpl::bool_) + { + if (const Functor* fp = f.template target()) + return function_equal(*fp, g); + else return false; + } + + template + bool + compare_equal(const Function& f, const reference_wrapper& g, + int, mpl::bool_) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + + template + bool + compare_not_equal(const Function& f, const Functor& g, long, + mpl::bool_) + { + if (const Functor* fp = f.template target()) + return !function_equal(*fp, g); + else return true; + } + + template + bool + compare_not_equal(const Function& f, + const reference_wrapper& g, int, + mpl::bool_) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } +#endif // BOOST_NO_SFINAE + + /** + * Stores the "manager" portion of the vtable for a + * boost::function object. + */ + struct vtable_base + { + void (*manager)(const function_buffer& in_buffer, + function_buffer& out_buffer, + functor_manager_operation_type op); + }; + } // end namespace function + } // end namespace detail + +/** + * The function_base class contains the basic elements needed for the + * function1, function2, function3, etc. classes. It is common to all + * functions (and as such can be used to tell if we have one of the + * functionN objects). + */ +class function_base +{ +public: + function_base() : vtable(0) { } + + /** Determine if the function is empty (i.e., has no target). */ + bool empty() const { return !vtable; } + + /** Retrieve the type of the stored function object, or type_id() + if this is empty. */ + const boost::typeindex::type_info& target_type() const + { + if (!vtable) return boost::typeindex::type_id().type_info(); + + detail::function::function_buffer type; + get_vtable()->manager(functor, type, detail::function::get_functor_type_tag); + return *type.members.type.type; + } + + template + Functor* target() + { + if (!vtable) return 0; + + detail::function::function_buffer type_result; + type_result.members.type.type = &boost::typeindex::type_id().type_info(); + type_result.members.type.const_qualified = is_const::value; + type_result.members.type.volatile_qualified = is_volatile::value; + get_vtable()->manager(functor, type_result, + detail::function::check_functor_type_tag); + return static_cast(type_result.members.obj_ptr); + } + + template + const Functor* target() const + { + if (!vtable) return 0; + + detail::function::function_buffer type_result; + type_result.members.type.type = &boost::typeindex::type_id().type_info(); + type_result.members.type.const_qualified = true; + type_result.members.type.volatile_qualified = is_volatile::value; + get_vtable()->manager(functor, type_result, + detail::function::check_functor_type_tag); + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + return static_cast(type_result.members.obj_ptr); + } + + template + bool contains(const F& f) const + { + if (const F* fp = this->template target()) + { + return function_equal(*fp, f); + } else { + return false; + } + } + +#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3 + // GCC 3.3 and newer cannot copy with the global operator==, due to + // problems with instantiation of function return types before it + // has been verified that the argument types match up. + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(Functor g) const + { + if (const Functor* fp = target()) + return function_equal(*fp, g); + else return false; + } + + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(Functor g) const + { + if (const Functor* fp = target()) + return !function_equal(*fp, g); + else return true; + } +#endif + +public: // should be protected, but GCC 2.95.3 will fail to allow access + detail::function::vtable_base* get_vtable() const { + return reinterpret_cast( + reinterpret_cast(vtable) & ~static_cast(0x01)); + } + + bool has_trivial_copy_and_destroy() const { + return reinterpret_cast(vtable) & 0x01; + } + + detail::function::vtable_base* vtable; + mutable detail::function::function_buffer functor; +}; + +#if defined(BOOST_CLANG) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wweak-vtables" +#endif +/** + * The bad_function_call exception class is thrown when a boost::function + * object is invoked + */ +class bad_function_call : public std::runtime_error +{ +public: + bad_function_call() : std::runtime_error("call to empty boost::function") {} +}; +#if defined(BOOST_CLANG) +# pragma clang diagnostic pop +#endif + +#ifndef BOOST_NO_SFINAE +inline bool operator==(const function_base& f, + detail::function::useless_clear_type*) +{ + return f.empty(); +} + +inline bool operator!=(const function_base& f, + detail::function::useless_clear_type*) +{ + return !f.empty(); +} + +inline bool operator==(detail::function::useless_clear_type*, + const function_base& f) +{ + return f.empty(); +} + +inline bool operator!=(detail::function::useless_clear_type*, + const function_base& f) +{ + return !f.empty(); +} +#endif + +#ifdef BOOST_NO_SFINAE +// Comparisons between boost::function objects and arbitrary function objects +template + inline bool operator==(const function_base& f, Functor g) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_equal(f, g, 0, integral()); + } + +template + inline bool operator==(Functor g, const function_base& f) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_equal(f, g, 0, integral()); + } + +template + inline bool operator!=(const function_base& f, Functor g) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_not_equal(f, g, 0, integral()); + } + +template + inline bool operator!=(Functor g, const function_base& f) + { + typedef mpl::bool_<(is_integral::value)> integral; + return detail::function::compare_not_equal(f, g, 0, integral()); + } +#else + +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) +// Comparisons between boost::function objects and arbitrary function +// objects. GCC 3.3 and before has an obnoxious bug that prevents this +// from working. +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(const function_base& f, Functor g) + { + if (const Functor* fp = f.template target()) + return function_equal(*fp, g); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(Functor g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return function_equal(g, *fp); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(const function_base& f, Functor g) + { + if (const Functor* fp = f.template target()) + return !function_equal(*fp, g); + else return true; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(Functor g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return !function_equal(g, *fp); + else return true; + } +# endif + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(const function_base& f, reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(reference_wrapper g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() == fp; + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(const function_base& f, reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(reference_wrapper g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() != fp; + else return true; + } + +#endif // Compiler supporting SFINAE + +namespace detail { + namespace function { + inline bool has_empty_target(const function_base* f) + { + return f->empty(); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) + inline bool has_empty_target(const void*) + { + return false; + } +#else + inline bool has_empty_target(...) + { + return false; + } +#endif + } // end namespace function +} // end namespace detail +} // end namespace boost + +#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif + +#endif // BOOST_FUNCTION_BASE_HEADER diff --git a/boost/function/function_fwd.hpp b/boost/function/function_fwd.hpp new file mode 100644 index 00000000..e79b5048 --- /dev/null +++ b/boost/function/function_fwd.hpp @@ -0,0 +1,69 @@ +// Boost.Function library +// Copyright (C) Douglas Gregor 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) +// +// For more information, see http://www.boost.org +#ifndef BOOST_FUNCTION_FWD_HPP +#define BOOST_FUNCTION_FWD_HPP +#include + +#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG) +// Work around a compiler bug. +// boost::python::objects::function has to be seen by the compiler before the +// boost::function class template. +namespace boost { namespace python { namespace objects { + class function; +}}} +#endif + +#if defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \ + || !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540) +# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX +#endif + +namespace boost { + class bad_function_call; + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + // Preferred syntax + template class function; + + template + inline void swap(function& f1, function& f2) + { + f1.swap(f2); + } +#endif // have partial specialization + + // Portable syntax + template class function0; + template class function1; + template class function2; + template class function3; + template + class function4; + template + class function5; + template + class function6; + template + class function7; + template + class function8; + template + class function9; + template + class function10; +} + +#endif diff --git a/boost/function/function_template.hpp b/boost/function/function_template.hpp new file mode 100644 index 00000000..0b05940b --- /dev/null +++ b/boost/function/function_template.hpp @@ -0,0 +1,1187 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2006 +// Copyright Emil Dotchevski 2007 +// 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) + +// For more information, see http://www.boost.org + +// Note: this header is a header template and must NOT have multiple-inclusion +// protection. +#include +#include + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable : 4127 ) // "conditional expression is constant" +#endif + +#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) + +#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T) + +#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I) + +#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY) + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) +#else +# include +# define BOOST_FUNCTION_ARG(J,I,D) ::boost::forward< BOOST_PP_CAT(T,I) >(BOOST_PP_CAT(a,I)) +# define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY) +#endif + +#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \ + typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type); + +#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY) + +// Comma if nonzero number of arguments +#if BOOST_FUNCTION_NUM_ARGS == 0 +# define BOOST_FUNCTION_COMMA +#else +# define BOOST_FUNCTION_COMMA , +#endif // BOOST_FUNCTION_NUM_ARGS > 0 + +// Class names used in this version of the code +#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_INVOKER \ + BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \ + BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \ + BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \ + BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_MEMBER_INVOKER \ + BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \ + BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \ + BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \ + BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_MEMBER_INVOKER \ + BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_INVOKER \ + BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS) + +#ifndef BOOST_NO_VOID_RETURNS +# define BOOST_FUNCTION_VOID_RETURN_TYPE void +# define BOOST_FUNCTION_RETURN(X) X +#else +# define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable +# define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE () +#endif + +namespace boost { + namespace detail { + namespace function { + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_INVOKER + { + static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + { + FunctionPtr f = reinterpret_cast(function_ptr.members.func_ptr); + return f(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionPtr f = reinterpret_cast(function_ptr.members.func_ptr); + BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS)); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f; + if (function_allows_small_object_optimization::value) + f = reinterpret_cast(function_obj_ptr.data); + else + f = reinterpret_cast(function_obj_ptr.members.obj_ptr); + return (*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f; + if (function_allows_small_object_optimization::value) + f = reinterpret_cast(function_obj_ptr.data); + else + f = reinterpret_cast(function_obj_ptr.members.obj_ptr); + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_REF_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f = + reinterpret_cast(function_obj_ptr.members.obj_ptr); + return (*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f = + reinterpret_cast(function_obj_ptr.members.obj_ptr); + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); + } + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Handle invocation of member pointers. */ + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_MEMBER_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + MemberPtr* f = + reinterpret_cast(function_obj_ptr.data); + return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_MEMBER_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + MemberPtr* f = + reinterpret_cast(function_obj_ptr.data); + BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); + } + }; +#endif + + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_REF_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Retrieve the appropriate invoker for a member pointer. */ + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_MEMBER_INVOKER + { + typedef typename mpl::if_c<(is_void::value), + BOOST_FUNCTION_VOID_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; +#endif + + /* Given the tag returned by get_function_tag, retrieve the + actual invoker that will be used for the given function + object. + + Each specialization contains an "apply" nested class template + that accepts the function object, return type, function + argument types, and allocator. The resulting "apply" class + contains two typedefs, "invoker_type" and "manager_type", + which correspond to the invoker and manager types. */ + template + struct BOOST_FUNCTION_GET_INVOKER { }; + + /* Retrieve the invoker for a function pointer. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Retrieve the invoker for a member pointer. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + }; +#endif + + /* Retrieve the invoker for a function object. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager_a manager_type; + }; + }; + + /* Retrieve the invoker for a reference to a function object. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< + typename RefWrapper::type, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef reference_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< + typename RefWrapper::type, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef reference_manager manager_type; + }; + }; + + + /** + * vtable for a specific boost::function instance. This + * structure must be an aggregate so that we can use static + * initialization in boost::function's assign_to and assign_to_a + * members. It therefore cannot have any constructors, + * destructors, base classes, etc. + */ + template + struct BOOST_FUNCTION_VTABLE + { +#ifndef BOOST_NO_VOID_RETURNS + typedef R result_type; +#else + typedef typename function_return_type::type result_type; +#endif // BOOST_NO_VOID_RETURNS + + typedef result_type (*invoker_type)(function_buffer& + BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS); + + template + bool assign_to(F f, function_buffer& functor) const + { + typedef typename get_function_tag::type tag; + return assign_to(f, functor, tag()); + } + template + bool assign_to_a(F f, function_buffer& functor, Allocator a) const + { + typedef typename get_function_tag::type tag; + return assign_to_a(f, functor, a, tag()); + } + + void clear(function_buffer& functor) const + { + if (base.manager) + base.manager(functor, functor, destroy_functor_tag); + } + + private: + // Function pointers + template + bool + assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const + { + this->clear(functor); + if (f) { + // should be a reinterpret cast, but some compilers insist + // on giving cv-qualifiers to free functions + functor.members.func_ptr = reinterpret_cast(f); + return true; + } else { + return false; + } + } + template + bool + assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const + { + return assign_to(f,functor,function_ptr_tag()); + } + + // Member pointers +#if BOOST_FUNCTION_NUM_ARGS > 0 + template + bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const + { + // DPG TBD: Add explicit support for member function + // objects, so we invoke through mem_fn() but we retain the + // right target_type() values. + if (f) { + this->assign_to(boost::mem_fn(f), functor); + return true; + } else { + return false; + } + } + template + bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const + { + // DPG TBD: Add explicit support for member function + // objects, so we invoke through mem_fn() but we retain the + // right target_type() values. + if (f) { + this->assign_to_a(boost::mem_fn(f), functor, a); + return true; + } else { + return false; + } + } +#endif // BOOST_FUNCTION_NUM_ARGS > 0 + + // Function objects + // Assign to a function object using the small object optimization + template + void + assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const + { + new (reinterpret_cast(functor.data)) FunctionObj(f); + } + template + void + assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const + { + assign_functor(f,functor,mpl::true_()); + } + + // Assign to a function object allocated on the heap. + template + void + assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const + { + functor.members.obj_ptr = new FunctionObj(f); + } + template + void + assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const + { + typedef functor_wrapper functor_wrapper_type; +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Allocator::template rebind::other + wrapper_allocator_type; + typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type; +#else + using wrapper_allocator_type = typename std::allocator_traits::template rebind_alloc; + using wrapper_allocator_pointer_type = typename std::allocator_traits::pointer; +#endif + wrapper_allocator_type wrapper_allocator(a); + wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); +#if defined(BOOST_NO_CXX11_ALLOCATOR) + wrapper_allocator.construct(copy, functor_wrapper_type(f,a)); +#else + std::allocator_traits::construct(wrapper_allocator, copy, functor_wrapper_type(f,a)); +#endif + functor_wrapper_type* new_f = static_cast(copy); + functor.members.obj_ptr = new_f; + } + + template + bool + assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const + { + if (!boost::detail::function::has_empty_target(boost::addressof(f))) { + assign_functor(f, functor, + mpl::bool_<(function_allows_small_object_optimization::value)>()); + return true; + } else { + return false; + } + } + template + bool + assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const + { + if (!boost::detail::function::has_empty_target(boost::addressof(f))) { + assign_functor_a(f, functor, a, + mpl::bool_<(function_allows_small_object_optimization::value)>()); + return true; + } else { + return false; + } + } + + // Reference to a function object + template + bool + assign_to(const reference_wrapper& f, + function_buffer& functor, function_obj_ref_tag) const + { + functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer()); + functor.members.obj_ref.is_const_qualified = is_const::value; + functor.members.obj_ref.is_volatile_qualified = is_volatile::value; + return true; + } + template + bool + assign_to_a(const reference_wrapper& f, + function_buffer& functor, Allocator, function_obj_ref_tag) const + { + return assign_to(f,functor,function_obj_ref_tag()); + } + + public: + vtable_base base; + invoker_type invoker; + }; + } // end namespace function + } // end namespace detail + + template< + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + class BOOST_FUNCTION_FUNCTION : public function_base + { + public: +#ifndef BOOST_NO_VOID_RETURNS + typedef R result_type; +#else + typedef typename boost::detail::function::function_return_type::type + result_type; +#endif // BOOST_NO_VOID_RETURNS + + private: + typedef boost::detail::function::BOOST_FUNCTION_VTABLE< + R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> + vtable_type; + + vtable_type* get_vtable() const { + return reinterpret_cast( + reinterpret_cast(vtable) & ~static_cast(0x01)); + } + + struct clear_type {}; + + public: + BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS); + + // add signature for boost::lambda + template + struct sig + { + typedef result_type type; + }; + +#if BOOST_FUNCTION_NUM_ARGS == 1 + typedef T0 argument_type; +#elif BOOST_FUNCTION_NUM_ARGS == 2 + typedef T0 first_argument_type; + typedef T1 second_argument_type; +#endif + + BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS); + BOOST_FUNCTION_ARG_TYPES + + typedef BOOST_FUNCTION_FUNCTION self_type; + + BOOST_FUNCTION_FUNCTION() : function_base() { } + + // MSVC chokes if the following two constructors are collapsed into + // one with a default parameter. + template + BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_c< + !(is_integral::value), + int>::type = 0 +#endif // BOOST_NO_SFINAE + ) : + function_base() + { + this->assign_to(f); + } + template + BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_c< + !(is_integral::value), + int>::type = 0 +#endif // BOOST_NO_SFINAE + ) : + function_base() + { + this->assign_to_a(f,a); + } + +#ifndef BOOST_NO_SFINAE + BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { } +#else + BOOST_FUNCTION_FUNCTION(int zero) : function_base() + { + BOOST_ASSERT(zero == 0); + } +#endif + + BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base() + { + this->assign_to_own(f); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base() + { + this->move_assign(f); + } +#endif + + ~BOOST_FUNCTION_FUNCTION() { clear(); } + + result_type operator()(BOOST_FUNCTION_PARMS) const + { + if (this->empty()) + boost::throw_exception(bad_function_call()); + + return get_vtable()->invoker + (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); + } + + // The distinction between when to use BOOST_FUNCTION_FUNCTION and + // when to use self_type is obnoxious. MSVC cannot handle self_type as + // the return type of these assignment operators, but Borland C++ cannot + // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to + // construct. + template +#ifndef BOOST_NO_SFINAE + typename boost::enable_if_c< + !(is_integral::value), + BOOST_FUNCTION_FUNCTION&>::type +#else + BOOST_FUNCTION_FUNCTION& +#endif + operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) + { + this->clear(); + BOOST_TRY { + this->assign_to(f); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + return *this; + } + template + void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a) + { + this->clear(); + BOOST_TRY{ + this->assign_to_a(f,a); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#ifndef BOOST_NO_SFINAE + BOOST_FUNCTION_FUNCTION& operator=(clear_type*) + { + this->clear(); + return *this; + } +#else + BOOST_FUNCTION_FUNCTION& operator=(int zero) + { + BOOST_ASSERT(zero == 0); + this->clear(); + return *this; + } +#endif + + // Assignment from another BOOST_FUNCTION_FUNCTION + BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f) + { + if (&f == this) + return *this; + + this->clear(); + BOOST_TRY { + this->assign_to_own(f); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Move assignment from another BOOST_FUNCTION_FUNCTION + BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f) + { + if (&f == this) + return *this; + + this->clear(); + BOOST_TRY { + this->move_assign(f); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + return *this; + } +#endif + + void swap(BOOST_FUNCTION_FUNCTION& other) + { + if (&other == this) + return; + + BOOST_FUNCTION_FUNCTION tmp; + tmp.move_assign(*this); + this->move_assign(other); + other.move_assign(tmp); + } + + // Clear out a target, if there is one + void clear() + { + if (vtable) { + if (!this->has_trivial_copy_and_destroy()) + get_vtable()->clear(this->functor); + vtable = 0; + } + } + +#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG) + // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it + operator bool () const { return !this->empty(); } +#else + private: + struct dummy { + void nonnull() {} + }; + + typedef void (dummy::*safe_bool)(); + + public: + operator safe_bool () const + { return (this->empty())? 0 : &dummy::nonnull; } + + bool operator!() const + { return this->empty(); } +#endif + + private: + void assign_to_own(const BOOST_FUNCTION_FUNCTION& f) + { + if (!f.empty()) { + this->vtable = f.vtable; + if (this->has_trivial_copy_and_destroy()) + this->functor = f.functor; + else + get_vtable()->base.manager(f.functor, this->functor, + boost::detail::function::clone_functor_tag); + } + } + + template + void assign_to(Functor f) + { + using boost::detail::function::vtable_base; + + typedef typename boost::detail::function::get_function_tag::type tag; + typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; + typedef typename get_invoker:: + template apply + handler_type; + + typedef typename handler_type::invoker_type invoker_type; + typedef typename handler_type::manager_type manager_type; + + // Note: it is extremely important that this initialization use + // static initialization. Otherwise, we will have a race + // condition here in multi-threaded code. See + // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. + static const vtable_type stored_vtable = + { { &manager_type::manage }, &invoker_type::invoke }; + + if (stored_vtable.assign_to(f, functor)) { + std::size_t value = reinterpret_cast(&stored_vtable.base); + // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). + if (boost::has_trivial_copy_constructor::value && + boost::has_trivial_destructor::value && + boost::detail::function::function_allows_small_object_optimization::value) + value |= static_cast(0x01); + vtable = reinterpret_cast(value); + } else + vtable = 0; + } + + template + void assign_to_a(Functor f,Allocator a) + { + using boost::detail::function::vtable_base; + + typedef typename boost::detail::function::get_function_tag::type tag; + typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; + typedef typename get_invoker:: + template apply_a + handler_type; + + typedef typename handler_type::invoker_type invoker_type; + typedef typename handler_type::manager_type manager_type; + + // Note: it is extremely important that this initialization use + // static initialization. Otherwise, we will have a race + // condition here in multi-threaded code. See + // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. + static const vtable_type stored_vtable = + { { &manager_type::manage }, &invoker_type::invoke }; + + if (stored_vtable.assign_to_a(f, functor, a)) { + std::size_t value = reinterpret_cast(&stored_vtable.base); + // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). + if (boost::has_trivial_copy_constructor::value && + boost::has_trivial_destructor::value && + boost::detail::function::function_allows_small_object_optimization::value) + value |= static_cast(0x01); + vtable = reinterpret_cast(value); + } else + vtable = 0; + } + + // Moves the value from the specified argument to *this. If the argument + // has its function object allocated on the heap, move_assign will pass + // its buffer to *this, and set the argument's buffer pointer to NULL. + void move_assign(BOOST_FUNCTION_FUNCTION& f) + { + if (&f == this) + return; + + BOOST_TRY { + if (!f.empty()) { + this->vtable = f.vtable; + if (this->has_trivial_copy_and_destroy()) + this->functor = f.functor; + else + get_vtable()->base.manager(f.functor, this->functor, + boost::detail::function::move_functor_tag); + f.vtable = 0; + } else { + clear(); + } + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + } + }; + + template + inline void swap(BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >& f1, + BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >& f2) + { + f1.swap(f2); + } + +// Poison comparisons between boost::function objects of the same type. +template + void operator==(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>&, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>&); +template + void operator!=(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>&, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>& ); + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + +#if BOOST_FUNCTION_NUM_ARGS == 0 +#define BOOST_FUNCTION_PARTIAL_SPEC R (void) +#else +#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T)) +#endif + +template +class function + : public BOOST_FUNCTION_FUNCTION +{ + typedef BOOST_FUNCTION_FUNCTION base_type; + typedef function self_type; + + struct clear_type {}; + +public: + + function() : base_type() {} + + template + function(Functor f +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_c< + !(is_integral::value), + int>::type = 0 +#endif + ) : + base_type(f) + { + } + template + function(Functor f, Allocator a +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_c< + !(is_integral::value), + int>::type = 0 +#endif + ) : + base_type(f,a) + { + } + +#ifndef BOOST_NO_SFINAE + function(clear_type*) : base_type() {} +#endif + + function(const self_type& f) : base_type(static_cast(f)){} + + function(const base_type& f) : base_type(static_cast(f)){} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Move constructors + function(self_type&& f): base_type(static_cast(f)){} + function(base_type&& f): base_type(static_cast(f)){} +#endif + + self_type& operator=(const self_type& f) + { + self_type(f).swap(*this); + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + self_type& operator=(self_type&& f) + { + self_type(static_cast(f)).swap(*this); + return *this; + } +#endif + + template +#ifndef BOOST_NO_SFINAE + typename boost::enable_if_c< + !(is_integral::value), + self_type&>::type +#else + self_type& +#endif + operator=(Functor f) + { + self_type(f).swap(*this); + return *this; + } + +#ifndef BOOST_NO_SFINAE + self_type& operator=(clear_type*) + { + this->clear(); + return *this; + } +#endif + + self_type& operator=(const base_type& f) + { + self_type(f).swap(*this); + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + self_type& operator=(base_type&& f) + { + self_type(static_cast(f)).swap(*this); + return *this; + } +#endif +}; + +#undef BOOST_FUNCTION_PARTIAL_SPEC +#endif // have partial specialization + +} // end namespace boost + +// Cleanup after ourselves... +#undef BOOST_FUNCTION_VTABLE +#undef BOOST_FUNCTION_COMMA +#undef BOOST_FUNCTION_FUNCTION +#undef BOOST_FUNCTION_FUNCTION_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER +#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_MEMBER_INVOKER +#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER +#undef BOOST_FUNCTION_GET_INVOKER +#undef BOOST_FUNCTION_TEMPLATE_PARMS +#undef BOOST_FUNCTION_TEMPLATE_ARGS +#undef BOOST_FUNCTION_PARMS +#undef BOOST_FUNCTION_PARM +#ifdef BOOST_FUNCTION_ARG +# undef BOOST_FUNCTION_ARG +#endif +#undef BOOST_FUNCTION_ARGS +#undef BOOST_FUNCTION_ARG_TYPE +#undef BOOST_FUNCTION_ARG_TYPES +#undef BOOST_FUNCTION_VOID_RETURN_TYPE +#undef BOOST_FUNCTION_RETURN + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif diff --git a/boost/function_equal.hpp b/boost/function_equal.hpp new file mode 100644 index 00000000..2d76c75b --- /dev/null +++ b/boost/function_equal.hpp @@ -0,0 +1,28 @@ +// Copyright Douglas Gregor 2004. +// Copyright 2005 Peter Dimov + +// 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) + +// For more information, see http://www.boost.org +#ifndef BOOST_FUNCTION_EQUAL_HPP +#define BOOST_FUNCTION_EQUAL_HPP + +namespace boost { + +template + bool function_equal_impl(const F& f, const G& g, long) + { return f == g; } + +// function_equal_impl needs to be unqualified to pick +// user overloads on two-phase compilers + +template + bool function_equal(const F& f, const G& g) + { return function_equal_impl(f, g, 0); } + +} // end namespace boost + +#endif // BOOST_FUNCTION_EQUAL_HPP diff --git a/boost/functional/hash.hpp b/boost/functional/hash.hpp new file mode 100644 index 00000000..327a3eca --- /dev/null +++ b/boost/functional/hash.hpp @@ -0,0 +1,6 @@ + +// Copyright 2005-2009 Daniel James. +// 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 diff --git a/boost/functional/hash_fwd.hpp b/boost/functional/hash_fwd.hpp new file mode 100644 index 00000000..62bc23c7 --- /dev/null +++ b/boost/functional/hash_fwd.hpp @@ -0,0 +1,6 @@ + +// Copyright 2005-2009 Daniel James. +// 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 diff --git a/boost/get_pointer.hpp b/boost/get_pointer.hpp new file mode 100644 index 00000000..36e2cd7d --- /dev/null +++ b/boost/get_pointer.hpp @@ -0,0 +1,76 @@ +// Copyright Peter Dimov and 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 GET_POINTER_DWA20021219_HPP +#define GET_POINTER_DWA20021219_HPP + +#include + +// In order to avoid circular dependencies with Boost.TR1 +// we make sure that our include of doesn't try to +// pull in the TR1 headers: that's why we use this header +// rather than including directly: +#include // std::auto_ptr + +namespace boost { + +// get_pointer(p) extracts a ->* capable pointer from p + +template T * get_pointer(T * p) +{ + return p; +} + +// get_pointer(shared_ptr const & p) has been moved to shared_ptr.hpp + +#if !defined( BOOST_NO_AUTO_PTR ) + +#if defined( __GNUC__ ) && (defined( __GXX_EXPERIMENTAL_CXX0X__ ) || (__cplusplus >= 201103L)) +#if defined( BOOST_GCC ) +#if BOOST_GCC >= 40600 +#define BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS +#endif // BOOST_GCC >= 40600 +#elif defined( __clang__ ) && defined( __has_warning ) +#if __has_warning("-Wdeprecated-declarations") +#define BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS +#endif // __has_warning("-Wdeprecated-declarations") +#endif +#endif // defined( __GNUC__ ) && (defined( __GXX_EXPERIMENTAL_CXX0X__ ) || (__cplusplus >= 201103L)) + +#if defined( BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS ) +// Disable libstdc++ warnings about std::auto_ptr being deprecated in C++11 mode +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#define BOOST_CORE_DETAIL_DISABLED_DEPRECATED_WARNINGS +#endif + +template T * get_pointer(std::auto_ptr const& p) +{ + return p.get(); +} + +#if defined( BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS ) +#pragma GCC diagnostic pop +#undef BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS +#endif + +#endif // !defined( BOOST_NO_AUTO_PTR ) + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + +template T * get_pointer( std::unique_ptr const& p ) +{ + return p.get(); +} + +template T * get_pointer( std::shared_ptr const& p ) +{ + return p.get(); +} + +#endif + +} // namespace boost + +#endif // GET_POINTER_DWA20021219_HPP diff --git a/boost/indirect_reference.hpp b/boost/indirect_reference.hpp new file mode 100644 index 00000000..3279cd05 --- /dev/null +++ b/boost/indirect_reference.hpp @@ -0,0 +1,43 @@ +#ifndef INDIRECT_REFERENCE_DWA200415_HPP +# define INDIRECT_REFERENCE_DWA200415_HPP + +// +// Copyright David Abrahams 2004. 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) +// +// typename indirect_reference

::type provides the type of *p. +// +// http://www.boost.org/libs/iterator/doc/pointee.html +// + +# include +# include +# include +# include +# include + +namespace boost { + +namespace detail +{ + template + struct smart_ptr_reference + { + typedef typename boost::pointee

::type& type; + }; +} + +template +struct indirect_reference + : mpl::eval_if< + detail::is_incrementable

+ , iterator_reference

+ , detail::smart_ptr_reference

+ > +{ +}; + +} // namespace boost + +#endif // INDIRECT_REFERENCE_DWA200415_HPP diff --git a/boost/integer.hpp b/boost/integer.hpp new file mode 100644 index 00000000..9fa00194 --- /dev/null +++ b/boost/integer.hpp @@ -0,0 +1,262 @@ +// boost integer.hpp header file -------------------------------------------// + +// Copyright Beman Dawes and Daryle Walker 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/integer for documentation. + +// Revision History +// 22 Sep 01 Added value-based integer templates. (Daryle Walker) +// 01 Apr 01 Modified to use new header. (John Maddock) +// 30 Jul 00 Add typename syntax fix (Jens Maurer) +// 28 Aug 99 Initial version + +#ifndef BOOST_INTEGER_HPP +#define BOOST_INTEGER_HPP + +#include // self include + +#include // for boost::::boost::integer_traits +#include // for ::std::numeric_limits +#include // for boost::int64_t and BOOST_NO_INTEGRAL_INT64_T +#include + +// +// We simply cannot include this header on gcc without getting copious warnings of the kind: +// +// boost/integer.hpp:77:30: warning: use of C99 long long integer constant +// +// And yet there is no other reasonable implementation, so we declare this a system header +// to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +namespace boost +{ + + // Helper templates ------------------------------------------------------// + + // fast integers from least integers + // int_fast_t<> works correctly for unsigned too, in spite of the name. + template< typename LeastInt > + struct int_fast_t + { + typedef LeastInt fast; + typedef fast type; + }; // imps may specialize + + namespace detail{ + + // convert category to type + template< int Category > struct int_least_helper {}; // default is empty + template< int Category > struct uint_least_helper {}; // default is empty + + // specializatons: 1=long, 2=int, 3=short, 4=signed char, + // 6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned char + // no specializations for 0 and 5: requests for a type > long are in error +#ifdef BOOST_HAS_LONG_LONG + template<> struct int_least_helper<1> { typedef boost::long_long_type least; }; +#elif defined(BOOST_HAS_MS_INT64) + template<> struct int_least_helper<1> { typedef __int64 least; }; +#endif + template<> struct int_least_helper<2> { typedef long least; }; + template<> struct int_least_helper<3> { typedef int least; }; + template<> struct int_least_helper<4> { typedef short least; }; + template<> struct int_least_helper<5> { typedef signed char least; }; +#ifdef BOOST_HAS_LONG_LONG + template<> struct uint_least_helper<1> { typedef boost::ulong_long_type least; }; +#elif defined(BOOST_HAS_MS_INT64) + template<> struct uint_least_helper<1> { typedef unsigned __int64 least; }; +#endif + template<> struct uint_least_helper<2> { typedef unsigned long least; }; + template<> struct uint_least_helper<3> { typedef unsigned int least; }; + template<> struct uint_least_helper<4> { typedef unsigned short least; }; + template<> struct uint_least_helper<5> { typedef unsigned char least; }; + + template + struct exact_signed_base_helper{}; + template + struct exact_unsigned_base_helper{}; + + template <> struct exact_signed_base_helper { typedef signed char exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned char exact; }; +#if USHRT_MAX != UCHAR_MAX + template <> struct exact_signed_base_helper { typedef short exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned short exact; }; +#endif +#if UINT_MAX != USHRT_MAX + template <> struct exact_signed_base_helper { typedef int exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned int exact; }; +#endif +#if ULONG_MAX != UINT_MAX && ( !defined __TI_COMPILER_VERSION__ || \ + ( __TI_COMPILER_VERSION__ >= 7000000 && !defined __TI_40BIT_LONG__ ) ) + template <> struct exact_signed_base_helper { typedef long exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned long exact; }; +#endif +#if defined(BOOST_HAS_LONG_LONG) &&\ + ((defined(ULLONG_MAX) && (ULLONG_MAX != ULONG_MAX)) ||\ + (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX != ULONG_MAX)) ||\ + (defined(ULONGLONG_MAX) && (ULONGLONG_MAX != ULONG_MAX)) ||\ + (defined(_ULLONG_MAX) && (_ULLONG_MAX != ULONG_MAX))) + template <> struct exact_signed_base_helper { typedef boost::long_long_type exact; }; + template <> struct exact_unsigned_base_helper { typedef boost::ulong_long_type exact; }; +#endif + + + } // namespace detail + + // integer templates specifying number of bits ---------------------------// + + // signed + template< int Bits > // bits (including sign) required + struct int_t : public boost::detail::exact_signed_base_helper + { + BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::intmax_t) * CHAR_BIT), + "No suitable signed integer type with the requested number of bits is available."); + typedef typename boost::detail::int_least_helper + < +#ifdef BOOST_HAS_LONG_LONG + (Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) + +#else + 1 + +#endif + (Bits-1 <= ::std::numeric_limits::digits) + + (Bits-1 <= ::std::numeric_limits::digits) + + (Bits-1 <= ::std::numeric_limits::digits) + + (Bits-1 <= ::std::numeric_limits::digits) + >::least least; + typedef typename int_fast_t::type fast; + }; + + // unsigned + template< int Bits > // bits required + struct uint_t : public boost::detail::exact_unsigned_base_helper + { + BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::uintmax_t) * CHAR_BIT), + "No suitable unsigned integer type with the requested number of bits is available."); +#if (defined(__BORLANDC__) || defined(__CODEGEAR__)) && defined(BOOST_NO_INTEGRAL_INT64_T) + // It's really not clear why this workaround should be needed... shrug I guess! JM + BOOST_STATIC_CONSTANT(int, s = + 6 + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits)); + typedef typename detail::int_least_helper< ::boost::uint_t::s>::least least; +#else + typedef typename boost::detail::uint_least_helper + < +#ifdef BOOST_HAS_LONG_LONG + (Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) + +#else + 1 + +#endif + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + >::least least; +#endif + typedef typename int_fast_t::type fast; + // int_fast_t<> works correctly for unsigned too, in spite of the name. + }; + + // integer templates specifying extreme value ----------------------------// + + // signed +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MaxValue > // maximum value to require support +#else + template< long MaxValue > // maximum value to require support +#endif + struct int_max_value_t + { + typedef typename boost::detail::int_least_helper + < +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + (MaxValue <= ::boost::integer_traits::const_max) + +#else + 1 + +#endif + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + >::least least; + typedef typename int_fast_t::type fast; + }; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MinValue > // minimum value to require support +#else + template< long MinValue > // minimum value to require support +#endif + struct int_min_value_t + { + typedef typename boost::detail::int_least_helper + < +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + (MinValue >= ::boost::integer_traits::const_min) + +#else + 1 + +#endif + (MinValue >= ::boost::integer_traits::const_min) + + (MinValue >= ::boost::integer_traits::const_min) + + (MinValue >= ::boost::integer_traits::const_min) + + (MinValue >= ::boost::integer_traits::const_min) + >::least least; + typedef typename int_fast_t::type fast; + }; + + // unsigned +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::ulong_long_type MaxValue > // minimum value to require support +#else + template< unsigned long MaxValue > // minimum value to require support +#endif + struct uint_value_t + { +#if (defined(__BORLANDC__) || defined(__CODEGEAR__)) + // It's really not clear why this workaround should be needed... shrug I guess! JM +#if defined(BOOST_NO_INTEGRAL_INT64_T) + BOOST_STATIC_CONSTANT(unsigned, which = + 1 + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max)); + typedef typename detail::int_least_helper< ::boost::uint_value_t::which>::least least; +#else // BOOST_NO_INTEGRAL_INT64_T + BOOST_STATIC_CONSTANT(unsigned, which = + 1 + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max)); + typedef typename detail::uint_least_helper< ::boost::uint_value_t::which>::least least; +#endif // BOOST_NO_INTEGRAL_INT64_T +#else + typedef typename boost::detail::uint_least_helper + < +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + (MaxValue <= ::boost::integer_traits::const_max) + +#else + 1 + +#endif + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + >::least least; +#endif + typedef typename int_fast_t::type fast; + }; + + +} // namespace boost + +#endif // BOOST_INTEGER_HPP diff --git a/boost/integer/common_factor_rt.hpp b/boost/integer/common_factor_rt.hpp new file mode 100644 index 00000000..341b3165 --- /dev/null +++ b/boost/integer/common_factor_rt.hpp @@ -0,0 +1,578 @@ +// (C) Copyright Jeremy William Murphy 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) + +#ifndef BOOST_INTEGER_COMMON_FACTOR_RT_HPP +#define BOOST_INTEGER_COMMON_FACTOR_RT_HPP + +#include +#include + +#include // for BOOST_NESTED_TEMPLATE, etc. +#include // for std::numeric_limits +#include // for CHAR_MIN +#include +#include +#include +#include +#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS +#include +#endif +#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL +#include +#endif + +#if ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) +#include +#endif + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4127 4244) // Conditional expression is constant +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_CXX11_NOEXCEPT) +#define BOOST_GCD_NOEXCEPT(T) noexcept(std::is_arithmetic::value) +#else +#define BOOST_GCD_NOEXCEPT(T) +#endif + +namespace boost { + + template + class rational; + + namespace integer { + + namespace gcd_detail{ + + // + // some helper functions which really should be constexpr already, but sadly aren't: + // +#ifndef BOOST_NO_CXX14_CONSTEXPR + template + inline constexpr T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T) + { + return a < b ? a : b; + } + template + inline constexpr auto constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T) -> decltype(a.swap(b)) + { + return a.swap(b); + } + template + inline constexpr void constexpr_swap(T&a, U& b...) BOOST_GCD_NOEXCEPT(T) + { + T t(static_cast(a)); + a = static_cast(b); + b = static_cast(t); + } +#else + template + inline T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T) + { + return a < b ? a : b; + } + template + inline void constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T) + { + using std::swap; + swap(a, b); + } +#endif + + template ::value || +#endif + (std::numeric_limits::is_specialized && !std::numeric_limits::is_signed)> + struct gcd_traits_abs_defaults + { + inline static BOOST_CXX14_CONSTEXPR const T& abs(const T& val) BOOST_GCD_NOEXCEPT(T) { return val; } + }; + template + struct gcd_traits_abs_defaults + { + inline static T BOOST_CXX14_CONSTEXPR abs(const T& val) BOOST_GCD_NOEXCEPT(T) + { + // This sucks, but std::abs is not constexpr :( + return val < T(0) ? -val : val; + } + }; + + enum method_type + { + method_euclid = 0, + method_binary = 1, + method_mixed = 2 + }; + + struct any_convert + { + template + any_convert(const T&); + }; + + struct unlikely_size + { + char buf[9973]; + }; + + unlikely_size operator <<= (any_convert, any_convert); + unlikely_size operator >>= (any_convert, any_convert); + + template + struct gcd_traits_defaults : public gcd_traits_abs_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(T& val) BOOST_GCD_NOEXCEPT(T) + { + unsigned r = 0; + while(0 == (val & 1u)) + { +#ifdef _MSC_VER // VC++ can't handle operator >>= in constexpr code for some reason + val = val >> 1; +#else + val >>= 1; +#endif + ++r; + } + return r; + } + inline static BOOST_CXX14_CONSTEXPR bool less(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T) + { + return a < b; + } + + static T& get_value(); + +#ifndef BOOST_NO_SFINAE + static const bool has_operator_left_shift_equal = sizeof(get_value() <<= 2) != sizeof(unlikely_size); + static const bool has_operator_right_shift_equal = sizeof(get_value() >>= 2) != sizeof(unlikely_size); +#else + static const bool has_operator_left_shift_equal = true; + static const bool has_operator_right_shift_equal = true; +#endif + static const method_type method = std::numeric_limits::is_specialized && std::numeric_limits::is_integer && has_operator_left_shift_equal && has_operator_right_shift_equal ? method_mixed : method_euclid; + }; + // + // Default gcd_traits just inherits from defaults: + // + template + struct gcd_traits : public gcd_traits_defaults {}; + + // + // Some platforms have fast bitscan operations, that allow us to implement + // make_odd much more efficiently, unfortunately we can't use these if we want + // the functions to be constexpr as the compiler intrinsics aren't constexpr. + // +#if defined(BOOST_NO_CXX14_CONSTEXPR) && ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) +#pragma intrinsic(_BitScanForward,) + template <> + struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static unsigned find_lsb(unsigned long val) BOOST_NOEXCEPT + { + unsigned long result; + _BitScanForward(&result, val); + return result; + } + BOOST_FORCEINLINE static unsigned make_odd(unsigned long& val) BOOST_NOEXCEPT + { + unsigned result = find_lsb(val); + val >>= result; + return result; + } + }; + +#ifdef _M_X64 +#pragma intrinsic(_BitScanForward64) + template <> + struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static unsigned find_lsb(unsigned __int64 mask) BOOST_NOEXCEPT + { + unsigned long result; + _BitScanForward64(&result, mask); + return result; + } + BOOST_FORCEINLINE static unsigned make_odd(unsigned __int64& val) BOOST_NOEXCEPT + { + unsigned result = find_lsb(val); + val >>= result; + return result; + } + }; +#endif + // + // Other integer type are trivial adaptations of the above, + // this works for signed types too, as by the time these functions + // are called, all values are > 0. + // + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(long& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(unsigned int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static signed make_odd(signed char& val)BOOST_NOEXCEPT{ signed result = gcd_traits::find_lsb(val); val >>= result; return result; } }; + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; +#ifndef BOOST_NO_INTRINSIC_WCHAR_T + template <> struct gcd_traits : public gcd_traits_defaults + { BOOST_FORCEINLINE static unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; +#endif +#ifdef _M_X64 + template <> struct gcd_traits<__int64> : public gcd_traits_defaults<__int64> + { BOOST_FORCEINLINE static unsigned make_odd(__int64& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } }; +#endif + +#elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__)) + + template <> + struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(unsigned mask)BOOST_NOEXCEPT + { + return __builtin_ctz(mask); + } + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned& val)BOOST_NOEXCEPT + { + unsigned result = find_lsb(val); + val >>= result; + return result; + } + }; + template <> + struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(unsigned long mask)BOOST_NOEXCEPT + { + return __builtin_ctzl(mask); + } + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned long& val)BOOST_NOEXCEPT + { + unsigned result = find_lsb(val); + val >>= result; + return result; + } + }; + template <> + struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(boost::ulong_long_type mask)BOOST_NOEXCEPT + { + return __builtin_ctzll(mask); + } + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(boost::ulong_long_type& val)BOOST_NOEXCEPT + { + unsigned result = find_lsb(val); + val >>= result; + return result; + } + }; + // + // Other integer type are trivial adaptations of the above, + // this works for signed types too, as by the time these functions + // are called, all values are > 0. + // + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(boost::long_long_type& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(long& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(int& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR signed make_odd(signed char& val)BOOST_NOEXCEPT { signed result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; +#ifndef BOOST_NO_INTRINSIC_WCHAR_T + template <> struct gcd_traits : public gcd_traits_defaults + { + BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT { unsigned result = gcd_traits::find_lsb(val); val >>= result; return result; } + }; +#endif +#endif + // + // The Mixed Binary Euclid Algorithm + // Sidi Mohamed Sedjelmaci + // Electronic Notes in Discrete Mathematics 35 (2009) 169-176 + // + template + BOOST_CXX14_CONSTEXPR T mixed_binary_gcd(T u, T v) BOOST_GCD_NOEXCEPT(T) + { + if(gcd_traits::less(u, v)) + constexpr_swap(u, v); + + unsigned shifts = 0; + + if(u == T(0)) + return v; + if(v == T(0)) + return u; + + shifts = constexpr_min(gcd_traits::make_odd(u), gcd_traits::make_odd(v)); + + while(gcd_traits::less(1, v)) + { + u %= v; + v -= u; + if(u == T(0)) + return v << shifts; + if(v == T(0)) + return u << shifts; + gcd_traits::make_odd(u); + gcd_traits::make_odd(v); + if(gcd_traits::less(u, v)) + constexpr_swap(u, v); + } + return (v == 1 ? v : u) << shifts; + } + + /** Stein gcd (aka 'binary gcd') + * + * From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose + */ + template + BOOST_CXX14_CONSTEXPR SteinDomain Stein_gcd(SteinDomain m, SteinDomain n) BOOST_GCD_NOEXCEPT(SteinDomain) + { + BOOST_ASSERT(m >= 0); + BOOST_ASSERT(n >= 0); + if (m == SteinDomain(0)) + return n; + if (n == SteinDomain(0)) + return m; + // m > 0 && n > 0 + int d_m = gcd_traits::make_odd(m); + int d_n = gcd_traits::make_odd(n); + // odd(m) && odd(n) + while (m != n) + { + if (n > m) + constexpr_swap(n, m); + m -= n; + gcd_traits::make_odd(m); + } + // m == n + m <<= constexpr_min(d_m, d_n); + return m; + } + + + /** Euclidean algorithm + * + * From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose + * + */ + template + inline BOOST_CXX14_CONSTEXPR EuclideanDomain Euclid_gcd(EuclideanDomain a, EuclideanDomain b) BOOST_GCD_NOEXCEPT(EuclideanDomain) + { + while (b != EuclideanDomain(0)) + { + a %= b; + constexpr_swap(a, b); + } + return a; + } + + + template + inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c::method == method_mixed, T>::type + optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) + { + return gcd_detail::mixed_binary_gcd(a, b); + } + + template + inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c::method == method_binary, T>::type + optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) + { + return gcd_detail::Stein_gcd(a, b); + } + + template + inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c::method == method_euclid, T>::type + optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) + { + return gcd_detail::Euclid_gcd(a, b); + } + + template + inline BOOST_CXX14_CONSTEXPR T lcm_imp(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T) + { + T temp = boost::integer::gcd_detail::optimal_gcd_select(a, b); +#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) + return (temp != T(0)) ? T(a / temp * b) : T(0); +#else + return temp != T(0) ? T(a / temp * b) : T(0); +#endif + } + +} // namespace detail + + +template +inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer) +{ + if(a == (std::numeric_limits::min)()) + return a == static_cast(0) ? gcd_detail::gcd_traits::abs(b) : boost::integer::gcd(static_cast(a % b), b); + else if (b == (std::numeric_limits::min)()) + return b == static_cast(0) ? gcd_detail::gcd_traits::abs(a) : boost::integer::gcd(a, static_cast(b % a)); + return gcd_detail::optimal_gcd_select(static_cast(gcd_detail::gcd_traits::abs(a)), static_cast(gcd_detail::gcd_traits::abs(b))); +} + +template +inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer) +{ + return gcd_detail::lcm_imp(static_cast(gcd_detail::gcd_traits::abs(a)), static_cast(gcd_detail::gcd_traits::abs(b))); +} +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES +// +// This looks slightly odd, but the variadic forms must have 3 or more arguments, and the variadic argument pack may be empty. +// This matters not at all for most compilers, but Oracle C++ selects the wrong overload in the 2-arg case unless we do this. +// +template +inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b, const Integer& c, Args const&... args) BOOST_GCD_NOEXCEPT(Integer) +{ + Integer t = gcd(b, c, args...); + return t == 1 ? 1 : gcd(a, t); +} + +template +inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b, Integer const& c, Args const&... args) BOOST_GCD_NOEXCEPT(Integer) +{ + return lcm(a, lcm(b, c, args...)); +} +#endif +// +// Special handling for rationals: +// +template +inline typename boost::enable_if_c::is_specialized, boost::rational >::type gcd(boost::rational const &a, boost::rational const &b) +{ + return boost::rational(static_cast(gcd(a.numerator(), b.numerator())), static_cast(lcm(a.denominator(), b.denominator()))); +} + +template +inline typename boost::enable_if_c::is_specialized, boost::rational >::type lcm(boost::rational const &a, boost::rational const &b) +{ + return boost::rational(static_cast(lcm(a.numerator(), b.numerator())), static_cast(gcd(a.denominator(), b.denominator()))); +} +/** + * Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 + * Chapter 4.5.2, Algorithm C: Greatest common divisor of n integers. + * + * Knuth counts down from n to zero but we naturally go from first to last. + * We also return the termination position because it might be useful to know. + * + * Partly by quirk, partly by design, this algorithm is defined for n = 1, + * because the gcd of {x} is x. It is not defined for n = 0. + * + * @tparam I Input iterator. + * @return The gcd of the range and the iterator position at termination. + */ +template +std::pair::value_type, I> +gcd_range(I first, I last) BOOST_GCD_NOEXCEPT(I) +{ + BOOST_ASSERT(first != last); + typedef typename std::iterator_traits::value_type T; + + T d = *first++; + while (d != T(1) && first != last) + { + d = gcd(d, *first); + first++; + } + return std::make_pair(d, first); +} +template +std::pair::value_type, I> +lcm_range(I first, I last) BOOST_GCD_NOEXCEPT(I) +{ + BOOST_ASSERT(first != last); + typedef typename std::iterator_traits::value_type T; + + T d = *first++; + while (d != T(1) && first != last) + { + d = lcm(d, *first); + first++; + } + return std::make_pair(d, first); +} + +template < typename IntegerType > +class gcd_evaluator +#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL + : public std::binary_function +#endif +{ +public: +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + typedef IntegerType first_argument_type; + typedef IntegerType second_argument_type; + typedef IntegerType result_type; +#endif + IntegerType operator()(IntegerType const &a, IntegerType const &b)const + { + return boost::integer::gcd(a, b); + } +}; + +template < typename IntegerType > +class lcm_evaluator +#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL + : public std::binary_function +#endif +{ +public: +#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL + typedef IntegerType first_argument_type; + typedef IntegerType second_argument_type; + typedef IntegerType result_type; +#endif + IntegerType operator()(IntegerType const &a, IntegerType const &b)const + { + return boost::integer::lcm(a, b); + } +}; + +} // namespace integer +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_INTEGER_COMMON_FACTOR_RT_HPP diff --git a/boost/integer/static_log2.hpp b/boost/integer/static_log2.hpp new file mode 100644 index 00000000..56c7a001 --- /dev/null +++ b/boost/integer/static_log2.hpp @@ -0,0 +1,127 @@ +// -------------- Boost static_log2.hpp header file ----------------------- // +// +// Copyright (C) 2001 Daryle Walker. +// Copyright (C) 2003 Vesa Karvonen. +// Copyright (C) 2003 Gennaro Prota. +// +// 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. +// ------------------------------------------------------------------------- // + + +#ifndef BOOST_INTEGER_STATIC_LOG2_HPP +#define BOOST_INTEGER_STATIC_LOG2_HPP + +#include "boost/integer_fwd.hpp" // for boost::intmax_t + +namespace boost { + + namespace detail { + + namespace static_log2_impl { + + // choose_initial_n<> + // + // Recursively doubles its integer argument, until it + // becomes >= of the "width" (C99, 6.2.6.2p4) of + // static_log2_argument_type. + // + // Used to get the maximum power of two less then the width. + // + // Example: if on your platform argument_type has 48 value + // bits it yields n=32. + // + // It's easy to prove that, starting from such a value + // of n, the core algorithm works correctly for any width + // of static_log2_argument_type and that recursion always + // terminates with x = 1 and n = 0 (see the algorithm's + // invariant). + + typedef boost::static_log2_argument_type argument_type; + typedef boost::static_log2_result_type result_type; + + template + struct choose_initial_n { + + BOOST_STATIC_CONSTANT(bool, c = (argument_type(1) << n << n) != 0); + BOOST_STATIC_CONSTANT( + result_type, + value = !c*n + choose_initial_n<2*c*n>::value + ); + + }; + + template <> + struct choose_initial_n<0> { + BOOST_STATIC_CONSTANT(result_type, value = 0); + }; + + + + // start computing from n_zero - must be a power of two + const result_type n_zero = 16; + const result_type initial_n = choose_initial_n::value; + + // static_log2_impl<> + // + // * Invariant: + // 2n + // 1 <= x && x < 2 at the start of each recursion + // (see also choose_initial_n<>) + // + // * Type requirements: + // + // argument_type maybe any unsigned type with at least n_zero + 1 + // value bits. (Note: If larger types will be standardized -e.g. + // unsigned long long- then the argument_type typedef can be + // changed without affecting the rest of the code.) + // + + template + struct static_log2_impl { + + BOOST_STATIC_CONSTANT(bool, c = (x >> n) > 0); // x >= 2**n ? + BOOST_STATIC_CONSTANT( + result_type, + value = c*n + (static_log2_impl< (x>>c*n), n/2 >::value) + ); + + }; + + template <> + struct static_log2_impl<1, 0> { + BOOST_STATIC_CONSTANT(result_type, value = 0); + }; + + } + } // detail + + + + // -------------------------------------- + // static_log2 + // ---------------------------------------- + + template + struct static_log2 { + + BOOST_STATIC_CONSTANT( + static_log2_result_type, + value = detail::static_log2_impl::static_log2_impl::value + ); + + }; + + + template <> + struct static_log2<0> { }; + +} + + + +#endif // include guard diff --git a/boost/integer_fwd.hpp b/boost/integer_fwd.hpp new file mode 100644 index 00000000..18519dd6 --- /dev/null +++ b/boost/integer_fwd.hpp @@ -0,0 +1,190 @@ +// Boost integer_fwd.hpp header file ---------------------------------------// + +// (C) Copyright Dave Abrahams and Daryle Walker 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. + +#ifndef BOOST_INTEGER_FWD_HPP +#define BOOST_INTEGER_FWD_HPP + +#include // for UCHAR_MAX, etc. +#include // for std::size_t + +#include // for BOOST_NO_INTRINSIC_WCHAR_T +#include // for std::numeric_limits +#include // For intmax_t + + +namespace boost +{ + +#ifdef BOOST_NO_INTEGRAL_INT64_T + typedef unsigned long static_log2_argument_type; + typedef int static_log2_result_type; + typedef long static_min_max_signed_type; + typedef unsigned long static_min_max_unsigned_type; +#else + typedef boost::uintmax_t static_min_max_unsigned_type; + typedef boost::intmax_t static_min_max_signed_type; + typedef boost::uintmax_t static_log2_argument_type; + typedef int static_log2_result_type; +#endif + +// From ------------------------------------------------// + +// Only has typedefs or using statements, with #conditionals + + +// From -----------------------------------------// + +template < class T > + class integer_traits; + +template < > + class integer_traits< bool >; + +template < > + class integer_traits< char >; + +template < > + class integer_traits< signed char >; + +template < > + class integer_traits< unsigned char >; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template < > + class integer_traits< wchar_t >; +#endif + +template < > + class integer_traits< short >; + +template < > + class integer_traits< unsigned short >; + +template < > + class integer_traits< int >; + +template < > + class integer_traits< unsigned int >; + +template < > + class integer_traits< long >; + +template < > + class integer_traits< unsigned long >; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) +template < > +class integer_traits< ::boost::long_long_type>; + +template < > +class integer_traits< ::boost::ulong_long_type >; +#elif !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_MS_INT64) +template < > +class integer_traits<__int64>; + +template < > +class integer_traits; +#endif + + +// From ------------------------------------------------// + +template < typename LeastInt > + struct int_fast_t; + +template< int Bits > + struct int_t; + +template< int Bits > + struct uint_t; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MaxValue > // maximum value to require support +#else + template< long MaxValue > // maximum value to require support +#endif + struct int_max_value_t; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MinValue > // minimum value to require support +#else + template< long MinValue > // minimum value to require support +#endif + struct int_min_value_t; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::ulong_long_type MaxValue > // maximum value to require support +#else + template< unsigned long MaxValue > // maximum value to require support +#endif + struct uint_value_t; + + +// From -----------------------------------// + +template < std::size_t Bit > + struct high_bit_mask_t; + +template < std::size_t Bits > + struct low_bits_mask_t; + +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; + +// From ------------------------------------// + +template + struct static_log2; + +template <> struct static_log2<0u>; + + +// From ---------------------------------// + +template + struct static_signed_min; + +template + struct static_signed_max; + +template + struct static_unsigned_min; + +template + struct static_unsigned_max; + + +namespace integer +{ +// From + +#ifdef BOOST_NO_INTEGRAL_INT64_T + typedef unsigned long static_gcd_type; +#else + typedef boost::uintmax_t static_gcd_type; +#endif + +template < static_gcd_type Value1, static_gcd_type Value2 > + struct static_gcd; +template < static_gcd_type Value1, static_gcd_type Value2 > + struct static_lcm; + + +// From + +template < typename IntegerType > + class gcd_evaluator; +template < typename IntegerType > + class lcm_evaluator; + +} // namespace integer + +} // namespace boost + + +#endif // BOOST_INTEGER_FWD_HPP diff --git a/boost/integer_traits.hpp b/boost/integer_traits.hpp new file mode 100644 index 00000000..94eb00d3 --- /dev/null +++ b/boost/integer_traits.hpp @@ -0,0 +1,256 @@ +/* boost integer_traits.hpp header file + * + * Copyright Jens Maurer 2000 + * 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) + * + * $Id$ + * + * Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers + */ + +// See http://www.boost.org/libs/integer for documentation. + + +#ifndef BOOST_INTEGER_TRAITS_HPP +#define BOOST_INTEGER_TRAITS_HPP + +#include +#include + +// These are an implementation detail and not part of the interface +#include +// we need wchar.h for WCHAR_MAX/MIN but not all platforms provide it, +// and some may have but not ... +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && (!defined(BOOST_NO_CWCHAR) || defined(sun) || defined(__sun) || defined(__QNX__)) +#include +#endif + +// +// We simply cannot include this header on gcc without getting copious warnings of the kind: +// +// ../../../boost/integer_traits.hpp:164:66: warning: use of C99 long long integer constant +// +// And yet there is no other reasonable implementation, so we declare this a system header +// to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +namespace boost { +template +class integer_traits : public std::numeric_limits +{ +public: + BOOST_STATIC_CONSTANT(bool, is_integral = false); +}; + +namespace detail { +template +class integer_traits_base +{ +public: + BOOST_STATIC_CONSTANT(bool, is_integral = true); + BOOST_STATIC_CONSTANT(T, const_min = min_val); + BOOST_STATIC_CONSTANT(T, const_max = max_val); +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +template +const bool integer_traits_base::is_integral; + +template +const T integer_traits_base::const_min; + +template +const T integer_traits_base::const_max; +#endif + +} // namespace detail + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template<> +class integer_traits + : public std::numeric_limits, + // Don't trust WCHAR_MIN and WCHAR_MAX with Mac OS X's native + // library: they are wrong! +#if defined(WCHAR_MIN) && defined(WCHAR_MAX) && !defined(__APPLE__) + public detail::integer_traits_base +#elif defined(__BORLANDC__) || defined(__CYGWIN__) || defined(__MINGW32__) || (defined(__BEOS__) && defined(__GNUC__)) + // No WCHAR_MIN and WCHAR_MAX, whar_t is short and unsigned: + public detail::integer_traits_base +#elif (defined(__sgi) && (!defined(__SGI_STL_PORT) || __SGI_STL_PORT < 0x400))\ + || (defined __APPLE__)\ + || (defined(__OpenBSD__) && defined(__GNUC__))\ + || (defined(__NetBSD__) && defined(__GNUC__))\ + || (defined(__FreeBSD__) && defined(__GNUC__))\ + || (defined(__DragonFly__) && defined(__GNUC__))\ + || (defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 3) && !defined(__SGI_STL_PORT)) + // No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as int. + // - SGI MIPSpro with native library + // - gcc 3.x on HP-UX + // - Mac OS X with native library + // - gcc on FreeBSD, OpenBSD and NetBSD + public detail::integer_traits_base +#else +#error No WCHAR_MIN and WCHAR_MAX present, please adjust integer_traits<> for your compiler. +#endif +{ }; +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) +#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX> +{ }; + +#elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> : public std::numeric_limits< ::boost::long_long_type>, public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ }; +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX> +{ }; + +#elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX> +{ }; + +#elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX> +{ }; + +#elif defined(BOOST_HAS_LONG_LONG) +// +// we have long long but no constants, this happens for example with gcc in -ansi mode, +// we'll just have to work out the values for ourselves (assumes 2's compliment representation): +// +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1)), ~(1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1))> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL> +{ }; + +#elif defined(BOOST_HAS_MS_INT64) + +template<> +class integer_traits< __int64> + : public std::numeric_limits< __int64>, + public detail::integer_traits_base< __int64, _I64_MIN, _I64_MAX> +{ }; + +template<> +class integer_traits< unsigned __int64> + : public std::numeric_limits< unsigned __int64>, + public detail::integer_traits_base< unsigned __int64, 0, _UI64_MAX> +{ }; + +#endif +#endif + +} // namespace boost + +#endif /* BOOST_INTEGER_TRAITS_HPP */ + + + diff --git a/boost/intrusive/detail/algorithm.hpp b/boost/intrusive/detail/algorithm.hpp new file mode 100644 index 00000000..d2421ffa --- /dev/null +++ b/boost/intrusive/detail/algorithm.hpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP +#define BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +struct algo_pred_equal +{ + template + bool operator()(const T &x, const T &y) const + { return x == y; } +}; + +struct algo_pred_less +{ + template + bool operator()(const T &x, const T &y) const + { return x < y; } +}; + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p) +{ + for (; first1 != last1; ++first1, ++first2) { + if (!p(*first1, *first2)) { + return false; + } + } + return true; +} + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) +{ return (algo_equal)(first1, last1, first2, algo_pred_equal()); } + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate pred) +{ + for (; first1 != last1 && first2 != last2; ++first1, ++first2) + if (!pred(*first1, *first2)) + return false; + return first1 == last1 && first2 == last2; +} + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) +{ return (algo_equal)(first1, last1, first2, last2, algo_pred_equal()); } + +template + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred) +{ + while (first1 != last1){ + if (first2 == last2 || *first2 < *first1) return false; + else if (pred(*first1, *first2)) return true; + ++first1; ++first2; + } + return (first2 != last2); +} + +template + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) +{ return (algo_lexicographical_compare)(first1, last1, first2, last2, algo_pred_less()); } + +} //namespace intrusive { +} //namespace boost { + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP diff --git a/boost/intrusive/detail/config_begin.hpp b/boost/intrusive/detail/config_begin.hpp new file mode 100644 index 00000000..8bd57a3b --- /dev/null +++ b/boost/intrusive/detail/config_begin.hpp @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#ifdef BOOST_MSVC + + #pragma warning (push) + #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" + #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" + #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter + #pragma warning (disable : 4996) // "function": was declared deprecated + #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4244) // possible loss of data + #pragma warning (disable : 4521) ////Disable "multiple copy constructors specified" + #pragma warning (disable : 4127) //conditional expression is constant + #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data + #pragma warning (disable : 4541) //'typeid' used on polymorphic type 'boost::exception' with /GR- + #pragma warning (disable : 4512) //'typeid' used on polymorphic type 'boost::exception' with /GR- + #pragma warning (disable : 4522) // "class" : multiple assignment operators specified + #pragma warning (disable : 4706) //assignment within conditional expression + #pragma warning (disable : 4710) // function not inlined + #pragma warning (disable : 4714) // "function": marked as __forceinline not inlined + #pragma warning (disable : 4711) // function selected for automatic inline expansion + #pragma warning (disable : 4786) // identifier truncated in debug info + #pragma warning (disable : 4996) // "function": was declared deprecated +#endif + +//#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE +//#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE diff --git a/boost/intrusive/detail/config_end.hpp b/boost/intrusive/detail/config_end.hpp new file mode 100644 index 00000000..a081443e --- /dev/null +++ b/boost/intrusive/detail/config_end.hpp @@ -0,0 +1,15 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#if defined BOOST_MSVC + #pragma warning (pop) +#endif diff --git a/boost/intrusive/detail/has_member_function_callable_with.hpp b/boost/intrusive/detail/has_member_function_callable_with.hpp new file mode 100644 index 00000000..92ef60ee --- /dev/null +++ b/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -0,0 +1,366 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +//In case no decltype and no variadics, mark that we don't support 0 arg calls due to +//compiler ICE in GCC 3.4/4.0/4.1 and, wrong SFINAE for GCC 4.2/4.3/MSVC10/MSVC11 +#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# if defined(BOOST_GCC) && (BOOST_GCC < 40400) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# endif +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include +#include + +namespace boost_intrusive_hmfcw { + +typedef char yes_type; +struct no_type{ char dummy[2]; }; + +struct dont_care +{ + dont_care(...); +}; + +#if defined(BOOST_NO_CXX11_DECLTYPE) + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template +struct make_dontcare +{ + typedef dont_care type; +}; + +#endif + +struct private_type +{ + static private_type p; + private_type const &operator,(int) const; +}; + +template +no_type is_private_type(T const &); +yes_type is_private_type(private_type const &); + +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) + +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; + +#endif + +} //namespace boost_intrusive_hmfcw { + +#endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME before including this header!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN before including this header!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX before including this header!" +#endif + +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX < BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX value MUST be greater or equal than BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN!" +#endif + +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF +#else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF , +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG not defined!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!" +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) + //With decltype and variadic templaes, things are pretty easy + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template + static decltype(boost::move_detail::declval(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval()...) + , boost_intrusive_hmfcw::yes_type()) Test(U* f); + template + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + +#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX + // declaration, special case and 0 arg specializaton + // + ///////////////////////////////////////////////////////// + + template + class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + struct BaseMixin + { + void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + {} //Some compilers require the definition or linker errors happen + }; + + struct Base + : public boost_intrusive_hmfcw::remove_cv::type, public BaseMixin + { //Declare the unneeded default constructor as some old compilers wrongly require it with is_convertible + Base(){} + }; + template class Helper{}; + + template + static boost_intrusive_hmfcw::no_type deduce + (U*, Helper* = 0); + static boost_intrusive_hmfcw::yes_type deduce(...); + + public: + static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0)); + }; + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX for 1 to N arguments + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //defined(BOOST_NO_CXX11_DECLTYPE) must be true + template + struct FunWrapTmpl : Fun + { + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; + FunWrapTmpl(); + template + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const; + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); + + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + + { + static const bool value = false; + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type + ( (::boost::move_detail::declval + < FunWrapTmpl >(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval()...), 0) ) + ) + ); + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + ::value + , Args...> + {}; + #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX specializations + // + ///////////////////////////////////////////////////////// + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); + + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + + { + static const bool value = false; + }; + + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + //0 arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + #if !defined(BOOST_NO_CXX11_DECLTYPE) + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template + static decltype(boost::move_detail::declval().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + , boost_intrusive_hmfcw::yes_type()) Test(U* f); + + template + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + + #else //defined(BOOST_NO_CXX11_DECLTYPE) + + #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + + template().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)> + struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); + template static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + + #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { //Some compilers gives ICE when instantiating the 0 arg version so it is not supported. + static const bool value = true; + }; + + #endif//!defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + #endif //!defined(BOOST_NO_CXX11_DECLTYPE) + #endif //#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + //1 to N arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + //Declare some unneeded default constructor as some old compilers wrongly require it with is_convertible + #if defined(BOOST_NO_CXX11_DECLTYPE) + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + \ + template\ + struct BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + : Fun\ + {\ + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;\ + BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)();\ + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME\ + (BOOST_MOVE_REPEAT##N(boost_intrusive_hmfcw::dont_care)) const;\ + };\ + \ + template\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + {\ + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type\ + ( (::boost::move_detail::declval\ + < BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) >().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N), 0) )\ + )\ + );\ + };\ + // + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + template\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + \ + {\ + template\ + static decltype(boost::move_detail::declval().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N)\ + , boost_intrusive_hmfcw::yes_type()) Test(U* f);\ + template\ + static boost_intrusive_hmfcw::no_type Test(...);\ + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);\ + };\ + // + #endif + //////////////////////////////////// + // Build and invoke BOOST_MOVE_ITERATE_NTOM macrofunction, note that N has to be at least 1 + //////////////////////////////////// + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 1 + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #endif + BOOST_MOVE_CAT + (BOOST_MOVE_CAT(BOOST_MOVE_CAT(BOOST_MOVE_ITERATE_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN), TO) + ,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX) + (BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION) + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN + //////////////////////////////////// + // End of BOOST_MOVE_ITERATE_NTOM + //////////////////////////////////// + #endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_FUNC + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //Otherwise use the preprocessor + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + ::value + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + {}; + #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + +//Undef local macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF + +//Undef user defined macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END diff --git a/boost/intrusive/detail/iterator.hpp b/boost/intrusive/detail/iterator.hpp new file mode 100644 index 00000000..c25be430 --- /dev/null +++ b/boost/intrusive/detail/iterator.hpp @@ -0,0 +1,262 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ +namespace iterators{ + +struct incrementable_traversal_tag; +struct single_pass_traversal_tag; +struct forward_traversal_tag; +struct bidirectional_traversal_tag; +struct random_access_traversal_tag; + +namespace detail{ + +template +struct iterator_category_with_traversal; + +} //namespace boost{ +} //namespace iterators{ +} //namespace detail{ + +namespace boost { +namespace intrusive { + +using boost::movelib::iterator_traits; + +//////////////////// +// iterator +//////////////////// +template +struct iterator +{ + typedef Category iterator_category; + typedef T value_type; + typedef Difference difference_type; + typedef Pointer pointer; + typedef Reference reference; +}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_boost_iterator +//////////////////////////////////////// +template +struct is_boost_iterator +{ + static const bool value = false; +}; + +template +struct is_boost_iterator< boost::iterators::detail::iterator_category_with_traversal > +{ + static const bool value = true; +}; + +template +struct iterator_enable_if_boost_iterator + : ::boost::move_detail::enable_if_c + < is_boost_iterator::iterator_category >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template +struct iterator_enable_if_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value + , R> +{}; + +template +struct iterator_disable_if_tag + : ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template +struct iterator_enable_if_convertible_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same_or_convertible + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value && + !::boost::move_detail::is_same_or_convertible + < typename boost::intrusive::iterator_traits::iterator_category + , Tag2 + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag_difference_type +//////////////////////////////////////// +template +struct iterator_enable_if_tag_difference_type + : iterator_enable_if_tag::difference_type> +{}; + +template +struct iterator_disable_if_tag_difference_type + : iterator_disable_if_tag::difference_type> +{}; + +//////////////////// +// advance +//////////////////// + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + for (; 0 < n; --n) + ++it; + for (; n < 0; ++n) + --it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + it += n; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + for (; 0 < n; --n) + ++it; + for (; n < 0; ++n) + --it; +} + +class fake{}; + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + it += n; +} + +//////////////////// +// distance +//////////////////// +template inline +typename iterator_disable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) +{ + typename iterator_traits::difference_type off = 0; + while(first != last){ + ++off; + ++first; + } + return off; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) +{ + typename iterator_traits::difference_type off = last - first; + return off; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_traits::pointer iterator_arrow_result(const I &i) +{ return i.operator->(); } + +template +BOOST_INTRUSIVE_FORCEINLINE T * iterator_arrow_result(T *p) +{ return p; } + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP diff --git a/boost/intrusive/detail/minimal_pair_header.hpp b/boost/intrusive/detail/minimal_pair_header.hpp new file mode 100644 index 00000000..1358a085 --- /dev/null +++ b/boost/intrusive/detail/minimal_pair_header.hpp @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP +#define BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +# +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#//Try to avoid including , as it's quite big in C++11 +#if defined(BOOST_GNU_STDLIB) +# include +#else +# include //Fallback +#endif +# +#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP diff --git a/boost/intrusive/detail/mpl.hpp b/boost/intrusive/detail/mpl.hpp new file mode 100644 index 00000000..15230881 --- /dev/null +++ b/boost/intrusive/detail/mpl.hpp @@ -0,0 +1,216 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2014 +// (C) Copyright 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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP +#define BOOST_INTRUSIVE_DETAIL_MPL_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +using boost::move_detail::is_same; +using boost::move_detail::add_const; +using boost::move_detail::remove_const; +using boost::move_detail::remove_cv; +using boost::move_detail::remove_reference; +using boost::move_detail::add_reference; +using boost::move_detail::remove_pointer; +using boost::move_detail::add_pointer; +using boost::move_detail::true_type; +using boost::move_detail::false_type; +using boost::move_detail::enable_if_c; +using boost::move_detail::enable_if; +using boost::move_detail::disable_if_c; +using boost::move_detail::disable_if; +using boost::move_detail::is_convertible; +using boost::move_detail::if_c; +using boost::move_detail::if_; +using boost::move_detail::is_const; +using boost::move_detail::identity; +using boost::move_detail::alignment_of; +using boost::move_detail::is_empty; +using boost::move_detail::addressof; +using boost::move_detail::integral_constant; +using boost::move_detail::enable_if_convertible; +using boost::move_detail::disable_if_convertible; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::yes_type; +using boost::move_detail::no_type; +using boost::move_detail::apply; +using boost::move_detail::eval_if_c; +using boost::move_detail::eval_if; +using boost::move_detail::unvoid_ref; +using boost::move_detail::add_const_if_c; + +template +struct ls_zeros +{ + static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value); +}; + +template<> +struct ls_zeros<0> +{ + static const std::size_t value = 0; +}; + +template<> +struct ls_zeros<1> +{ + static const std::size_t value = 0; +}; + +// Infrastructure for providing a default type for T::TNAME if absent. +#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ + template \ + struct boost_intrusive_has_type_ ## TNAME \ + { \ + template \ + static char test(int, typename X::TNAME*); \ + \ + template \ + static int test(...); \ + \ + static const bool value = (1 == sizeof(test(0, 0))); \ + }; \ + \ + template \ + struct boost_intrusive_default_type_ ## TNAME \ + { \ + struct DefaultWrap { typedef DefaultType TNAME; }; \ + \ + typedef typename \ + ::boost::intrusive::detail::if_c \ + < boost_intrusive_has_type_ ## TNAME::value \ + , T, DefaultWrap>::type::TNAME type; \ + }; \ + // + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ +// + +#define BOOST_INTRUSIVE_HAS_TYPE(INSTANTIATION_NS_PREFIX, T, TNAME) \ + INSTANTIATION_NS_PREFIX \ + boost_intrusive_has_type_ ## TNAME< T >::value \ +// + +#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\ + template \ + struct boost_intrusive_eval_default_type_ ## TNAME \ + { \ + template \ + static char test(int, typename X::TNAME*); \ + \ + template \ + static int test(...); \ + \ + struct DefaultWrap \ + { typedef typename DefaultType::type TNAME; }; \ + \ + static const bool value = (1 == sizeof(test(0, 0))); \ + \ + typedef typename \ + ::boost::intrusive::detail::eval_if_c \ + < value \ + , ::boost::intrusive::detail::identity \ + , ::boost::intrusive::detail::identity \ + >::type::TNAME type; \ + }; \ +// + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \ +// + +#define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \ +template \ +struct TRAITS_PREFIX##_bool\ +{\ + template\ + struct two_or_three {yes_type _[2 + Add];};\ + template static yes_type test(...);\ + template static two_or_three test (int);\ + static const std::size_t value = sizeof(test(0));\ +};\ +\ +template \ +struct TRAITS_PREFIX##_bool_is_true\ +{\ + static const bool value = TRAITS_PREFIX##_bool::value > sizeof(yes_type)*2;\ +};\ +// + +#define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ + template \ + class TRAITS_NAME \ + { \ + private: \ + template struct helper;\ + template \ + static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \ + template static ::boost::intrusive::detail::no_type test(...); \ + public: \ + static const bool value = sizeof(test(0)) == sizeof(::boost::intrusive::detail::yes_type); \ + }; \ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \ +template \ +struct TRAITS_NAME \ +{ \ + struct BaseMixin \ + { \ + void FUNC_NAME(); \ + }; \ + struct Base : public Type, public BaseMixin { Base(); }; \ + template class Helper{}; \ + template \ + static ::boost::intrusive::detail::no_type test(U*, Helper* = 0); \ + static ::boost::intrusive::detail::yes_type test(...); \ + static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \ +};\ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ +BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \ +\ +template \ +struct TRAITS_NAME \ + : public TRAITS_NAME##_ignore_signature \ +{};\ +// + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP diff --git a/boost/intrusive/detail/reverse_iterator.hpp b/boost/intrusive/detail/reverse_iterator.hpp new file mode 100644 index 00000000..57631feb --- /dev/null +++ b/boost/intrusive/detail/reverse_iterator.hpp @@ -0,0 +1,165 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +class reverse_iterator +{ + public: + typedef typename boost::intrusive::iterator_traits::pointer pointer; + typedef typename boost::intrusive::iterator_traits::reference reference; + typedef typename boost::intrusive::iterator_traits::difference_type difference_type; + typedef typename boost::intrusive::iterator_traits::iterator_category iterator_category; + typedef typename boost::intrusive::iterator_traits::value_type value_type; + + + typedef It iterator_type; + + reverse_iterator() + : m_current() //Value initialization to achieve "null iterators" (N3644) + {} + + explicit reverse_iterator(It r) + : m_current(r) + {} + + reverse_iterator(const reverse_iterator& r) + : m_current(r.base()) + {} + + template + reverse_iterator( const reverse_iterator& r + , typename boost::intrusive::detail::enable_if_convertible::type* =0 + ) + : m_current(r.base()) + {} + + reverse_iterator & operator=( const reverse_iterator& r) + { m_current = r.base(); return *this; } + + template + typename boost::intrusive::detail::enable_if_convertible::type + operator=( const reverse_iterator& r) + { m_current = r.base(); return *this; } + + It base() const + { return m_current; } + + reference operator*() const + { + It temp(m_current); + --temp; + reference r = *temp; + return r; + } + + pointer operator->() const + { + It temp(m_current); + --temp; + return iterator_arrow_result(temp); + } + + reference operator[](difference_type off) const + { + return this->m_current[-off - 1]; + } + + reverse_iterator& operator++() + { + --m_current; + return *this; + } + + reverse_iterator operator++(int) + { + reverse_iterator temp((*this)); + --m_current; + return temp; + } + + reverse_iterator& operator--() + { + ++m_current; + return *this; + } + + reverse_iterator operator--(int) + { + reverse_iterator temp((*this)); + ++m_current; + return temp; + } + + friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current == r.m_current; } + + friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current != r.m_current; } + + friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current > r.m_current; } + + friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current >= r.m_current; } + + friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current < r.m_current; } + + friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current <= r.m_current; } + + reverse_iterator& operator+=(difference_type off) + { m_current -= off; return *this; } + + reverse_iterator& operator-=(difference_type off) + { m_current += off; return *this; } + + friend reverse_iterator operator+(reverse_iterator l, difference_type off) + { return (l += off); } + + friend reverse_iterator operator+(difference_type off, reverse_iterator r) + { return (r += off); } + + friend reverse_iterator operator-(reverse_iterator l, difference_type off) + { return (l-= off); } + + friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) + { return r.m_current - l.m_current; } + + private: + It m_current; // the wrapped iterator +}; + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP diff --git a/boost/intrusive/detail/std_fwd.hpp b/boost/intrusive/detail/std_fwd.hpp new file mode 100644 index 00000000..8193ea8e --- /dev/null +++ b/boost/intrusive/detail/std_fwd.hpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP +#define BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +////////////////////////////////////////////////////////////////////////////// +// Standard predeclarations +////////////////////////////////////////////////////////////////////////////// + +#include +BOOST_MOVE_STD_NS_BEG + +template +struct less; + +template +struct equal_to; + +struct input_iterator_tag; +struct forward_iterator_tag; +struct bidirectional_iterator_tag; +struct random_access_iterator_tag; + +BOOST_MOVE_STD_NS_END +#include + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP diff --git a/boost/intrusive/detail/workaround.hpp b/boost/intrusive/detail/workaround.hpp new file mode 100644 index 00000000..594ac0b2 --- /dev/null +++ b/boost/intrusive/detail/workaround.hpp @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-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) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP +#define BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + #define BOOST_INTRUSIVE_PERFECT_FORWARDING +#endif + +//Macros for documentation purposes. For code, expands to the argument +#define BOOST_INTRUSIVE_IMPDEF(TYPE) TYPE +#define BOOST_INTRUSIVE_SEEDOC(TYPE) TYPE +#define BOOST_INTRUSIVE_DOC1ST(TYPE1, TYPE2) TYPE2 +#define BOOST_INTRUSIVE_I , +#define BOOST_INTRUSIVE_DOCIGN(T1) T1 + +#define BOOST_INTRUSIVE_DISABLE_FORCEINLINE + +#if defined(BOOST_INTRUSIVE_DISABLE_FORCEINLINE) + #define BOOST_INTRUSIVE_FORCEINLINE inline +#elif defined(BOOST_INTRUSIVE_FORCEINLINE_IS_BOOST_FORCELINE) + #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE +#elif defined(BOOST_MSVC) && defined(_DEBUG) + //"__forceinline" and MSVC seems to have some bugs in debug mode + #define BOOST_INTRUSIVE_FORCEINLINE inline +#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) + //Older GCCs have problems with forceinline + #define BOOST_INTRUSIVE_FORCEINLINE inline +#else + #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE +#endif + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP diff --git a/boost/intrusive/pack_options.hpp b/boost/intrusive/pack_options.hpp new file mode 100644 index 00000000..944243f6 --- /dev/null +++ b/boost/intrusive/pack_options.hpp @@ -0,0 +1,374 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP +#define BOOST_INTRUSIVE_PACK_OPTIONS_HPP + +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + +template +struct do_pack +{ + //Use "pack" member template to pack options + typedef typename Next::template pack type; +}; + +template +struct do_pack +{ + //Avoid packing "void" to shorten template names + typedef Prev type; +}; + +template + < class DefaultOptions + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + , class O11 = void + > +struct pack_options +{ + // join options + typedef + typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < DefaultOptions + , O1 + >::type + , O2 + >::type + , O3 + >::type + , O4 + >::type + , O5 + >::type + , O6 + >::type + , O7 + >::type + , O8 + >::type + , O9 + >::type + , O10 + >::type + , O11 + >::type + type; +}; +#else + +//index_tuple +template +struct index_tuple{}; + +//build_number_seq +template > +struct build_number_seq; + +template +struct build_number_seq > + : build_number_seq > +{}; + +template +struct build_number_seq<0, index_tuple > +{ typedef index_tuple type; }; + +template +struct typelist +{}; + +//invert_typelist +template +struct invert_typelist; + +template +struct typelist_element; + +template +struct typelist_element > +{ + typedef typename typelist_element >::type type; +}; + +template +struct typelist_element<0, typelist > +{ + typedef Head type; +}; + +template +typelist >::type...> + inverted_typelist(index_tuple, typelist) +{ + return typelist >::type...>(); +} + +//sizeof_typelist +template +struct sizeof_typelist; + +template +struct sizeof_typelist< typelist > +{ + static const std::size_t value = sizeof...(Types); +}; + +//invert_typelist_impl +template +struct invert_typelist_impl; + + +template +struct invert_typelist_impl< Typelist, index_tuple > +{ + static const std::size_t last_idx = sizeof_typelist::value - 1; + typedef typelist + ::type...> type; +}; + +template +struct invert_typelist_impl< Typelist, index_tuple > +{ + typedef Typelist type; +}; + +template +struct invert_typelist_impl< Typelist, index_tuple<> > +{ + typedef Typelist type; +}; + +//invert_typelist +template +struct invert_typelist; + +template +struct invert_typelist< typelist > +{ + typedef typelist typelist_t; + typedef typename build_number_seq::type indexes_t; + typedef typename invert_typelist_impl::type type; +}; + +//Do pack +template +struct do_pack; + +template<> +struct do_pack >; + +template +struct do_pack > +{ + typedef Prev type; +}; + +template +struct do_pack > +{ + typedef typename Prev::template pack type; +}; + +template +struct do_pack > +{ + typedef typename Prev::template pack + >::type> type; +}; + + +template +struct pack_options +{ + typedef typelist typelist_t; + typedef typename invert_typelist::type inverted_typelist; + typedef typename do_pack::type type; +}; + +#endif //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + +#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \ +template< class TYPE> \ +struct OPTION_NAME \ +{ \ + template \ + struct pack : Base \ + { \ + typedef TYPEDEF_EXPR TYPEDEF_NAME; \ + }; \ +}; \ +// + +#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \ +template< TYPE VALUE> \ +struct OPTION_NAME \ +{ \ + template \ + struct pack : Base \ + { \ + static const TYPE CONSTANT_NAME = VALUE; \ + }; \ +}; \ +// + +#else //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +//! This class is a utility that takes: +//! - a default options class defining initial static constant +//! and typedefs +//! - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and +//! BOOST_INTRUSIVE_OPTION_TYPE +//! +//! and packs them together in a new type that defines all options as +//! member typedefs or static constant values. Given options of form: +//! +//! \code +//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type) +//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) +//! \endcode +//! +//! the following expression +//! +//! \code +//! +//! struct default_options +//! { +//! typedef long int_type; +//! static const int int_constant = -1; +//! }; +//! +//! pack_options< default_options, my_pointer, incremental >::type +//! \endcode +//! +//! will create a type that will contain the following typedefs/constants +//! +//! \code +//! struct unspecified_type +//! { +//! //Default options +//! typedef long int_type; +//! static const int int_constant = -1; +//! +//! //Packed options (will ovewrite any default option) +//! typedef void* my_pointer_type; +//! static const bool is_incremental = true; +//! }; +//! \endcode +//! +//! If an option is specified in the default options argument and later +//! redefined as an option, the last definition will prevail. +template +struct pack_options +{ + typedef unspecified_type type; +}; + +//! Defines an option class of name OPTION_NAME that can be used to specify a type +//! of type TYPE... +//! +//! \code +//! struct OPTION_NAME +//! { unspecified_content }; +//! \endcode +//! +//! ...that after being combined with +//! boost::intrusive::pack_options, +//! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example: +//! +//! \code +//! //[includes and namespaces omitted for brevity] +//! +//! //This macro will create the following class: +//! // template +//! // struct my_pointer +//! // { unspecified_content }; +//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer::type, my_pointer_type) +//! +//! struct empty_default{}; +//! +//! typedef pack_options< empty_default, typename my_pointer >::type::my_pointer_type type; +//! +//! BOOST_STATIC_ASSERT(( boost::is_same::value )); +//! +//! \endcode +#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) + +//! Defines an option class of name OPTION_NAME that can be used to specify a constant +//! of type TYPE with value VALUE... +//! +//! \code +//! struct OPTION_NAME +//! { unspecified_content }; +//! \endcode +//! +//! ...that after being combined with +//! boost::intrusive::pack_options, +//! will contain a CONSTANT_NAME static constant of value VALUE. Example: +//! +//! \code +//! //[includes and namespaces omitted for brevity] +//! +//! //This macro will create the following class: +//! // template +//! // struct incremental +//! // { unspecified_content }; +//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) +//! +//! struct empty_default{}; +//! +//! const bool is_incremental = pack_options< empty_default, incremental >::type::is_incremental; +//! +//! BOOST_STATIC_ASSERT(( is_incremental == true )); +//! +//! \endcode +#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) + +#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP diff --git a/boost/intrusive/pointer_rebind.hpp b/boost/intrusive/pointer_rebind.hpp new file mode 100644 index 00000000..9592e06e --- /dev/null +++ b/boost/intrusive/pointer_rebind.hpp @@ -0,0 +1,188 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-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) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_POINTER_REBIND_HPP +#define BOOST_INTRUSIVE_POINTER_REBIND_HPP + +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP +#include +#endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +/////////////////////////// +//struct pointer_rebind_mode +/////////////////////////// +template +struct pointer_has_rebind +{ + template struct any + { any(const V&) { } }; + + template + static char test(int, typename X::template rebind*); + + template + static int test(any, void*); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + +template +struct pointer_has_rebind_other +{ + template struct any + { any(const V&) { } }; + + template + static char test(int, typename X::template rebind::other*); + + template + static int test(any, void*); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + +template +struct pointer_rebind_mode +{ + static const unsigned int rebind = (unsigned int)pointer_has_rebind::value; + static const unsigned int rebind_other = (unsigned int)pointer_has_rebind_other::value; + static const unsigned int mode = rebind + rebind*rebind_other; +}; + +//////////////////////// +//struct pointer_rebinder +//////////////////////// +template +struct pointer_rebinder; + +// Implementation of pointer_rebinder::type if Ptr has +// its own rebind::other type (C++03) +template +struct pointer_rebinder< Ptr, U, 2u > +{ + typedef typename Ptr::template rebind::other type; +}; + +// Implementation of pointer_rebinder::type if Ptr has +// its own rebind template. +template +struct pointer_rebinder< Ptr, U, 1u > +{ + typedef typename Ptr::template rebind type; +}; + +// Specialization of pointer_rebinder if Ptr does not +// have its own rebind template but has a the form Ptr, +// where An... comprises zero or more type parameters. +// Many types fit this form, hence many pointers will get a +// reasonable default for rebind. +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template

SqwV}$F3U1n`2!5 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%0Df8Lf??*y=Q$pCz8QXsAEWDhqvag4 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 UO8r0hKk$9yUX*0MKZLnG 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 >!JhEI_ScdJ`)>R<0n+v`FLH8l=Hg9> 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